Skip to content

[aw-compat] Missing codemod: auto-hoist run-block $\{\{ ... }} expressions to env: bindings #32527

@github-actions

Description

@github-actions

Problem

The compiler emits a hard error when any inline ${{ ... }} GitHub Actions expression remains inside a run: shell script in the generated lock.yml:

error: compiler regression detected: GitHub Actions expressions found in run: shell scripts of compiled workflow

The compiler must rewrite expressions in run: blocks to env variables.
Use env: assignments and shell variable references instead of inline ${{ ... }} in run: scripts.

There is currently no codemod in gh aw fix that rewrites the source workflow to eliminate this pattern. Users hit a wall: the compiler says "the compiler must rewrite" but the compiler doesn't, and fix has nothing for this case.

Evidence (cross-run signal)

  • microsoft/aspire.github/workflows/milestone-changelog.md
    • Failed on 2026-05-15 daily run
    • Failed again on 2026-05-16 daily run with the same error
    • 3 other workflows in the same repo were auto-fixed cleanly; only this pattern is left behind.

The error specifically calls out ${{ github.token }} inside a run: heredoc:

Examples found:
  - ${{ github.token }}
    in: echo "GH_TOKEN=${{ github.token }}" >> "$GITHUB_OUTPUT"

Proposed codemod: auto-hoist-run-expressions

Scan source .md workflow files for ${{ ... }} expressions inside run: blocks (both literal-scalar | form and inline string form). For each occurrence:

  1. Generate a stable, deterministic env var name from the expression (e.g. ${{ github.token }}EXPR_GITHUB_TOKEN, ${{ env.FOO }}EXPR_FOO, dedup across the step).
  2. Add the binding under the step's env: block (create the block if missing).
  3. Replace the inline ${{ ... }} with $VARNAME (or "$VARNAME" inside double-quoted contexts) inside the run script.
  4. Preserve original indentation, quoting style, and surrounding text.

Before

- name: Capture token
  run: |
    echo "GH_TOKEN=${{ github.token }}" >> "$GITHUB_OUTPUT"

After

- name: Capture token
  env:
    EXPR_GITHUB_TOKEN: ${{ github.token }}
  run: |
    echo "GH_TOKEN=$EXPR_GITHUB_TOKEN" >> "$GITHUB_OUTPUT"

Why this is high priority (P1)

  • It is the only hard compile failure in the top-20 audit two days in a row.
  • The compiler's own error message describes the exact rewrite the codemod should perform.
  • It closes the loop: users would no longer need to read the error and manually rewrite.
  • The compiler safeguards in the meantime (writing to .invalid.yml) confirm the pattern is well-classified.

Edge cases to handle

  • Expressions that resolve to non-string values (numeric, boolean) → keep env binding (Actions always stringifies).
  • Expressions inside quoted strings vs. bare context → preserve quoting around the variable reference.
  • Multiple occurrences of the same expression in one run block → reuse the same env var.
  • Multiple distinct expressions in one step → emit each as its own EXPR_* binding.
  • PowerShell / shell: pwsh run blocks → use $env:VARNAME syntax instead of $VARNAME.
  • Conservative: leave inline expressions used as conditions/non-script contexts (if:, step args, etc.) alone — they are not affected by the regression check.

References

  • Companion: daily compatibility summary issue (2026-05-16)
  • §25949808920

Generated by 🔧 Daily AW Cross-Repo Compile Check · ● 13.5M ·

  • expires on May 23, 2026, 2:13 AM UTC

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions