LoginSignup
3
0

More than 3 years have passed since last update.

GitHubActionsのformat関数を使えばhashFilesの引数にenvを渡せる

Last updated at Posted at 2020-03-14

はじめに

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))}}
3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0