バージョンタグとはセマンティック バージョニング (SemVer) 2.0.0のような1.2.3
というバージョンの頭にv
が付いたv1.2.3
のようなタグの事をここでは指します。
例えば以下のようなワークフローがあるとします。これがv1.2.3
のようなタグをプッシュした時のみ、ジョブが実行されるワークフローです。これはセマンティック バージョニング (SemVer) 2.0.0echo fooと表示
されます。
on:
push:
branches-ignore:
- '**'
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-18.04
steps:
- run: echo foo
これは全体をタグがプッシュした時に実行というフィルターを掛けているような形になっています。ただケースによってはブランチプッシュでもタグプッシュでも共に実行したい共通ステップが出てきてしまったりするかもしれません。
この対応方法にはざっと以下のようなものがあります。
ブランチとタグで別々のワークフローを実行
ブランチとタグで同じワークフローを実行し、バージョンタグのプッシュ時にだけしか実行されないようなステップで対応
どちらが良いのかは規模感によって変わります。個人プロジェクトのような小さなものなら 1 で良いでしょうし、大きいなら 1 だと管理が辛くなるかもしれません。
1. ブランチとタグで別々のワークフローを実行
これは単にワークフローファイルを別々に置くというだけです。
例えば上記のワークフローがバージョンタグのプッシュ時のみというものだったので、ブランチプッシュ時のみ実行されるワークフローは以下のように書き始めます。
on: push
jobs: # 略
push
イベントはbrannchs
やtags
で何もフィルタリングしていない時、すべてのブランチが対象で全てのタグが除外という設定になるので、これだけでブランチ用のワークフローになります。
2. ブランチとタグで同じワークフローを実行し、バージョンタグのプッシュ時にだけしか実行されないようなステップで対応
同じワークフローで実行というのは、<job>.if
や<step>-if
などの制御を活用して、バージョンタグをプッシュした時だけに実行される領域をワークフロー内に作ろうという意味です。これにはまず 2 つの要素の理解をします。
1 つ目は参照の名前の存在です。何かしらをプッシュするとgithub
コンテキストのref
値に参照の名前が入ります。参照の名前というのはセマンティック バージョニング (SemVer) 2.0.0echo fooと表示ブランチのプッシュ
であればrefs/heads/<branch-name>
(refs/heads/master
など)、セマンティック バージョニング (SemVer) 2.0.0echo fooと表示ブランチのプッシュタグのプッシュ
であればrefs/tags/<tag-name>
(refs/tags/v0.0.2
など)のような名前のことです。
2 つ目はワークフロー内ではstartsWith
という関数が使えます。これは引数を文字列として 2 つ取り、 1 つ目の文字列が 2 つ目に渡した文字列から始まっていればtrue
を返します。
この 2 つの要素を組み合わせます。例えばタグの参照名はrefs/tags/
から始まると分かったので、startsWith( github.ref, 'refs/tags/' )
のようにすればタグの時だけtrue
になりそうです。ただ今回はバージョンダグを扱うので、refs/tags/v
とします。
上記から作成したブランチとバージョンタグが共存したワークフローが以下のようなものです。
on:
push:
branches:
- '**'
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-18.04
steps:
- run: echo ${{ github.ref }}
- if: startsWith( github.ref, 'refs/tags/v' )
env:
REF: ${{ github.ref }}
run: echo "${REF##*/}"
2 つ目のステップのenv.REF
とecho "${REF##*/}
はちょっとしたテクニックで、シェルが Bash (デフォルト)の時だけですが、このようにするとecho
でv0.0.3
のような値が表示(取得)できます。(ちなみにecho "${REF##*/v}
とすると0.0.3
という値になります)