この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、CX事業本部 IoT事業部の若槻です。
前回の下記エントリでは、Push時はCIのみ、Merge時はCIおよびCDを実行するGitHub Actionsの作成において、「Workflowの再使用」を活用し、Workflowを分けた場合でもCI処理の記述の重複が無いようにしてみました。
今回は、同じくPush時はCIのみ、Merge時はCIおよびCDを実行するGitHub Actionsの作成を、単一のWorkflowでやってみました。
やってみた
前提
feature/****
というブランチでPull Requestを作成して開発を行い、レビューがOKならmain
ブランチにマージするというフローで考えてみます。- Pull Requestでの開発中にPushをするとCIが実行され、
main
ブランチにマージをするとCIおよびCIが行われるようにしたいです。 - AWS CDkプロジェクトのCI/CDを行うWorkflowで考えてみます。
- 認証に必要なAssumeRoleは、
AWS_OIDC_ROLE_ARN
から取得したロールを使用してOIDCにより行っています。
- 認証に必要なAssumeRoleは、
Workflow fileの作成
下記のような1つのWorkflow fileを作成します。
.github/workflows/cicd.yaml
on:
push:
paths-ignore:
- '**/*.md'
jobs:
integration:
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 ci --cache .npm --no-audit --progress=false --silent
- name: CDK Test
run: npm run test
deploy:
runs-on: ubuntu-latest
if: ${{ github.ref_name == 'main' }}
needs: integration
env:
AWS_OIDC_ROLE_ARN: ${{ secrets.AWS_OIDC_ROLE_ARN }}
AWS_REGION: us-east-1
permissions:
id-token: write
contents: read
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
ポイントとしては、まずトリガーはすべてのブランチでのアクション時に動作するようにしています。
.github/workflows/cicd.yaml
on:
push:
paths-ignore:
- '**/*.md'
そしてCDを行うジョブのif条件を${{ github.ref_name == 'main' }}
とし、main
ブランチへのマージ時のみCDが行われるようにしています。
.github/workflows/cicd.yaml
deploy:
runs-on: ubuntu-latest
if: ${{ github.ref_name == 'main' }}
needs: integration
動作確認
PushをするとCIだけ実行されました!
MergeをするとCIおよびCDが実行されました!
ハマった箇所
Workflowのトリガーですが、本来ならこのようにpush
とpull_request
を組み合わせて使用したかったです。これによりmain
ブランチではPushによるトリガーされなくなり、マージ時のみトリガーされるようになります。main
ブランチへのPushを想定していないならこれでも良いはずです。
on:
push:
paths-ignore:
- '**/*.md'
branches-ignore:
- main
pull_request:
types:
- closed
branches:
- main
ではトリガーをこのようになぜしなかったかと言うと、pull_request
使用時にaws-actions/configure-aws-credentials
による認証がなぜか失敗してしまうためです。
例えば次のWorkflowで試してみます。
.github/workflows/cicd.yaml(Assume Roleが落ちる)
on:
pull_request:
types:
- closed
branches:
- main
jobs:
integration:
runs-on: ubuntu-latest
steps:
- run: echo "中略"
deploy:
runs-on: ubuntu-latest
if: ${{ github.ref_name == 'main' }}
needs: integration
env:
AWS_OIDC_ROLE_ARN: ${{ secrets.AWS_OIDC_ROLE_ARN }}
AWS_REGION: us-east-1
permissions:
id-token: write
contents: read
steps:
- name: Assume Role
uses: aws-actions/configure-aws-credentials@v1
with:
role-to-assume: ${{ env.AWS_OIDC_ROLE_ARN }}
aws-region: ${{env.AWS_REGION}}
マージをするとAssumeRoleがエラーとなりました。上手くトークンを渡せていないような動作です。
Not authorized to perform sts:AssumeRoleWithWebIdentity
ここら辺の設定がいるのかなあと試しに有効にしてみましたが変化はありませんでした。
解決策が分かったらまた共有をしたいと思います。
ただ、直接pushする運用をしないmain
ブランチはブランチ保護ルールでpush制限をするかと思うので、push
トリガーだけの使用でもさほど不便は無いかと思います。
参考
以上