⚙️

Github ActionsのTips

2023/12/12に公開

はじめに

Github Actionsに関するTipsを書かせていただきました。
まだ使い始めて数ヶ月ではありますが、よく使う・見返すものをまとめてみます。

GITHUB_OUTPUT

needsを使うと、jobを超えてoutputを渡せます。

jobs:
  job1:
    runs-on: ubuntu-latest
    # Map a step output to a job output
    outputs:
      output1: ${{ steps.step1.outputs.test }}
      output2: ${{ steps.step2.outputs.test }}
    steps:
      - id: step1
        run: echo "test=hello" >> "$GITHUB_OUTPUT"
      - id: step2
        run: echo "test=world" >> "$GITHUB_OUTPUT"
  job2:
    runs-on: ubuntu-latest
    needs: job1
    steps:
      - env:
          OUTPUT1: ${{needs.job1.outputs.output1}}
          OUTPUT2: ${{needs.job1.outputs.output2}}
        run: echo "$OUTPUT1 $OUTPUT2"

https://docs.github.com/ja/actions/using-jobs/defining-outputs-for-jobs
GITHUB_OUTPUTなどでは、現在以下の使い方は非推奨です。

- name: Save state
run: echo "::save-state name={name}::{value}"

- name: Set output
run: echo "::set-output name={name}::{value}"

Workflows using save-state or set-output in their workflows will continue to work as expected, however, a warning will appear under annotations indicating the planned deprecation. We recommend customers using these commands to upgrade their workflows to use environment files.

https://github.blog/changelog/2023-07-24-github-actions-update-on-save-state-and-set-output-commands/
今は以下のような使い方をします。

- name: Save state
run: echo "{name}={value}" >> $GITHUB_STATE

- name: Set output
run: echo "{name}={value}" >> $GITHUB_OUTPUT

https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter

workflow_dispatch

※一部公開当初より、内容を変更しています。

inputs.tags

のように、workflow_dispatchで入力したものを値として取り出せます。

on:
  workflow_dispatch:
    inputs:
      logLevel:
        description: 'Log level'
        required: true
        default: 'warning'
        type: choice
        options:
          - info
          - warning
          - debug
      print_tags:
        description: 'True to print to STDOUT'
        required: true
        type: boolean
      tags:
        description: 'Test scenario tags'
        required: true
        type: string
      environment:
        description: 'Environment to run tests against'
        type: environment
        required: true

jobs:
  print-tag:
    runs-on: ubuntu-latest
    if:  ${{ inputs.print_tags }} 
    steps:
      - name: Print the input tag to STDOUT
        run: echo  The tags are ${{ inputs.tags }} 

上の例では、workflow_dispatchのtagsの項目で入力したものを

run: echo  The tags are ${{ inputs.tags }} 

として利用しています。
https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onworkflow_dispatchinputs

if

  • 基本的な使い方
name: example-workflow
on: [push]
jobs:
  production-deploy:
    if: github.repository == 'octo-org/octo-repo-prod'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v3
        with:
          node-version: '14'
      - run: npm install -g bats

https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idif

  • run時に使う時
    先程のworkflow_dispatchの例を元に、一部変更した上で実装しています。
    if文の例でもありますが、GITHUB_OUTPUTでも触れたこと(前のjobで定義したoutputsをまとめて、needsを使って次のjob以降に渡せる)の実装例にもなっています。
on:
  workflow_dispatch:
    inputs:
      logLevel:
        description: "Log level"
        required: true
        default: "warning"
        type: choice
        options:
          - info
          - warning
          - debug
      print_tags:
        description: "True to print to STDOUT"
        required: true
        type: boolean
      tags:
        description: "Test scenario tags"
        required: true
        type: string

jobs:
  prepare-loglevel:
    runs-on: ubuntu-latest
    steps:
      - name: Set loglevel
        id: set-loglevel
        run: |
          if [ "${{ inputs.loglevel }}" == "info" ]; then
            echo "Info log is sending"
            echo "SELECTED-LOGLEVEL=info" >> "$GITHUB_OUTPUT"
          elif [ "${{ inputs.loglevel }}" == "warning" ]; then
            echo "Warning log is sending!!"
            echo "SELECTED-LOGLEVEL=warning" >> "$GITHUB_OUTPUT"
          elif [ "${{ inputs.loglevel }}" == "debug" ]; then
            echo "Debug log is sending"
            echo "SELECTED-LOGLEVEL=debug" >> "$GITHUB_OUTPUT"
          else 
            echo "Unknown log is sending"
          fi

    outputs:
      selected-loglevel: ${{ steps.set-loglevel.outputs.SELECTED-LOGLEVEL }}

  print-loglevel:
    needs: prepare-loglevel
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Print loglevel
        id: print-loglevel
        run: echo "This loglevel is ${{ needs.prepare-loglevel.outputs.selected-loglevel }}"

https://thomasthornton.cloud/2023/08/11/if-elseif-or-else-in-github-actions/

コンテキスト

コンテキストの使い方でわからなくなったら、ここを見ます。
https://docs.github.com/ja/actions/learn-github-actions/contexts#about-contexts

Github Secret

大事なもの(IDとかPassとか)は、ymlに直接書かないようにします。
https://docs.github.com/ja/actions/security-guides/using-secrets-in-github-actions

Github Actionsで使われているリソース

Linux(例:ubuntu-latest)、Window(例:windows-latest)、macOS(例:macos-latest)が使えます。
https://docs.github.com/ja/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources

Github Actionsのコスト

Github Actionsでは、OSごとにコストが違います。
https://docs.github.com/ja/billing/managing-billing-for-github-actions/about-billing-for-github-actions
Linuxが一番コストが低いです。

Githubで出力できるものをSlackに通知する(slack-github-action)

Slack Incoming Webhookなどを使う時、基本Usage通りに作ります。
https://github.com/slackapi/slack-github-action

Slack Incoming Webhook

- name: Send custom JSON data to Slack workflow
  id: slack
  uses: slackapi/slack-github-action@v1.24.0
  with:
    # For posting a rich message using Block Kit
    payload: |
      {
        "text": "GitHub Action build result: ${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}",
        "blocks": [
          {
            "type": "section",
            "text": {
              "type": "mrkdwn",
              "text": "GitHub Action build result: ${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}"
            }
          }
        ]
      }
  env:
    SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
    SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK

公開されているActionsもありますが、自分で作りたい場合はこれに従うと楽です。

Scheduleの時間

日本時間(JST)とUTCは、9時間ずれています。
計算するときはUTC-9して、JSTを出します。
https://www.jisakeisan.com/
例)
UTC=23
JST=8

on:
  schedule:
  #JST=AM8:00
    - cron: '0 23 * * *'

また、scheduleでセットしても何分かは遅れるので、少し注意する必要があります。
https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule

Windowsのときでもbashが使える

steps:
  - name: Display the path
    shell: bash
    run: echo $PATH

Windowsでも、シェルスクリプトが使えます。
https://docs.github.com/ja/actions/using-workflows/workflow-syntax-for-github-actions#example-running-a-command-using-bash

さいごに

Github ActionsはCI/CDツールとして便利なので、少しずつものにしたいです。

Discussion