From 7218a3af720e0996489a5a43aa28001789281ced Mon Sep 17 00:00:00 2001 From: danielmeppiel Date: Fri, 29 May 2026 14:03:38 +0200 Subject: [PATCH] fix(shared/apm.md): avoid gh-aw expression harvesting inside bash comment gh-aw v0.76+ scans the body of `run:` blocks for GitHub Actions expression tokens and hoists them into the step's env: block. It does this even for tokens that appear inside `#` shell comments. shared/apm.md:325 contained a comment that, for documentation purposes, included the literal expression form of a secrets-context reference. v0.76+ harvested that into env: GH_AW_EXPR_36F7BDB0: ${{ secrets.* }} which fails workflow load with 'A sequence was not expected' because the wildcard secrets-context filter evaluates to a sequence, not a string. This broke pr-review-panel, triage-panel, and docs-sync at template-load time on every triggering event (see PR #1538 CI failure). Fix: rewrite the comment so it documents the contract without spelling out the literal expression syntax. Recompiled the three affected lock files. No behaviour change in the resolved step; the env block now only carries ROW_INDEX / ROW_KIND as intended. Filing upstream against github/gh-aw separately so future expression harvesting respects shell-comment boundaries. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/docs-sync.lock.yml | 16 ++++++++++++---- .github/workflows/pr-review-panel.lock.yml | 16 ++++++++++++---- .github/workflows/shared/apm.md | 13 ++++++++++--- .github/workflows/triage-panel.lock.yml | 16 ++++++++++++---- 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/.github/workflows/docs-sync.lock.yml b/.github/workflows/docs-sync.lock.yml index 0d91a8d22..89bb8e03d 100644 --- a/.github/workflows/docs-sync.lock.yml +++ b/.github/workflows/docs-sync.lock.yml @@ -1038,9 +1038,16 @@ jobs: # ROW_PRIVATE_KEY values so downstream tolerance is irrelevant. pk="${pk%$'\n'}" # Defence in depth: the PK is already masked because it came from - # a $GH_AW_EXPR_36F7BDB0 reference at compile time, but registering it - # again here makes the contract explicit and survives any future - # gh-aw template churn that might lose the secret tag. + # a secrets-context reference at compile time (gh-aw substitutes + # the configured private-key secret into AW_APM_*), but + # registering it again here makes the contract explicit and + # survives any future gh-aw template churn that might lose the + # secret tag. NOTE: do not write GitHub Actions expression syntax + # (dollar-doublecurly ... doublecurly) inside this comment. + # gh-aw v0.76+ harvests such tokens out of bash run-block bodies + # (even inside `#` comments) and hoists them into the step env, + # which fails workflow load when the inner expression resolves + # to a sequence (e.g. wildcard secrets-context references). echo "::add-mask::$pk" # Use a random heredoc delimiter to eliminate any chance of a PEM # line collision terminating the value early. The official docs @@ -1054,7 +1061,8 @@ jobs: printf '%s\n' "$delim" } >> "$GITHUB_ENV" env: - GH_AW_EXPR_36F7BDB0: ${{ secrets.* }} + ROW_INDEX: ${{ matrix.group.index }} + ROW_KIND: ${{ matrix.group.kind }} - name: Mint installation token id: token if: ${{ matrix.group.has-app == 'true' }} diff --git a/.github/workflows/pr-review-panel.lock.yml b/.github/workflows/pr-review-panel.lock.yml index 6141b1012..943172723 100644 --- a/.github/workflows/pr-review-panel.lock.yml +++ b/.github/workflows/pr-review-panel.lock.yml @@ -1068,9 +1068,16 @@ jobs: # ROW_PRIVATE_KEY values so downstream tolerance is irrelevant. pk="${pk%$'\n'}" # Defence in depth: the PK is already masked because it came from - # a $GH_AW_EXPR_36F7BDB0 reference at compile time, but registering it - # again here makes the contract explicit and survives any future - # gh-aw template churn that might lose the secret tag. + # a secrets-context reference at compile time (gh-aw substitutes + # the configured private-key secret into AW_APM_*), but + # registering it again here makes the contract explicit and + # survives any future gh-aw template churn that might lose the + # secret tag. NOTE: do not write GitHub Actions expression syntax + # (dollar-doublecurly ... doublecurly) inside this comment. + # gh-aw v0.76+ harvests such tokens out of bash run-block bodies + # (even inside `#` comments) and hoists them into the step env, + # which fails workflow load when the inner expression resolves + # to a sequence (e.g. wildcard secrets-context references). echo "::add-mask::$pk" # Use a random heredoc delimiter to eliminate any chance of a PEM # line collision terminating the value early. The official docs @@ -1084,7 +1091,8 @@ jobs: printf '%s\n' "$delim" } >> "$GITHUB_ENV" env: - GH_AW_EXPR_36F7BDB0: ${{ secrets.* }} + ROW_INDEX: ${{ matrix.group.index }} + ROW_KIND: ${{ matrix.group.kind }} - name: Mint installation token id: token if: ${{ matrix.group.has-app == 'true' }} diff --git a/.github/workflows/shared/apm.md b/.github/workflows/shared/apm.md index 47194cd1d..9e3a18256 100644 --- a/.github/workflows/shared/apm.md +++ b/.github/workflows/shared/apm.md @@ -322,9 +322,16 @@ jobs: # ROW_PRIVATE_KEY values so downstream tolerance is irrelevant. pk="${pk%$'\n'}" # Defence in depth: the PK is already masked because it came from - # a ${{ secrets.* }} reference at compile time, but registering it - # again here makes the contract explicit and survives any future - # gh-aw template churn that might lose the secret tag. + # a secrets-context reference at compile time (gh-aw substitutes + # the configured private-key secret into AW_APM_*), but + # registering it again here makes the contract explicit and + # survives any future gh-aw template churn that might lose the + # secret tag. NOTE: do not write GitHub Actions expression syntax + # (dollar-doublecurly ... doublecurly) inside this comment. + # gh-aw v0.76+ harvests such tokens out of bash run-block bodies + # (even inside `#` comments) and hoists them into the step env, + # which fails workflow load when the inner expression resolves + # to a sequence (e.g. wildcard secrets-context references). echo "::add-mask::$pk" # Use a random heredoc delimiter to eliminate any chance of a PEM # line collision terminating the value early. The official docs diff --git a/.github/workflows/triage-panel.lock.yml b/.github/workflows/triage-panel.lock.yml index 8e6b4e56f..44f074dc2 100644 --- a/.github/workflows/triage-panel.lock.yml +++ b/.github/workflows/triage-panel.lock.yml @@ -1136,9 +1136,16 @@ jobs: # ROW_PRIVATE_KEY values so downstream tolerance is irrelevant. pk="${pk%$'\n'}" # Defence in depth: the PK is already masked because it came from - # a $GH_AW_EXPR_36F7BDB0 reference at compile time, but registering it - # again here makes the contract explicit and survives any future - # gh-aw template churn that might lose the secret tag. + # a secrets-context reference at compile time (gh-aw substitutes + # the configured private-key secret into AW_APM_*), but + # registering it again here makes the contract explicit and + # survives any future gh-aw template churn that might lose the + # secret tag. NOTE: do not write GitHub Actions expression syntax + # (dollar-doublecurly ... doublecurly) inside this comment. + # gh-aw v0.76+ harvests such tokens out of bash run-block bodies + # (even inside `#` comments) and hoists them into the step env, + # which fails workflow load when the inner expression resolves + # to a sequence (e.g. wildcard secrets-context references). echo "::add-mask::$pk" # Use a random heredoc delimiter to eliminate any chance of a PEM # line collision terminating the value early. The official docs @@ -1152,7 +1159,8 @@ jobs: printf '%s\n' "$delim" } >> "$GITHUB_ENV" env: - GH_AW_EXPR_36F7BDB0: ${{ secrets.* }} + ROW_INDEX: ${{ matrix.group.index }} + ROW_KIND: ${{ matrix.group.kind }} - name: Mint installation token id: token if: ${{ matrix.group.has-app == 'true' }}