概要
先日GitHub Actionsの設定ファイルの書き方が変わりました。
これまでは独自のフォーマットだったものが、YAMLで設定するようになりました。
tagでfilterする方法を調べたのでメモします。
やりたいこと
- リポジトリにpushされたら
- ユニットテストの実行
- ユニットテストをパスした かつ vで始まるtagがpushされた場合、リリースする
をやりたい。
普段はpushしたらその都度ユニットテストが実行され、tagもpushした場合のみリリースするということをやりたい
旧GitHub Actions設定ファイル
Node.jsのプロジェクトでnpm publishまでやる例
workflow "Build, Test, and Publish" {
on = "push"
resolves = ["Publish"]
}
action "Build" {
uses = "actions/npm@master"
args = "install"
}
action "Test" {
needs = "Build"
uses = "actions/npm@master"
args = "test"
}
# Filter for release tag
action "RelaseTag" {
needs = "Test"
uses = "actions/bin/filter@master"
args = "tag v*"
}
action "Publish" {
needs = "RelaseTag"
uses = "actions/npm@master"
args = "publish --access public"
secrets = ["NPM_AUTH_TOKEN"]
}
もうこの設定は使えなくなるので詳細は割愛しますが、
- リポジトリにpushされたら
- ユニットテストの実行
- ユニットテストをパスした かつ vで始まるtagがpushされた場合、リリースする
という動きをします。
リポジトリにpushされてもtagがなかったらユニットテストの実行だけ動きます。
新GitHub Actions設定ファイル
name: Node CI
on: [push]
jobs:
test:
name: Test on node ${{ matrix.node-version }} and ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [8.x, 10.x, 12.x]
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: npm install, build, and test
run: |
npm install
npm run build --if-present
npm test
env:
CI: true
publish:
name: npm publish
runs-on: ubuntu-latest
needs: [test]
steps:
- uses: actions/checkout@master
- uses: actions/setup-node@v1
with:
node-version: '12.x'
registry-url: 'https://registry.npmjs.org'
- run: npm install
if: contains(github.ref, 'tags/v')
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
if: contains(github.ref, 'tags/v')
旧と比べて 複数のNode.jsのバージョン、複数のOS でのテストが追加されていますがそれ以外はやっていることは同じです。
新GitHub Actions設定ファイルのポイント
on
での制御
特定の条件、例えば「特定のtagがpushされた時」をやりたい場合、上部の
on: [push]
でも制御できます。
参考: https://help.github.com/ja/articles/workflow-syntax-for-github-actions#on
ただしその条件が全体に適用されるので、旧での
リポジトリにpushされてもtagがなかったらユニットテストの実行だけ動きます。
この動きが実現できません。
if
と needs
ということで、on
では実現できないので別jobを作って対応します。
jobは基本的に並列で動くので、
- ユニットテストをパスした かつ vで始まるtagがpushされた場合、リリースする
の「テストをパスした後に」を実現するために needs
を使います。
needs: [test]
この設定を入れるとjobの「publish」は「test」が終わった後に実行されます。
「vで始まるtagがpushされた場合」を実現するためには if
を使います
- run: npm publish
if: contains(github.ref, 'tags/v')
これでvで始まるtagがpushされたときのみ npm publish
が動きます。
参考: https://help.github.com/ja/articles/contexts-and-expression-syntax-for-github-actions
まとめ
「普段はpushしたらその都度ユニットテストが実行され、tagもpushした場合のみリリースする」が実現できました。
on
がjobごとに設定できたらもう少しわかりやすくなるかも?
もう少しいい設定方法があったら知りたい
(全体的にまとまりのない文章ですみません)