ゴール
- GithubActionsを使ってPR作成時のTest&Buildのステータスチェックを実行する
https://go-tech.blog/category/githubactions/
導入手順
前提
- 何かしらのプロジェクトフォルダが作成されている
- 実行環境:Node.js + Typescript + Jest
手順
- GithubActionsのワークフローを作成
- Build実行
- Test実行
実装
ワークフローのファイル作成
最終的なディレクトリ構成と完成したワークフローは以下
├── .github
│ └── workflows
│ └── test-and-build.yml
│
├── src
│ └── index.ts
├── test
│ └── index.spec.ts
├── package-lock.json
├── package.json
└── tsconfig.json
name: Test and Build
on:
workflow_dispatch:
pull_request:
branches:
- develop
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
node: [16.18.1]
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
- name: Checkout
uses: actions/checkout@v3
- name: Setup node env
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run build
run: npm run build
run_test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
node: [16.18.1]
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
- name: Checkout
uses: actions/checkout@v3
- name: Setup node env
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run Test
run: npm run test
実行環境の準備
ビルドとテストを実行するために最低限の実行環境を用意
package.json
{
"name": "practice",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"build": "npx tsc",
"build:watch": "npx tsc --watch",
"test": "jest"
},
"jest": {
"transform": {
"^.+\\.m?[tj]sx?$": [
"ts-jest",
{
"tsconfig": "<rootDir>/tsconfig.json"
}
]
},
"preset": "ts-jest/presets/default-esm"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/jest": "^29.4.0",
"@types/node": "^18.11.18",
"jest": "^29.4.3",
"ts-jest": "^29.0.5",
"typescript": "^4.9.5"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "es2020",
"module": "esnext",
"moduleResolution": "node",
"outDir": "./dist",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
},
"include": ["./src/**/*.ts"]
}
index.ts
export const sum = (a: number, b: number) => {
return a + b;
};
index.spec.ts
import { sum } from '../src/index';
describe('sum', () => {
it('returns correct result', () => {
expect(sum(1, 2)).toBe(3);
});
});
Build実行
ビルドを実行するためのワークフローは以下
name: Test and Build
on:
workflow_dispatch:
pull_request:
branches:
- develop
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
node: [16.18.1]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup node env
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
- name: Install dependencies
run: npm ci
- name: Run build
run: npm run build
※公式Docを参考に作成
Test実行
buildのワークフローと同じようにtestも追加
name: Test and Build
on:
workflow_dispatch:
pull_request:
branches:
- develop
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
node: [16.18.1]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup node env
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
- name: Install dependencies
run: npm ci
- name: Run build
run: npm run build
#以下を追加
run_test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
node: [16.18.1]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup node env
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
- name: Install dependencies
run: npm ci
- name: Run Test
run: npm run test
PRのステータスチェックでどちらでエラーになったのかがわかりやすいようにジョブを分けている
※一緒にしてしまっても問題なし
キャッシュ
以前までは下記のように書いていたが、
- name: Cache node_modules
uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
下記の書き方でも依存関係をキャッシュしてくれるようになったのこと
- name: Setup node env
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
cache: npm
実行中のアクションを停止&再実行
アクション実行中に新たなcommitをした影響で別のアクションを実行され、重複しているようなケースがあった場合
→ 有効な手段としては、前に実行しているアクションをキャンセルする方法
下記アクションを利用
→ styfle/cancel-workflow-action
以下のように追加するのみ
name: Test and Build
on:
workflow_dispatch:
pull_request:
branches:
- develop
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
node: [16.18.1]
steps:
- name: Cancel Previous Runs #追加
uses: styfle/cancel-workflow-action@0.11.0 #追加
- name: Checkout
uses: actions/checkout@v3
- name: Setup node env
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run build
run: npm run build
run_test:
....略
動作確認
developブランチに対してPRを作成すると、以下のようにステータスチェックが走りました。
詳細も確認し、正しく実行できていることが確認できました。
補足
正直、ビルドとテストでほぼ同じStepsを書いているのでかなり冗長になってしまっています。
今回のケースに有効な手段として、「ワークフローの再利用(Reusing workflows)」があります。
(現在はprivateリポジトリにも対応しているとのこと)
※ https://docs.github.com/ja/actions/using-workflows/reusing-workflows
具体的な方法としては、共通部分を別ファイルのワークフローとして切り出して、それを今回のワークフロー内で呼び出す形になるとのこと。
管理するワークフローが増えれば増えるほど有効な手段だなと感じました。
バージョンアップの度に全てのファイルを変更するのは漏れにつながりますし、管理が大変です。
今回は割愛しますが、いずれ備忘録として記事にまとめたいと思います。
さいごに
ご覧いただきありがとうございました。
まだまだGithubActionsを使ってできることはたくさんありますので、他のユースケースに応じた方法を備忘録としてまとめていきたいと思います。