はじめに
GitHubActionsのformat関数を使えばhashFilesの引数にEnvを渡せることを知ったので,その紹介です
結論
format
関数を使う
key: ${{ runner.os }}-cargo-registry-${{hashFiles(format('{0}/Cargo.lock', env.WORKING_DIRECTORY))}}
背景
GitHubActionsでキャッシュを使う際,.lockファイルをハッシュ化しそれをキー値として利用します
# https://github.com/actions/cache/blob/master/examples.md#rust---cargo
- name: Cache cargo registry
uses: actions/cache@v1
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo index
uses: actions/cache@v1
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo build
uses: actions/cache@v1
with:
path: target
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
このときに下記のようにhashFilesに渡す引数のlockファイルに,特定のサブディレクトリ上のものを指定したい
できれば特定のアプリに依存する処理をあちこちに書かずにこれを実現したい
下記を使えば前者は実現できるのですが,ディレクトリ名を変更した際にステップすべてを書き換える必要があるのでなるべくやりたくなかった
- name: Cache cargo build
uses: actions/cache@v1
with:
path: target
# subappに依存している
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/subapp/Cargo.lock') }}
調査
まっさきに思いついた方法はyamlのアンカーだったがGitHubActionsはアンカーに対応していない...
すこし調べてみるとどうやらenv変数はステップの中で使えるらしい
# https://github.community/t5/GitHub-Actions/use-working-directory-for-entire-job/td-p/36759
env:
WORKING_DIRECTORY: "subapp"
steps:
- name: dir
run: ls -R
# ちなみにですがworking-directory keyは`uses`の場合使えない..
working-directory: ${{env.WORKING_DIRECTORY}}
これをそのまま使ってみる
# ダメだったやつ
key: ${{ runner.os }}-cargo-registry-${{hashFiles(env.WORKING_DIRECTORY/'Cargo.lock')}}
# ダメだったやつ
key: ${{ runner.os }}-cargo-registry-${{hashFiles({{env.WORKING_DIRECTORY}}/'Cargo.lock')}}
結果Unexpected symbolに遭遇
なんかないかなーとGitHubActionsのドキュメント読んでると,format関数があることを知る
format( string, replaceValue0, replaceValue1, ..., replaceValueN)
Replaces values in the string, with the variable replaceValueN. Variables in the string are specified using the {N} syntax, where N is an integer. You must specify at least one replaceValue and string. There is no maximum for the number of variables (replaceValueN) you can use. Escape curly braces using double braces.
ドキュメント上にはenvを使った例はなかったですが,envの値を試してみる
key: ${{ runner.os }}-cargo-registry-${{hashFiles(format('{0}/Cargo.lock', env.WORKING_DIRECTORY))}}
結果エラーもなく,無事通過!やりたかったことを実現できた
最終的には下記のような感じになります
WORKING_DIRECTORY
の値を変更するだけで各ステップの値を変更することができ満足
env:
WORKING_DIRECTORY: "subapp"
steps:
- uses: actions/checkout@v2
- uses: actions/cache@v1
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{hashFiles(format('{0}/Cargo.lock', env.WORKING_DIRECTORY))}}
- uses: actions/cache@v1
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-index-${{hashFiles(format('{0}/Cargo.lock', env.WORKING_DIRECTORY))}}