GitHub Actions によるデプロイの手動起動で開発体験を改善する
オンライン家庭教師マナリンク 開発の Technote です。
今回は GitHub Actions
を利用した開発体験改善の取り組みの一部を紹介します。
背景
もともと develop
ブランチにマージでステージングに、master
ブランチにマージで本番にそれぞれデプロイする workflow
が組まれていました。
本番でも使用している Docker
環境を使用しているので、各自ローカルで本番に近い環境で開発できていますが、Expo
のプッシュ通知や外部からの Webhook
の動作などは確認が難しい、もしくはできない場合があります。
費用的、開発規模的な面からしばらくはサーバーはステージングと本番のみで運用したい、でも develop
にマージする前に動作確認もしたい...
一応 develop
ブランチだけではなく特定の名前(例: for-actions/deploy
)がついたブランチにプッシュすることでステージングにデプロイするようにもなっていましたが、以下のような問題がありました。
- 確認後にステージングを
develop
ブランチの状態に戻すのが面倒 - 特定の名前のブランチにプッシュはしたいけどデプロイはしたくない場合はアクションをキャンセルする必要があり面倒
この状況を少しでも改善するために GitHub Actions
でいつでも簡単にデプロイできるようにしました。
やったこと
PR にデプロイ用ラベルを付与でデプロイ
プルリクを作成している場合、そのプルリクに特定のラベルを追加することで workflow
が起動するようにしました。
- デプロイ開始時に「デプロイ用」ラベルを剥がして「デプロイ中」ラベルを付与
- デプロイ処理
- 「デプロイ中」ラベルを剥がす
以下がその workflow
です。
on:
pull_request:
types: [ labeled ]
name: Manual Deploy
jobs:
# デプロイを起動するかどうかチェック
# 後で追加する起動条件のためにチェックとデプロイを分けておく
check:
name: Whether to run
runs-on: ubuntu-latest
timeout-minutes: 1 # ほぼラベルのチェックだけなのでタイムアウトを短く設定
outputs:
run: ${{ env.RUN_FLAG }} # 後続のjobでチェックの結果を使用
steps:
# 特定のラベル (例: Deploy) の場合にフラグを立てる
- run: echo "RUN_FLAG=1" >> $GITHUB_ENV
if: github.event.label.name == 'Deploy'
# actions/github-script は Octokit も利用できる JavaScript を実行できちゃうすごいやつ
# ここでは Deploy ラベルを剥がして Deploying ラベルを付ける
- uses: actions/github-script@v4
name: Remove label
if: github.event.label.name == 'Deploy Staging'
with:
script: |
github.issues.removeLabel({
...context.repo,
issue_number: context.issue.number,
name: 'Deploy'
})
github.issues.addLabels({
...context.repo,
issue_number: context.issue.number,
labels: ['Deploying']
})
deploy:
name: Deploy
runs-on: ubuntu-latest
timeout-minutes: 10 # タイムアウトは必ず設定しましょう
needs: check
if: needs.check.outputs.run # check ジョブの結果を使用
steps:
- name: Checkout
uses: actions/checkout@v2
# 任意のデプロイステップ
# ...
# 付与した Deploying ラベルを剥がす
remove-label:
name: Remove Label
runs-on: ubuntu-latest
timeout-minutes: 1 # ラベルを剥がすだけなのでタイムアウトを短く設定
needs: deploy
# デプロイジョブが失敗していてもラベルを剥がす
# failure の場合は Slack に通知などの処理を入れてもいいかも
if: always() && needs.check.outputs.run
steps:
- uses: actions/github-script@v4
name: Remove label
with:
script: |
github.issues.removeLabel({
...context.repo,
issue_number: context.issue.number,
name: 'Deploying'
})
ラベルの付与のようなイベントでも起動できるのは本当に使い勝手がいいです。
他にも起動させられるイベントが色々あって眺めるだけでも楽しいです。
手動で任意のブランチをデプロイ
develop
ブランチの状態に戻したり、プルリクを作成していないブランチのデプロイにも対応できるようにブランチを指定して起動できるようにしました。
とは言っても起動できるようにするには以下の1行を追加するだけです‥!
on:
pull_request:
types: [ labeled ]
+ workflow_dispatch:
これだけでアクションの画面からブランチを選択して起動できるようになります。
ただ今回はプルリクへのラベル追加の時にも起動するので、workflow
内の if
を少し書き換える必要があります。
前述の workflow
を少し書き換えて最終的には以下のような workflow
になりました。
on:
pull_request:
types: [ labeled ]
+ workflow_dispatch:
name: Manual Deploy
jobs:
check:
name: Whether to run
runs-on: ubuntu-latest
timeout-minutes: 1
outputs:
run: ${{ env.RUN_FLAG }}
steps:
- run: echo "RUN_FLAG=1" >> $GITHUB_ENV
- if: github.event.label.name == 'Deploy'
+ if: github.event_name == 'pull_request' && github.event.label.name == 'Deploy'
+ - run: echo "RUN_FLAG=1" >> $GITHUB_ENV
+ if: github.event_name == 'workflow_dispatch'
- uses: actions/github-script@v4
name: Remove label
- if: github.event.label.name == 'Deploy Staging'
+ if: github.event_name == 'pull_request' && github.event.label.name == 'Deploy'
with:
script: |
github.issues.removeLabel({
...context.repo,
issue_number: context.issue.number,
name: 'Deploy'
})
github.issues.addLabels({
...context.repo,
issue_number: context.issue.number,
labels: ['Deploying']
})
deploy:
name: Deploy
runs-on: ubuntu-latest
timeout-minutes: 10
needs: check
if: needs.check.outputs.run
steps:
- name: Checkout
uses: actions/checkout@v2
# 任意のデプロイステップ
# ...
remove-label:
name: Remove Label
runs-on: ubuntu-latest
timeout-minutes: 1
needs: deploy
- if: always() && needs.check.outputs.run
+ if: always() && needs.check.outputs.run && github.event_name == 'pull_request'
steps:
- uses: actions/github-script@v4
name: Remove label
with:
script: |
github.issues.removeLabel({
...context.repo,
issue_number: context.issue.number,
name: 'Deploying'
})
以上の設定により、当初の課題であったステージングサーバー上での動作確認への心理的障壁を下げることができました。
また、Firebase
などの PaaS
でも同じように workflow
を用意すれば動作確認がより手軽に行うことができます。
オンライン家庭教師マナリンクを運営するスタートアップNoSchoolのテックブログです。 manalink.jp/ 創業以来年次200%前後で売上成長しつつ、技術面・組織面での課題に日々向き合っています。 カジュアル面談はこちら! forms.gle/fGAk3vDqKv4Dg2MN7
Discussion