![](https://cdn-ak.f.st-hatena.com/images/fotolife/e/excite-kazuki/20231221/20231221141236.png)
はじめに
エキサイト株式会社 バックエンドエンジニアの山縣(@zsp2088dev)です。
エキサイトホールディングス Advent Calendar 2023の6日目を担当します。
私の担当するエキサイトブログでは、アプリケーションのテスト、ビルド、デプロイにGitHub Actionsを使用しています。
GitHub Actionsを使用するにあたり、ワークフローファイルを.github/workflows
に定義していますが、
初回に定義したワークフローファイルのメンテナスが中々できていませんでした。
このような中で、GitHub Actionsでワークフローを再利用できることを知り、これを適用できそうだと判断し、実際にワークフローファイルを分割することにしました。
本記事では、workflow_call
イベントを使用したワークフローの分割とその際にハマった箇所、今後取り組みたいことについて紹介します。
概要
ワークフローファイルを分割する前のファイル一覧です。
❯ tree .github/workflows
.github/workflows
├── deploy_production.yml
├── deploy_staging.yml
└── deploy_test.yml
それぞれのワークフローファイルで、以下の処理を定義しています。
このように、共通の処理が多く存在し、コピペでワークフローファイルを作成することが常態化していました。
テスト環境
- コンテナをビルド
- Amazon ECRにビルドしたイメージをプッシュ
- Amazon ECSにデプロイ
ステージング環境/本番環境
- 静的ファイル(CSS/JavaScript)をAmazon S3にアップロード
- コンテナをビルド
- Amazon ECRにビルドしたイメージをプッシュ
- Amazon ECSにデプロイ
ワークフローファイルの分割
GitHub Actionsでワークフローを再利用できることを知り、早速ワークフローファイルを分割することにしました。
ワークフローを再利用するには、workflow_call
イベントを使用します。
これにより、別のワークフローからワークフローを呼び出すことができるようになります。
docs.github.com
以下に分割後のワークフローファイルの一例を示します。
今回のケースでは、workflow_dispatch
イベントからworkflow_call
イベントを呼び出しており、静的ファイルのアップロードとコンテナデプロイの処理を、それぞれworkflow_call
イベントに切り出しました。
これにより、それぞれの処理が一箇所にまとまり、タスクの追加や修正の手間を低減することができるようになります。
静的ファイルのアップロード (upload_to_s3.yml
)
on:
workflow_call:
inputs:
aws-s3-path:
type: string
required: true
secrets:
sample-secret-value:
required: true
jobs:
upload-to-s3:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
コンテナデプロイの処理 (deploy_to_ecs.yml
)
on:
workflow_call:
inputs:
image-name:
type: string
required: true
cluster-name:
type: string
required: true
service-name:
type: string
required: true
secrets:
sample-secret-value:
required: true
jobs:
deploy-to-ecs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
テスト環境のデプロイ (deploy_test.yml
)
name: 'deploy test'
on:
workflow_dispatch:
jobs:
skip-upload:
runs-on: ubuntu-latest
steps:
- run: echo "Skip upload"
deploy:
needs: skip-upload
uses: ./.github/workflows/deploy_to_ecs.yml
with:
image-name: sample-test
cluster-name: sample-test-cluster
service-name: sample-test-service
secrets:
sample-secret-value: ${{ secrets.SAMPLE_SECRET_VALUE_TEST }}
ステージング環境のデプロイ (deploy_staging.yml
)
name: 'deploy staging'
on:
workflow_dispatch:
jobs:
upload:
uses: ./.github/workflows/upload_to_s3.yml
with:
aws-s3-path: s3://sample/staging/path
secrets:
sample-secret-value: ${{ secrets.SAMPLE_SECRET_VALUE_STAGING }}
deploy:
needs: upload
uses: ./.github/workflows/deploy_to_ecs.yml
with:
image-name: sample-staging
cluster-name: sample-stating-cluster
service-name: sample-staging-service
secrets:
sample-secret-value: ${{ secrets.SAMPLE_SECRET_VALUE_STAGING }}
本番環境のデプロイ (deploy_production.yml
)
name: 'deploy production'
on:
workflow_dispatch:
jobs:
upload:
uses: ./.github/workflows/upload_to_s3.yml
with:
aws-s3-path: s3://sample/production/path
secrets:
sample-secret-value: ${{ secrets.SAMPLE_SECRET_VALUE_PRODUCTION }}
deploy:
needs: upload
uses: ./.github/workflows/deploy_to_ecs.yml
with:
image-name: sample-production
cluster-name: sample-production-cluster
service-name: sample-production-service
secrets:
sample-secret-value: ${{ secrets.SAMPLE_SECRET_VALUE_PRODUCTION }}
ハマった箇所
workflow_call
イベントを使用するにあたり、ハマった箇所について2つ紹介します。
stepsでワークフローファイルを呼び出すとエラーになる
再利用可能なワークフローを呼び出すときに、steps
内で呼び出していたところエラーになりました。
jobs
内で呼び出さないといけないようです。
以下の通り、公式ドキュメントの制約事項にも記述がありました。
Reusable workflows are called directly within a job, and not from within a job step. You cannot, therefore, use GITHUB_ENV to pass values to job steps in the caller workflow.
1つだけ別のワークフローを呼び出すとエラーになる
テスト環境のデプロイで使用するワークフローには、skip-upload
ジョブを定義しています。
これは、以下のエラー文の通り、workflow_call
イベントのみを使用したジョブを定義することができないため使用しています。
The workflow must contain at least one job with no dependencies.
今後取り組みたいこと
ワークフローファイルで、workflow_call
イベントを使用したワークフローファイルの分割以外にも取り組みたいことについて、以下にまとめます。
Environments secretsの活用
GitHub Actionsでは、Environments欄より環境を設定できます。
さらに、環境ごとに環境変数とシークレット変数を定義できます。
現状では、リポジトリ単位でシークレット変数を定義しており、変数名の末尾に_TEST
や_PRODUCTION
といった環境名を定義しています。
Environments secretsを活用して、それぞれの環境ごとにシークレット変数を用意したいと考えています。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/e/excite-kazuki/20231218/20231218114927.png)
docs.github.com
workflow_dispatch
イベントを使用して手動実行するときに、inputs
を使用することで、セレクトボックスを配置できます。
例えば、以下のように環境名を選択肢に入れることで、その値をワークフローファイル内で使用することができます。
また、上記のEnvironments secretsと併用することで、より使いやすいワークフローファイルを定義できそうです。
on:
workflow_dispatch:
inputs:
ENV:
description: 環境を指定します
default: test
required: true
type: choice
options:
- test
- staging
- production
docs.github.com
おわりに
本記事では、workflow_call
イベントを使用したワークフローの分割とその際にハマった箇所、今後取り組みたいことについて紹介しました。
エキサイトブログでは、既存機能の改修や新機能の開発などに取り組みやすい環境を作るために、CI/CDの整備にも力を入れていきます。
採用アナウンス
エキサイトではフロントエンジニア、バックエンドエンジニア、アプリエンジニアを随時募集しています。
また、長期インターンも歓迎しています。
カジュアル面談からもOKです。少しでもご興味がございましたら、お気軽にご連絡頂ければ幸いです。
▼ 募集職種一覧 ▼
recruit.jobcan.jp