kakakakakku blog

Weekly Tech Blog: Keep on Learning!

GitHub Actions の「ワークフローの再利用」をプライベートリポジトリで使う

2022年12月のリリースで GitHub Actions「reusable workflow(ワークフローの再利用)」をプライベートリポジトリでも使えるようになった❗️特に会社でプライベートリポジトリを使っている場合に便利で待望のアップデートだと思う.今まではプライベートリポジトリの場合は "同一リポジトリ内" での再利用しかできず,ワークフローを共通化するというユースケースでは使いにくかった.GitHub Actions のワークフローをコピーして増やす作業からおさらばできる...❓

github.blog

構成

今回はブログ用に以下のようなリポジトリ構成を作って試してみた.ワークフローとしては,Python プロジェクトで使える Flake8 / pytest の実行を再利用できるように reusable workflow にまとめる.

ついでに GitHub Actions の関連ドキュメントも以下にまとめておく.現時点だと日本語化されていないところもある.

再利用するワークフローを定義する(呼び出し先)

まず,再利用するワークフローを定義するプライベートリポジトリで「アクセス権限」を付与しておく.以下のように Actions > General メニューの AccessAccessible from repositories owned by the user 'USER NAME' を設定しておく.今回は kakakakakku/github-actions-reusable-workflows リポジトリを使う.

次に GitHub Actions の YAML ファイルを .github/workflows/python.yml として書く.普段と違うところは onworkflow_call と書くところ.あとは普段のワークフローと同じで Flake8 / pytest を実行している.

on:
  workflow_call:

jobs:
  python:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ['3.8', '3.9']
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install dependencies
        run: |
          pip install flake8 pytest
      - name: Lint with flake8
        run: |
          flake8 . --count --show-source --statistics
      - name: Test with pytest
        run: |
          pytest

ワークフローを再利用する(呼び出し元)

今度は再利用する側の YAML ファイルを .github/workflows/main.yml として書く.ポイントは uses で再利用するワークフローを指定するところ.あとは普段のワークフローと同じ.

name: Test

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master

jobs:
  reusable-python:
    uses: kakakakakku/github-actions-reusable-workflows/.github/workflows/python.yml@master

実行すると期待通りにワークフローを再利用できている❗️

機能 1. 再利用するワークフローのブランチを指定できる

ワークフローを更新するときに mainmaster などを直接更新してしまうと,再利用しているリポジトリが多いほど影響も気になると思う.reusable workflow ではワークフローを呼び出すときに @ でブランチ名やリリースタグを指定できるので,動作確認をしながら開発を進められる.

jobs:
  reusable-python:
    uses: kakakakakku/github-actions-reusable-workflows/.github/workflows/python.yml@develop

機能 2. パラメータやシークレットを指定できる

ワークフローを再利用しようとすると,どうしても柔軟性が失われてしまう.reusable workflow では "パラメータ" や "シークレット" を呼び出し元のワークフローで指定できるため,ワークフローごとに異なる値を注入することもできる.以下の YAML はドキュメントから引用した.また GitHub Actions の if と組み合わせれば,一部のステップをスキップするように使うこともできる.

name: Reusable workflow example

on:
  workflow_call:
    inputs:
      config-path:
        required: true
        type: string
    secrets:
      token:
        required: true

jobs:
  triage:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/labeler@v4
      with:
        repo-token: ${{ secrets.token }}
        configuration-path: ${{ inputs.config-path }}

注意点 1. 階層

reusable workflow の usesjobs.<job_id>.uses の階層のみで使える.jobs.<job_id>.steps[*].uses の階層では使えないため,もし複数のワークフローを再利用し,順番に実行する場合は needs を指定して以下のように書く.

name: Test

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master

jobs:
  reusable-python:
    uses: kakakakakku/github-actions-reusable-workflows/.github/workflows/python.yml@master
  reusable-deploy:
    needs: reusable-python
    uses: kakakakakku/github-actions-reusable-workflows/.github/workflows/deploy.yml@master