この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、CX事業本部 IoT事業部の若槻です。
GitHubのPull Requestを使用した開発で、次のトリガーでCI/CDを実行するWorkflowをよく組みます。
- BranchのPush時:CI(ビルドおよびテスト)のみ実行
- Pull RequestのMerge時:CIおよびCD(デプロイ)を実行
今回は、Push時はCIのみ、Merge時はCIおよびCDを実行するWorkflowを、GitHub ActionsのWorkflowの再使用で作ってみました。
Workflowの再使用
Push時とMerge時に実行されるWorkflow fileをそれぞれ作ることになるのですが、同じCI処理をそれぞれで実行したい場合は、記述を分けると2重管理となってしまいます。処理の修正時に抜け漏れも発生しかねません。
このような場合にWorkflowの記述の2重管理を避ける方法として、Workflowの再使用という機能があります。
この機能は2021年11月にGAとなった機能です。
使い方としては、Workflowを再使用される側では、トリガーにworkflow_call
を指定します。
on:
workflow_call:
inputs:
username:
required: true
type: string
secrets:
envPAT:
required: true
Workflowを再使用する側では、使用したいWorkflowファイルをパスで指定します。
jobs:
reusable_workflow_job:
runs-on: ubuntu-latest
environment: production
steps:
- uses: ./.github/workflows/my-action
with:
username: ${{ inputs.username }}
token: ${{ secrets.envPAT }}
これにより、「再使用する側」のWorkflowから「再使用される側」のWorkflowを呼び出して使用することができます。よって「再使用する側」をMerge時のみ、「再使用される側」をMerge時とPush時にトリガーされるようにすれば、記述の2重管理を回避できます。
やってみた
Workflow fileの作成
下記のような2つのWorkflow fileを作成します。ここではAWS CDkプロジェクトを管理するRepositoryを対象としたWorkflowです。
ci.yaml
では、Dependencyのキャッシュのリストア、Dependencyのインスール、テストを行います。トリガーは再使用時(on:workflow_call
)またはmain
ブランチへのPush時(on:push branches-ignore:main
)としています。
.github/workflows/ci.yaml
on:
workflow_call:
push:
paths-ignore:
- '**/*.md'
branches-ignore:
- main
jobs:
ci:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cache CDK Dependency
uses: actions/cache@v3
id: cache_cdk_dependency_id
env:
cache-name: cache-cdk-dependency
with:
path: node_modules
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('package-lock.json') }}
restore-keys: ${{ runner.os }}-build-${{ env.cache-name }}-
- name: Install CDK Dependency
if: steps.cache_cdk_dependency_id.outputs.cache-hit != 'true'
run: npm install
- name: CDK Test
run: npm run test
cd.yaml
では、AWSの認証、Dependencyのキャッシュのリストア、およびデプロイを行います。トリガーはmain
ブランチへのMerge時としています。
.github/workflows/cd.yaml
on:
push:
branches:
- main
permissions:
id-token: write
contents: read
env:
AWS_OIDC_ROLE_ARN: ${{ secrets.AWS_OIDC_ROLE_ARN }}
AWS_REGION: us-east-1
jobs:
ci-reuse:
uses: ./.github/workflows/ci.yaml
cd:
runs-on: ubuntu-latest
needs: ci-reuse
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Assume Role
uses: aws-actions/configure-aws-credentials@v1
with:
role-to-assume: ${{ env.AWS_OIDC_ROLE_ARN }}
aws-region: ${{env.AWS_REGION}}
- name: Cache CDK Dependency
uses: actions/cache@v3
id: cache_cdk_dependency_id
env:
cache-name: cache-cdk-dependency
with:
path: node_modules
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('package-lock.json') }}
- name: Deploy
run: npm run deploy
動作確認
Pushをすると、CIのみが実行されました!
Mergeをすると、CIおよびCDが実行されました!ci-reuse
で
ハマった箇所
Workflow fileのパス指定の記述
再使用する側のWorkflowを実行すると、次のようなエラーが発生しました。
invalid value workflow reference: no version specified
再使用したいWorkflow fileのパスの指定の記述が誤っていました。
誤ったパス指定
jobs:
ci-reuse:
uses: .github/workflows/ci.yaml
正しいパス指定
jobs:
ci-reuse:
uses: ./.github/workflows/ci.yaml
おわりに
Push時はCIのみ、Merge時はCIおよびCDを実行するWorkflowをGitHub Actionsで作ってみました。
今まで「Push時はCIのみ、Merge時はCIおよびCDを実行する」という処理を重複なく記述することは出来そうで出来なかった(頑張ればできた?)ため、仕方なく記述の2重管理をしていましたが、これからはWorkflowの再使用を活用してそれともおさらば出来ますね。
参考
以上