Github Actions入門その5-式と関数
はじめに
以下のエントリに引き続き、Github Actions を学習して学んだことをまとめて見ました。
- Github Actions 入門その 1-概要と用語の整理 | ゲンゾウ用ポストイット
- Github Actions 入門その 2-簡単なワークフローを作成してみる | ゲンゾウ用ポストイット
- Github Actions 入門その 3-アクションを探す・使う・自作する | ゲンゾウ用ポストイット
- Github Actions 入門その 4-環境変数/スクリプト/Artifacts を使う | ゲンゾウ用ポストイット
今回は Github Actions の学習シリーズの第 5 弾として、ワークフローの YAML 設定ファイル内で使用可能な式について解説します。
その後、式の種類や使い方について説明していきます。
式について
環境変数の設定や実行中のワークフローの状態を取得するために「式」を利用できます。
式を使うと、以下のようなことができます。
- リテラルの結合
- 実行中の環境情報の取得 ( 実行者、仮想マシン、等 )
- 関数呼び出し ( 値の加工等 )
算術計算のために演算子を使うこともできます。
式は if
キーワードと一緒に利用されることが多いです。
プログラミング言語のように、 if
で指定した式の値が true
となったときに、該当のステップが実行されます。
「文字列」ではなく「式」であると Github Actions に認識させるためには、以下の構文を使います。
${{ <式> }}
if
キーワードの値として式を使用した場合は、 ${{ ... }}
の構文を指定しないこともあります。
というのも、Github Actions は if:
以降に指定した記述を「式」として評価・処理するためです。if:
以降の記述に関しては、冗長かもしれませんが ${{ ... }}
の形式で記述しておくのが間違いないでしょうし、チームメンバにとってもわかりやすいでしょう。
以下のサンプルコードでは、 if
と環境変数へのセットを行っています。
文字列リテラル部分には注意が必要です。
ダブルクォーテーション ("
) は利用できず、 シングルクォーテーション('
)を使用する必要があります。
---
name: if-example
run-name: if-example
on:
- push
jobs:
if-example:
runs-on: ubuntu-22.04
steps:
- run: echo "hello false"
if: ${{ false }}
- run: echo "hello true"
if: ${{ true }}
- run: echo "hello $MY_ENV_VAR"
env:
MY_ENV_VAR: ${{ 'development' }}
$ gh run view --log 4841370653 | grep 'Run '
if-example Run echo "hello true" 2023-04-29T23:53:03.4496319Z ##[group]Run echo "hello true"
if-example Run echo "hello true" 2023-04-29T23:53:03.4496794Z echo "hello true"
if-example Run echo "hello true" 2023-04-29T23:53:03.4958971Z shell: /usr/bin/bash -e {0}
if-example Run echo "hello true" 2023-04-29T23:53:03.4959442Z ##[endgroup]
if-example Run echo "hello true" 2023-04-29T23:53:03.5502239Z hello true
if-example Run echo "hello $MY_ENV_VAR" 2023-04-29T23:53:03.5692289Z ##[group]Run echo "hello $MY_ENV_VAR"
if-example Run echo "hello $MY_ENV_VAR" 2023-04-29T23:53:03.5692775Z echo "hello $MY_ENV_VAR"
if-example Run echo "hello $MY_ENV_VAR" 2023-04-29T23:53:03.5744301Z shell: /usr/bin/bash -e {0}
if-example Run echo "hello $MY_ENV_VAR" 2023-04-29T23:53:03.5744685Z env:
if-example Run echo "hello $MY_ENV_VAR" 2023-04-29T23:53:03.5745102Z MY_ENV_VAR: development
if-example Run echo "hello $MY_ENV_VAR" 2023-04-29T23:53:03.5745390Z ##[endgroup]
if-example Run echo "hello $MY_ENV_VAR" 2023-04-29T23:53:03.5978957Z hello development
リテラル
式 ( ${{ ... }}
) の中では、以下のリテラルが利用できます。
type | value |
---|---|
boolean | true / false |
null | null |
number | JSON でサポートされているフォーマット |
string | シングルクォーテーション ' で囲む。 |
${{ 'value' }}
の表記の場合、 ${{ ... }}
で囲む必要はないです。
例
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Print variables
run: |
echo $myNull
echo $myBoolean
echo $myIntegerNumber
echo $myFloatNumber
echo $myHexNumber
echo $myExponentialNumber
echo $myString
echo $myStringInBraces
env:
myNull: ${{ null }}
myBoolean: ${{ false }}
myIntegerNumber: ${{ 711 }}
myFloatNumber: ${{ -9.2 }}
myHexNumber: ${{ 0xff }}
myExponentialNumber: ${{ -2.99e-2 }}
myString: Mona the Octocat
myStringInBraces: ${{ 'It''s open source!' }}
実行結果は以下のようになります。
false
711
-9.2
255
-0.0299
Mona the Octocat
It's open source!
関数
Github Actions では組み込み関数が提供されています。
関数は式の中で利用可能です。
いくつかの関数は、値を文字列に変換します。
関数の文字列変換のルールは型ごとに異なります。
以下のルールが適用されます。
型 | 結果 |
---|---|
Null | '' |
Boolean | 'true' or 'false' |
Number | 10 進数表現 または 値の大きな数値の場合は指数表現 |
Array | 文字列に変換されない |
Object | 文字列に変換されない |
contains
contains( search, item )
配列 search
の中に item
という要素が含まれていた場合に true
を返します。search
が string 型の場合は、 item
という文字列を含んでいた場合に true
を返します。
大文字小文字は区別されません 。
例 1
contains( 'Hello world', 'llo' )
は true
を返します。
例 2
以下の例では、もしイベントが発生した対象のイシューに "bug" というラベルが付与されていた場合に true
を返します。
contains( github.event.issue.labels.*.name, 'bug' )
例 3
github.event_name == "push" || github.event_name == "pull_request"
と記述する代わりに、 contains()
関数と fromJSON()
関数を組み合わせて記述できます。
contains(fromJSON('["push", "pull_requrest"]', github.event.name))
startsWith
startsWith( searchString, searchValue )
saarchString
で指定した文字列が searchValue
で指定した文字列で始まっている場合は true
となります。
大文字小文字は区別されません 。
例 1
startWtih('Hello world', 'He')
は true
を返します。
endWtith
endWith(searchString, searchValue)
searchString
の文字列が searchValue
で終わっていた場合、 true
を返します。
大文字小文字は区別されません 。
例 1
endsWith('Hello world', 'ld')
は true
を返します。
format
format( string, replaceValue0, replaceValue1, ..., replaceValueN)
string
で指定した文字列を、 replaceValue0
... replaceValueN
で指定した値で置換します。
置換対象の文字列は string
文字列の中で {N}
の形式で指定されます。N
の部分は数値を指定します。replaceValueN
は 1 つ以上指定する必要がありますが、上限はありません。
波括弧をエスケープしたいときは、 {{ ... }}
のように二重に重ねます。
例 1
format('Hello {0} {1} {2}', 'Mona', 'the', 'Octocat')
は Hello Mona the Octocat
を返します。
例 2
format('{{Hello {0} {1} {2}!}}', 'Mona', 'the', 'Octocat')
は {Hello Mona the Octocat!}
を返します。
join
join( array, optionalSeparator )
array
は配列か文字列を指定できます。array
の要素をつなげて1つの文字列にします。
もし optionalSeparator
が指定されたときは、連結された値の間に optionalSeparator
の値が挿入されます。optionalSeparator
が指定されたなかった場合は、 ,
が指定されたものとして動作します。
例 1
join(github.event.issue.labels.*.name, ', ')
の実行結果は 'bug, help wanted'
のようになります。
ここではラベルとして bug
と help wanted
が指定されているものとします。
toJSON
toJSON(value)
value
で指定した値を JSON 文字列表現に変換します。
デバッグ用に利用することが多いでしょう。
例 1
toJSON(job)
は {"status":"success"}
を返します。
fromJSON
fromJSON(value)
value
で指定された JSON の文字列表現を解析し、オブジェクトを返却します。
文字列リテラルや環境変数を Object、Boolean、Number に変換する場合にも利用されます。
例 1
job1
ジョブで実行した結果を JSON 文字列として出力し、 job2
ジョブでパースします。
name: build
on: push
jobs:
job1:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- id: set-matrix
run: echo "matrix={\"include\":[{\"project\":\"foo\",\"config\":\"Debug\"},{\"project\":\"bar\",\"config\":\"Release\"}]}" >> $GITHUB_OUTPUT
job2:
needs: job1
runs-on: ubuntu-latest
strategy:
matrix: ${{ fromJSON(needs.job1.outputs.matrix) }}
steps:
- run: build
例 2
このワークフローでは、環境変数の値を Boolean や Integer に変換するために fromJSON
関数を使用しています。
name: print
on: push
env:
continue: true
time: 3
jobs:
job1:
runs-on: ubuntu-latest
steps:
- continue-on-error: ${{ fromJSON(env.continue) }}
timeout-minutes: ${{ fromJSON(env.time) }}
run: echo ...
hashFiles
hashFiles(path)
指定したファイルパス ( ファイル OR ディレクトリ ) からハッシュ値を算出し返します。path
はパターン形式で指定できます。
また、カンマ区切りで文字列を複数指定できます。path
は GITHUB_WORKSPACE
環境変数にセットされているディレクトリからの相対パスで指定します。
必然的に、 GITHUB_WORKSPACE
環境変数のディレクトリ以下のファイルだけしか指定できないこととなります。
ハッシュ値の計算には SHA-256
アルゴリズムが利用されます。
大文字小文字は「Windows 環境でのみ」区別されません 。
例 1
package-lock.json
ファイルをすべて探し、ハッシュ値を算出します。
hashFiles('**/package-lock.json')
例 2
例 1 に加えて、 Gemfile.lock
を加えたハッシュ値を算出します。
hashFiles(' **/package-lock.json', '** /Gemfile.lock')
ステータスチェック用の関数
ここからはステータスチェック用の関数について触れていきます。
多くの場合、 if
フィールドの「式」中で利用されます。
if
フィールドが指定されていなかったとしても、各ステップは if: ${{ success() }}
が設定されたものとして動作します。
つまり、1 つ前のステップが成功しなかった場合には後続のステップはスキップされます。
success
1つ前のステップの実行結果が失敗やキャンセルされなかった場合、 true
を返します。
例
steps:
...
- name: The job has succeeded
if: ${{ success() }}
always
前段ステップの実行結果に関わらず、常に実行されます。
後始末や終了ログを送信するために使用されます。
例
if: ${{ always() }}
cancelled
ワークフローがキャンセルされたときに true
を返します。
例
if: ${{ cancelled() }}
failure
前段のステップの実行が失敗した場合に true
を返します。
更に複雑な失敗のチェック
失敗したステップを明確に特定したい場合は以下のような if
フィールドを記述します。
ここでは、失敗を特定したい事前ステップに demo
という名前を付与し、 steps.demo.conclusion
変数をチェックしています。
steps:
...
- name: Failing step
id: demo
run: exit 1
- name: The demo step has failed
if: ${{ failure() && steps.demo.conclusion == 'failure' }}
ひとこと
Github Actions で式を使うことで、より効率的な自動化が可能となります。
学習コストがかかるかもしれませんが、慣れてしまえば非常に使いやすく、大量の手作業を減らすことができます。
ぜひ、挑戦してみてください。
ディスカッション
コメント一覧
まだ、コメントがありません