この記事ではgithub actions
を用いて、React+TypeScriptで作成したアプリを自動テストして、App Engineに自動デプロイする方法の一例を紹介します。僕自身、Circle CIに挑戦してみたけど挫折して、試しにGithub actionsを利用してみたら結構すんなりできたので、そういう人にもおすすめかもしれません。
以下、自動デプロイ→CD、自動テスト→CIとします。
また、想定している読者は以下の通りです。
- Circle CIに挑戦してみたけど挫折した人
- github actionsが何なのかなんとなくわかる人
- 既に手動であればテストもデプロイもできる人
ちなみに「github actions?なにそれ?」となる人は参考記事を紹介しておきます。
Github Actionsの使い方メモ
Github Actionsが使えるようになったので使ってみる
どのタイミングでCI/CDが動くのか
まずは、どのタイミングでCICDが走るのか確認しておきましょう。
以下の表をご覧ください。
タイミング | |
---|---|
CI | Pull Request(以下PR)が作成されたタイミング |
CD | PRがmasterブランチにmergeされたタイミング |
今回は、これらのタイミングでCICDが走るようにコードを書きます。
最終的に完成したコード(CI)
github actionsでは.github/workflows/
配下の1つのyamlファイルが1つのワークフローとなります。
今回は、CI用で1つ、CD用で1つのファイルを用意しました。
まずはCI用のtest.yaml
から。
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Node.js CI
on: pull_request
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [15.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v2
- name: Cache Node.js modules
uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.OS }}-node-
${{ runner.OS }}-
- name: docker-compose up
run: docker-compose up -d firestore
- run: sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
- run: npm install -g npm@latest
- run: rm package-lock.json
- run: rm -rf node_modules
- run: sed -i 's/babel-jest//g' package.json
- run: npm install
- run: CI=false npm run build
- run: npm test
ファイルの中身について
github actionsのnew workflow
にあるテンプレートに自分なりに付け足していく感じになります。
そのテンプレートに手動でテストするときのコマンドを記載していきます。
僕の場合、手動でテストする場合は、
- firebase emulatorを起動(docker-compose)
- npm run test
という手順をとっているので、まずはdocker-compose up -d firestore
、npm run test
というコマンドを記述したのですが、実際にPRを作成してみると様々なエラーでワークフローが止まります。これに関しては人によって違うと思うのですが、僕の場合はエラーメッセージを調べつつ、エラーを一つ一つ解消するようにコマンドを追加していった結果が上記のようになりました。
最終的に完成したコード(CD)
次にapp engineに自動デプロイするためのdeploy.yaml
になります。
name: CD
# Controls when the action will run.
on:
pull_request:
types: [closed]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
if: github.event.pull_request.merged == true
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- uses: google-github-actions/setup-gcloud@master
with:
project_id: ${{ secrets.GCP_PROJECT_ID }}
service_account_key: ${{ secrets.GCP_SA_KEY }}
export_default_credentials: true
# Runs a single command using the runners shell
- run: rm package-lock.json
- run: rm -rf node_modules
- name: npm install, build
run: |
npm install
CI=false npm run build
env:
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
# Runs a set of commands using the runners shell
- name: GAE deploy
run: |
echo ${{ secrets.GCP_SA_EMAIL }} |
gcloud app deploy --quiet
ファイルの中身について
デプロイは手動の場合は、
- npm run build
- gcloud app deploy
で行っています。test同様これだけをyamlに記述してもうまくいきません。エラーが色々起こります。
それを一つ一つ解決していき、最終的に上記のようなファイルになっています。
また、
on:
pull_request:
types: [closed]
としているのですが、これはPRがクローズされたタイミング、つまりmasterブランチにmergeされたタイミングでファイルに記述したワークフローが動くというものです。
実行環境(runs-onの部分)はubuntu
を利用していますが、これはgcloudコマンドがデフォルトで利用できるからです。circle CIだとpathを通さないといけなく、そこで結局挫折したのですが、それがデフォルトで使えるとなるとubuntuを利用しない手はありません。
また、uses: google-github-actions/setup-gcloud@master
の部分では、githubのsecretsに登録しておいたgcloudのサービスアカウントの認証情報
を読み込んでいます。
まとめ
github actionsはcircle CIに比べて、参考となる記事や自分と同じような環境で実行している人の情報が少ないため、色々手探りのような感じになると思いますが、環境ごとのワークフローのテンプレートが豊富に用意されているので、個人的にはcircle CIよりも使いやすい印象を受けました。デプロイでは認証の部分で少してこずりましたが、思いのほか簡単にできたので、github actionsに挑戦してみて良かったと思っています。