この記事はトラストバンクAdventCalendar 21日目になります
トラストバンク SREグループの @kgkukoaoisi です
はじめに
同じようなデプロイフローが増えてきたのでジョブやステップを共通化してみました。
具体的には以下のような課題がありました:
- 新規構築のサービスで同じようなECSへのCI/CDがコピペされている
- 1箇所修正するたびに全リポジトリへ同じ変更を入れる必要がある
- ワークフローの品質にばらつきが出てきた
手法としては Reusable Workflow と Composite Action を使ったんですが、それぞれメリットデメリットあるので実例とともに使い分けをご紹介します。
共通の特徴
どちらの手法も以下の特徴があります:
- 重複する処理を共通化できる
- 同じリポジトリはもちろん、他のリポジトリに定義したワークフロー/アクションを呼び出せる
- タグやブランチを指定して呼び出し可能
他リポジトリからの呼び出し設定
他のリポジトリから呼び出す場合は、共通ワークフローを置いたリポジトリで設定が必要です:
Settings > Actions > General > Access で以下のいずれかを選択:
-
Accessible from repositories in the '<organization>' organization(同一Organization内で共有) -
Accessible from repositories owned by the user '<username>'(個人アカウントの場合)
Reusable Workflow
概要
ジョブ全体を再利用可能な形で定義します。workflow_callトリガーを使って定義し、usesで呼び出します。
定義例
# .github/workflows/deploy-to-ecs.yml(共通リポジトリ側)
name: Deploy to ECS
on:
workflow_call:
inputs:
environment:
description: 'デプロイ環境'
required: true
type: string
service-name:
description: 'ECSサービス名'
required: true
type: string
secrets:
AWS_ROLE_ARN:
required: true
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ap-northeast-1
- name: Deploy to ECS
run: |
aws ecs update-service \
--cluster ${{ inputs.environment }}-cluster \
--service ${{ inputs.service-name }} \
--force-new-deployment
呼び出し例
# .github/workflows/deploy.yml(呼び出し元リポジトリ)
name: Deploy
on:
push:
branches: [main]
jobs:
deploy-production:
uses: my-org/shared-workflows/.github/workflows/deploy-to-ecs.yml@v1
with:
environment: production
service-name: my-service
secrets:
AWS_ROLE_ARN: ${{ secrets.AWS_ROLE_ARN }}
メリット
- ジョブ単位で再利用できるので、CI/CDパイプライン全体を標準化しやすい
-
runs-onやpermissionsも含めて定義できる -
secrets: inheritで GitHub Secrets を一括継承できる(Variablesは継承不要で参照可能) - matrixと組み合わせてジョブの並列実行が簡単
デメリット
- 呼び出し元で
envを設定できない(値はinputsやsecretsで明示的に渡す必要あり) - ジョブ内の一部のステップだけ共通化したい場合には向かない
- ネストした呼び出し(Reusableから別のReusableを呼ぶ)は最大4階層まで
Composite Action
概要
特定のステップ群を再利用可能な形で定義します。action.ymlで定義し、通常のアクションと同じようにusesで呼び出します。
定義例
# .github/actions/setup-node-and-cache/action.yml
name: 'Setup Node.js with cache'
description: 'Node.jsのセットアップとnpm cacheの設定を行う'
inputs:
node-version:
description: 'Node.jsのバージョン'
required: false
default: '20'
runs:
using: 'composite'
steps:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
- name: Install dependencies
shell: bash
run: npm ci
- name: Run lint
shell: bash
run: npm run lint
呼び出し例
# .github/workflows/ci.yml
name: CI
on:
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup and lint
uses: my-org/shared-actions/.github/actions/setup-node-and-cache@v1
with:
node-version: '20'
- name: Run tests
run: npm test
メリット
- ステップ単位で柔軟に組み合わせられる
- 1つのジョブ内で複数のComposite Actionを呼び出せる
- 既存のワークフローに部分的に導入しやすい
- 呼び出し元の
envを参照できる(Reusable Workflowではできない)
デメリット
- Actionsのログ上で各ステップが折りたたまれて表示され、デバッグ時に見づらい
-
runs-onやpermissionsは呼び出し元で設定する必要がある
使い分けの指針
| 観点 | Reusable Workflow | Composite Action |
|---|---|---|
| 再利用の単位 | ジョブ全体 | ステップ群 |
| ユースケース | CI/CDパイプラインの標準化 | 共通処理の部品化 |
| runs-on指定 | 定義側で可能 | 呼び出し側で必要 |
| 呼び出し元のenv参照 | 不可 | 可能 |
| 柔軟性 | 低(ジョブ単位) | 高(組み合わせ自由) |
| ログの見やすさ | 見やすい | やや見づらい |
余談
YAMLアンカー
途中でYAMLアンカーが使えることを知り、permissionsとかwithとか共通化できるかもと思いましたが、GitHub Actionsでは制限があります。
# これはできない
x-common: &common
runs-on: ubuntu-latest
jobs:
build:
<<: *common # GitHub Actionsでは動かない
YAMLアンカーは同一ファイル内でのみ有効で、かつGitHub Actionsのパーサーがすべての構文をサポートしているわけではありません。
runnerにubuntu-slimを使ってみた
ubuntu-latestの代わりにubuntu-slimを使ってみました。
メリット:
- 起動が速い
- 最小限のツールのみプリインストール
制限事項:
- ジョブの実行時間が15分まで
- Dockerコマンドが使えない
- 一部のツールがプリインストールされていない
2025/11時点で ubuntu-slim はパブリックプレビューになります
release-pleaseでタグ管理
共通ワークフローやアクションを@v1のようなタグで呼び出す場合、リリースタグの管理が必要になります。
release-pleaseを使うと、
Conventional Commitsに基づいて自動でバージョンを上げてタグを作成してくれるので楽です。
PRをマージするだけでリリースPRが自動生成され、それをマージすればタグが切られます。
手動でタグを打つ運用から解放されました。
まとめ
ワークフローの共通化によって、メンテナンスが楽になりました。
- Reusable Workflow: デプロイなどジョブ全体を標準化したいときに
- Composite Action: セットアップなど部品として使い回したいときに
最初は「どっちを使えばいいの?」と迷いましたが、ジョブ単位かステップ単位かで考えると選びやすいです。
まずは小さく始めて、徐々に共通化の範囲を広げていくのがおすすめです。
トラストバンクでは、一緒に働く仲間を絶賛募集しています。
AdventCalendar を見て、少しでも気になった方は、是非ご連絡ください。