この記事で説明・提供していること
- GitHub Actionsの基礎知識:かんたんな用語整理(Actions, Workflow, Job, Step)
- Pull Requestのオープン(
opened
)と追加コミット・プッシュ(synchronize
)時だけ実行されるWorkflowの書き方 - CI(test)が成功したときだけDeployが実行されるWorkflow (Job)の書き方
- 実行するアクションの中でPull Request(PR)のNumber(
#99
)やRepository名を取得する方法 - Zeit NowにPR毎のアプリ(Review Apps)をPR NumberをURLに含むかたちでDeployする方法
- ↑でDeployされたReview AppのURLをPRにコメントとして書き込む方法
- これらが書かれたGitHub Actions(v2)設定yamlの完成コード
Change Log
- 2019/09/10 13:00:初稿として全体コードだけ載せました。詳細は後で書きます(ストックしておくと更新通知が来るので良かったらどうぞ)
- 2019/12/04 20:00:全体コードに加えて各パートの解説を書きました
GitHub Actionsの基礎知識
-
Actions
: あるRepositoryに存在するWorkflow
の集まり -
Workflow
: Repositoryに対する特定の行動(Push, Pull Request, etc.)に対して実行されるJob
の集まり -
Job
: 複数(または単一)のStep
を含むWorkflow
の実行単位。 各Job
は並列で実行されるが依存関係を設定することもできる。 実行されるプラットフォーム(Ubuntu etc.)の指定もここで行う -
Step
:Job
内で順番に実行される一つ一つの処理。前の処理の成功・失敗に応じて実行有無を変えることも可能
設定yamlの完成コード
パーツ毎の説明は後述するので、まずは最初に設定ファイル全体を載せます。( 説明は後で書きます 書きました)
また、完成コードを含むExampleをGitHubに置きました。
noriaki/gh-actions-example-with-zeit-nextjs-and-now: Example of GitHub Actions v2 with Zeit Next.js and Now
設定yamlコードの場所は~/.github/workflows/pull_request.ymlです。
on:
pull_request:
types: [opened, synchronize]
name: Test and Deploy with PR number alias and comment apps URL
jobs:
test:
name: CI Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
with:
fetch-depth: 1
- name: "[INFO] Versions"
run: |
echo "node: `node --version`"
echo "npm: v`npm --version`"
echo "yarn: v`yarn --version`"
- name: Install packages
run: >-
yarn install
--frozen-lockfile
--ignore-optional
--no-progress
--non-interactive
- name: Test
run: yarn test
deploy_to_zeit_now_staging:
name: Deploy and Alias with PR number
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v1
with:
fetch-depth: 1
- name: "[INFO] Versions"
run: |
echo "node: `node --version`"
echo "npm: v`npm --version`"
echo "yarn: v`yarn --version`"
echo "now: v`now --version`"
- name: Deploy
env:
ZEIT_TOKEN: ${{ secrets.ZEIT_TOKEN }}
run: >
now deploy
--build-env NODE_ENV=production
--env NODE_ENV=production
--public
--no-clipboard
--token ${ZEIT_TOKEN}
> ${HOME}/deployment-url.txt
- name: Alias with PR number
env:
ZEIT_TOKEN: ${{ secrets.ZEIT_TOKEN }}
run: >
now alias
--token ${ZEIT_TOKEN}
`cat ${HOME}/deployment-url.txt`
${{ github.event.repository.name }}-pr-${{ github.event.number }}.now.sh
post_comment_review_app_url:
name: Post comment that review app URL when PR opened
runs-on: ubuntu-latest
needs: deploy_to_zeit_now_staging
steps:
- name: Post comment review app URL by GitHub API
if: github.event_name == 'pull_request' && github.event.action == 'opened'
run: >
curl
-X POST
-H "Authorization: token $GITHUB_TOKEN"
-H "Accept: application/vnd.github.v3+json"
--data "{ \"body\": \"Review-App was deployed.\nhttps://${{ github.event.repository.name }}-pr-${{ github.event.number }}.now.sh\" }"
${{ github.event.pull_request.comments_url }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
以下、完成コードから一部抜粋するかたちで解説していきます。
Pull Requestのオープン(opened
)と追加コミット・プッシュ(synchronize
)時だけ実行されるWorkflowの書き方
on:
pull_request:
types: [opened, synchronize]
冒頭のこの部分でpull_request
の「opened
:プルリクオープン時」と「synchronize
:オープン済みプルリクに追加プッシュ時」を指定しています。
CI(test)が成功したときだけDeployが実行されるWorkflow (Job)の書き方
jobs:
test: # <- (a)
name: CI Test
runs-on: ubuntu-latest
# ...中略...
deploy_to_zeit_now_staging: # <- (b)
name: Deploy and Alias with PR number
runs-on: ubuntu-latest
needs: test
# ↑`needs`で指定した値(この場合`test`)をIDに持つJob(a)が
# 正常終了した場合だけこのJob(b)が実行される
コメントに書いたとおりですが、needs:
に指定したJob IDが正常に終了したら実行されます。
ちなみにJob IDは同じWorkflow内で重複しなければ任意のものを指定できます。また、配列で指定すれば複数のJobの正常終了を条件にすることも可能(GitHub Help)です。
実行するアクションの中でPull Request(PR)のNumber(#99
)やRepository名を取得する方法
${{ github.event.repository.name }}
にリポジトリの名前が、${{ github.event.number }}
にプルリクNumberが入っていて、以下のようにRunコマンドの中に書くと実行時に展開されます。
- name: Alias with PR number
env:
ZEIT_TOKEN: ${{ secrets.ZEIT_TOKEN }}
run: >
now alias
--token ${ZEIT_TOKEN}
`cat ${HOME}/deployment-url.txt`
${{ github.event.repository.name }}-pr-${{ github.event.number }}.now.sh
その他に取得できる情報は以下のページに書いてあります。
Contexts and expression syntax for GitHub Actions - GitHub Help
ちなみに、上記コードのrun: >
というのは、それ以降のヒアドキュメント文字列を半角空白()で連結する
YAML
の記法です。
Zeit NowにPR毎のアプリ(Review Apps)をPR NumberをURLに含むかたちでDeployする方法
プルリク内容を本番に近い状態で確認できるようにすると、コードに加えて動作もレビューすることができます。これは、個人的にHerokuのキラー機能と思っているHeroku Review Appsで実現されているものですが、同じことをZeit Now
で実現するためのJobです。
deploy_to_zeit_now_staging:
name: Deploy and Alias with PR number
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v1
with:
fetch-depth: 1
# (1)
- name: "[INFO] Versions"
run: |
echo "node: `node --version`"
echo "npm: v`npm --version`"
echo "yarn: v`yarn --version`"
echo "now: v`now --version`"
- name: Deploy
env: # (2)
ZEIT_TOKEN: ${{ secrets.ZEIT_TOKEN }}
run: > # (3)
now deploy
--build-env NODE_ENV=production
--env NODE_ENV=production
--public
--no-clipboard
--token ${ZEIT_TOKEN}
> ${HOME}/deployment-url.txt
- name: Alias with PR number
env:
ZEIT_TOKEN: ${{ secrets.ZEIT_TOKEN }}
run: >
now alias
--token ${ZEIT_TOKEN}
`cat ${HOME}/deployment-url.txt`
${{ github.event.repository.name }}-pr-${{ github.event.number }}.now.sh
この設定コードのポイントとしては、以下3点です。
- Zeit Nowのデプロイ等のコマンドラインツール
now
は、node
やyarn
と同じく(1)でバージョン表示しているようにubuntu-latest
に最初からインストールされています1 - (2)の部分で指定している
secrets.ZEIT_TOKEN
はZeitのTokensページで発行したものを、対象のリポジトリ設定(settings/secrets)にZEIT_TOKEN
という名前で保存すれば使えます - 同一Job内のStep間で値を受け渡ししたいときは、(3)
> ${HOME}/deployment-url.txt
のように${HOME}
ディレクトリ以下にファイルとして保存し、以降のStepで`cat ${HOME}/deployment-url.txt`
のように読み出すことが可能です
DeployされたReview AppのURLをPRにコメントとして書き込む方法
post_comment_review_app_url:
name: Post comment that review app URL when PR opened
runs-on: ubuntu-latest
needs: deploy_to_zeit_now_staging
steps:
- name: Post comment review app URL by GitHub API
if: github.event_name == 'pull_request' && github.event.action == 'opened'
run: >
curl
-X POST
-H "Authorization: token $GITHUB_TOKEN"
-H "Accept: application/vnd.github.v3+json"
--data "{ \"body\": \"Review-App was deployed.\nhttps://${{ github.event.repository.name }}-pr-${{ github.event.number }}.now.sh\" }"
${{ github.event.pull_request.comments_url }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
プルリクのオープン時のみ実行されるJob
冒頭でプルリクのオープン時・追加Push時に実行されるWorkflowについて説明しましたが、以下の部分ではjob毎に実行条件を指定しています。以下の場合、プルリクでオープン時のみ実行されます。2
if: github.event_name == 'pull_request' && github.event.action == 'opened'
GitHub Actionsの中からGitHub APIを叩く
GitHub Actions実行時に自動でセットされているsecrets.GITHUB_TOKEN
には書き込み権限があるため、curl
でGitHub APIのコメント投稿(Issue Comments)のエンドポイント${{ github.event.pull_request.comments_url }}
にPOSTしてあげればOKです。
run: >
curl
-X POST
-H "Authorization: token $GITHUB_TOKEN"
-H "Accept: application/vnd.github.v3+json"
--data "{ \"body\": \"Review-App was deployed.\nhttps://${{ github.event.repository.name }}-pr-${{ github.event.number }}.now.sh\" }"
${{ github.event.pull_request.comments_url }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
その他に使えるSoftwareの一覧:Software installed on GitHub-hosted runners - GitHub Help ↩
-
その他
if:
に指定できる条件:Workflow syntax for GitHub Actions - GitHub Help ↩