GitHub Actions

GitHubのリポジトリに対してCI/CD等のワークフローを自動実行できるサービス。
2019年11月に正式リリースされた

※2020-05-03 このページの内容を元に、Qiitaに投稿した

Documentation

https://help.github.com/en/actions

参考:

既知の制限事項

2020-05-03更新

Getting Started

https://github.com/actions/starter-workflows … 初心者向けワークフローサンプル集

Workflowの作成

https://help.github.com/en/actions/configuring-and-managing-workflows/configuring-a-workflow

NOTE:

プルリクエストで実行する

任意のプルリクエストでtestを実行し、masterブランチへのマージでのみdeployを実行する設定例(2ファイル):

# test.yml
name: test
on: pull_request
jobs:
  test:
    runs-on: ubuntu-latest
      steps:
        # tasks for testing
---
# deploy.yml
name: deploy
on:
  pull_request:
    branches:
      - master
    types: [closed]
jobs:
  deploy:
    runs-on: ubuntu-latest
    if: ${{ github.event.pull_request.merged == true }}
      steps:
        # tasks for deployment

NOTE:

参考:

定期的に実行する

crontabと同じ書式でワークフローを定期実行するタイミングを指定することができる。

Example:

on:
  schedule:
    # JSTで月曜から金曜の9:05 - 17:05の間、2時間毎に実行
    - cron: '5 0-8/2 * * MON-FRI'

NOTE:

  • cronのタイムゾーンはUTCなので注意

リファレンス:

対象branchやpathをフィルタする

Example:

on:
  push:
    branches:
      - master
      - 'releases/**'
      - '!releases/**-alpha' # alpha版は含めない
    tags:
      - v1
    # file paths to consider in the event. Optional; defaults to all.
    paths:
      - 'test/*'
    paths-ignore:
      - 'docs/**'

NOTE:

  • branchesbranches-ignore併用不可
  • tagstags-ignore併用不可
  • pathspaths-ignore は(たぶん)併用可

リファレンス:

複数の実行環境に対応する

複数のOSプラットフォームや、ランタイムのバージョンに対応する方法。
下のようなbuild matrixを設定すると良い。

Example:

jobs:
  node-test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-16.04, ubuntu-18.04]
        node: [6, 8, 10]
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node }}

NG例:

  • runs-on: [ubuntu-16.04, ubuntu-18.04]

リファレンス:

参考:

Dockerコンテナ上でビルド実行

jobs.<job_id>.container で指定する。

https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idcontainer

Examples:

jobs:
  my_job:
    container: node:10.16-jessie

---
jobs:
  my_job:
    container:
      image: node:10.16-jessie
      env:
        NODE_ENV: development
      ports:
        - 80
      volumes:
        - my_docker_volume:/volume_mount
      options: --cpus 1

starter-workflowsにも参考になるサンプルがある。以下は例:

環境変数を設定する

https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#env

いくつかの箇所で設定できる。それぞれ適用範囲が異なる。

設定位置適用範囲
envfor all jobs and steps
jobs.<job_id>.envfor all steps in the job
jobs.<job_id>.steps.envfor the step
jobs.<job_id>.container.envfor the container to run steps in the job

Examples:

env:
  SERVER: production

---
jobs:
  my-job:
    name: My Job
    runs-on: ubuntu-latest
    env:
      MY_VAR: Hi there! My name is
    steps:
    - name: Print a greeting
      env:
        FIRST_NAME: Mona
        MIDDLE_NAME: The
        LAST_NAME: Octocat
      run: |
                echo $MY_VAR $FIRST_NAME $MIDDLE_NAME $LAST_NAME.

See also #変数やシークレットの利用

jobやstepを特定の条件で実行する

jobs.<job_id>.ifjobs.<job_id>.steps.if の値に条件式を記述することで、該当のjobやstepを条件が真のときのみ実行することができる。

Examples:

jobs:
  deploy:
    # プルリクエストがマージされた時のみ実行
    if: ${{ github.event.pull_request.merged == true }}

    steps:
      - name: Deploy
        # some deploy action

      # このstepは常に実行する
      - name: Notify
        if: ${{ always() }}
        # some notify action

      # ジョブ失敗時に実行するstep
      - name: Clean up on Failure
        if: ${{ failure() }}
        # some clean up action

NOTE:

  • if: に渡す条件式では ${{ }} は省略可能
  • ワークフロー内でタスクが失敗すると、デフォルトでは後続のタスクはスキップされる
    • 後述のリファレンスに下の記述がある:

A job or step will not run when a critical failure prevents the task from running. For example, if getting sources failed.

リファレンス:

変数やシークレットの利用

Documents:

GITHUB_TOKENによる認証

Authenticating with the GITHUB_TOKEN - GitHub Help

GitHubは、ワークフローで利用する GITHUB_TOKEN シークレットを自動的に生成します。 この GITHUB_TOKEN は、ワークフローの実行内での認証に利用できます。

How-to

Workflow内でgit commit & push

ユースケースの例:

  • コードフォーマッタや、静的解析による修正を自動実行する
  • ビルドしたアーティファクトを追加する

checkoutアクションでチェックアウトしたものと同じリポジトリであれば、そのままpushできるようだ。

Example:

jobs:
  update:
    steps:
      - uses: actions/checkout@v2
      - run: |
        git config --global user.name "Your Name"
        git config --global user.email "[email protected]"
        ./do-something.sh
        git add .
        git commit -m "Update by GitHub Action"
        git push        

checkoutアクションではデフォルトで ${{ github.token }} が使われており、これにリポジトリへの書込み権限もついているからだろう。

git commit & pushを行うActionもある:

参考:

別ブランチを更新するには

権限は ${{ github.token }} で十分なので、上と同様にcheckoutアクションを使って、オプションで別ブランチをチェックアウトして更新を行えばよい。

Example:

jobs:
  publish:
    steps:
      - uses: actions/checkout@v2
      - uses: actions/checkout@v2
        with:
          ref: gh-pages
          path: public
      - run: |
        git config --global user.name "Your Name"
        git config --global user.email "[email protected]"
        make build
        cd public
        git add .
        git commit -m "Update by GitHub Action"
        git push        

上の設定自体は試してないが、やり方的には合っているはず。
progrhyme/binq-indexではこのやり方を取っている。

Workflow内でパッケージインストール

Ubuntuだったら単純に sudo apt install <package>run すればいい。

jobs:
  install-zsh:
    runs-on: ubuntu-latest
    steps:
      - run: sudo apt install zsh
      - run: zsh --version

参考: