背景
Terraform でインフラを管理していると、Pull Request に terraform plan の結果をコメントしたり、別ステップで整形して扱いたい場面があると思います。
ところが、この plan の出力は数千行に及ぶことも珍しくなく、GitHub Actions の $GITHUB_ENV や $GITHUB_OUTPUT を使った変数の受け渡しには向かないという問題にぶつかります。
GitHub Actions では環境変数やステップ出力のサイズに上限(おおむね 1MB 程度)があり、長すぎる環境変数の受け渡しによりジョブが失敗することがあるためです。
本記事では、Terraform plan のような「とにかく長いテキスト」をgithub actionsのステップ間で受け渡す方法を紹介します。
悪い例
長すぎる文字列が$GITHUB_ENVで受け渡しされた場合、どのような挙動になるのか確認します。
pull requestをトリガーとする簡単なgithub actionsのコードを作成しました。
わざと長い文字列を生成して$GITHUB_ENVに保存するステップと、環境変数を出力するだけのステップを作成しています。
name: BAD - ENV handoff
on:
pull_request:
jobs:
demo:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
# 長文を生成して環境変数に突っ込む
- name: Generate Big Text
run: |
yes "これはとても長い文字列です。" | tr -d '\n' | head -c 2000000 > big.txt
wc -c big.txt
BIG=$(cat big.txt)
echo "BIG<<EOF" >> "$GITHUB_ENV"
echo "$BIG" >> "$GITHUB_ENV"
echo "EOF" >> "$GITHUB_ENV"
# ENVから読み出して実際の長さを確認
- name: Check length from ENV
run: |
python - << 'PY'
import os
v = os.environ.get("BIG","")
print("ENV length:", len(v))
PY
実際にPRを出してみると、画像のようなエラーが出てしまいました。
(Argument list too longというエラーで、一見環境変数が原因のエラーと直感的にわかりづらいかもしれません。)
詳しくはこちらのissueが参考になると思います。
https://github.com/actions/runner/issues/1733

このように、長い文字列をGithub Actionsのstep間でやりとりをするためには、エラーを回避するための工夫が必要となります。
改善案
上記のエラーに対処済みのコードを以下に記載します。
単純に、環境変数に受け渡しをせず、ワークフローの実行環境でファイルを直接参照しています。
name: GOOD - File handoff
on:
pull_request:
permissions:
contents: read
issues: write
pull-requests: write
jobs:
demo:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
# 長文を生成してファイルに保存
- name: Generate Big Text
run: |
yes "これはとても長い文字列です。" | tr -d '\n' | head -c 2000000 > big.txt
wc -c big.txt
# ファイルから読み出して実際の長さを確認
- name: Check length from FILE
run: |
python - << 'PY'
from pathlib import Path
p = Path("big.txt")
data = p.read_bytes()
print("FILE length:", len(data))
PY
# PRコメントでプレビューを出す
- name: Post preview from file
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
const content = fs.readFileSync('big.txt', 'utf8');
const preview = content.slice(0, 200) + "\n...省略...";
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: [
"### 受け渡し(ファイル方式)プレビュー",
"",
"```",
preview,
"```"
].join("\n")
});
さきほどエラーになってしまったstepも無事に成功しました。

改善バージョンのgithub actionsのyamlではPRにプレビューをだすstepも追加しています。
こちらも正しく動作しており、ワークフローも成功していることが確認できました。

これまで環境変数でしか受け渡せないと思い込んでいたので、シンプルですが大きな気づきでした。
コメント