出力を入力へ

プログラミングに関する自分が考えた事を中心にまとめます

GitHub Actionsのsteps.withディレクティブでは環境変数ではなく出力パラメータを利用する

タイトルがすべて.

steps.with ディレクティブにおける制御

GitHub ワークフローにてActionsを呼び出すとき, Actionsのパラメータ設定としてsteps.withディレクティブを利用する.

例えば,GitHubのリリースページにビルド成果物をアップロードする Upload Release Asset Actions では以下のように指定する.

jobs:
  build:
    name: Upload Release Asset
    runs-on: ubuntu-latest
    steps:
      ...
      - name: Upload Release Asset
        id: upload-release-asset 
        uses: actions/upload-release-asset@v1.0.1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./my-artifact.zip
          asset_name: my-artifact.zip
          asset_content_type: application/zip

ここで, steps.withディレクティブ以下の upload_url, asset_path, asset_name, asset_content の4つが upload-release-asset Actionsの入力パラメータである.

入力パラメータの動的制御

Releaseページにアップロードするファイルを指定する asset_path において, ビルドソフトウェアのバージョンが含まれたファイルを指定したい. ソフトウェアバージョンを環境変数に設定したとして, 以下のような利用方法を想定する.

jobs:
  build:
    name: Upload Release Asset
    runs-on: ubuntu-latest
    steps:
      ...
      - name: Set software version
        run: |
          VERSION=$(cat VERSION)
          echo ${ VERSION }
      - name: Upload Release Asset
        id: upload-release-asset 
        uses: actions/upload-release-asset@v1.0.1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./my-artifact-${ VERSION }.zip
          asset_name: my-artifact-${ VERSION }.zip
          asset_content_type: application/zip

このように,VERSIONファイルに格納されているソフトウェアバージョンをVERSION変数に格納し, ビルド成果物の制御にこの値を利用したい. しかし,この方法には以下の2つ問題がある

このため,Set software versionのステップにおける echo ${ VERSION }では期待した通りの値が出力されるが, Upload Release Assetのステップではそんなファイル存在しない (##[error]ENOENT: no such file or directory )と怒られてしまう. これは,VERSION 変数が設定されていない問題と,仮に設定されていたとしてもその変数を利用できない問題の両方を解決する必要がある.

出力パラメータによる制御

ではどうするかと言うと環境変数ではなく 出力パラメータ(output parameter)を利用しましょう,というのが解決策である. 出力パラメータは別のステップから出力結果を参照するための仕組みであり, steps.withディレクティブでも利用できる.

jobs:
  build:
    name: Upload Release Asset
    runs-on: ubuntu-latest
    steps:
      ...
      - name: Set software version
        id: software_version
        run: |
          VERSION=$(cat VERSION)
          echo ::set-output name=version::${ VERSION }
          echo ${ VERSION }
      - name: Check output parameter value
        run: |
          echo ${{ steps.software_version.outputs.version }}
      - name: Upload Release Asset
        id: upload-release-asset 
        uses: actions/upload-release-asset@v1.0.1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./my-artifact-${{ steps.software_version.outputs.version }}.zip
          asset_name: my-artifact-${{ steps.software_version.outputs.version }}.zip
          asset_content_type: application/zip

このように, Set software version ステップにて VERSION変数の値を出力パラメータに設定しているので, 後段の Check output parameter value では最初に設定した VERSION 変数と同じ出力を確認することができ, Upload Release Assetステップの asset_pathasset_name でも利用することができる.