Skip to content

fix(safe_jobs): hoist expression env vars into step env: block to prevent run-script guardrail failure#32532

Open
Copilot wants to merge 11 commits into
mainfrom
copilot/aw-compat-daily-summary-2026-05-16
Open

fix(safe_jobs): hoist expression env vars into step env: block to prevent run-script guardrail failure#32532
Copilot wants to merge 11 commits into
mainfrom
copilot/aw-compat-daily-summary-2026-05-16

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 16, 2026

Safe jobs with env: values containing GitHub Actions expressions (e.g. GH_TOKEN: ${{ github.token }}) caused the compiler regression guardrail to fire on their own compiled output — microsoft/aspire's milestone-changelog.md was the reproducer.

Root cause

buildSafeJobs unconditionally inlined all env: values into the run: script via echo:

run: |
  echo "GH_TOKEN=${{ github.token }}" >> "$GITHUB_OUTPUT"  # guardrail violation

validateNoGitHubExpressionsInRunScriptsFromParsed (which github.token does not pass) then rejected the compiled lock file.

Fix

  • pkg/workflow/safe_jobs.go: Classify each env: entry as expression-based (${{ present) or literal. Expression entries are emitted in the step's env: block; the run: script references them as shell variables instead.
env:
  GH_TOKEN: ${{ github.token }}   # evaluated by Actions runner, not shell
run: |
  echo "GH_TOKEN=${GH_TOKEN}" >> "$GITHUB_OUTPUT"  # shell var, no inline expression

Literal values continue to be written directly in the run: script unchanged. Keys are sorted in both categories for deterministic output.

  • pkg/workflow/safe_jobs_test.go: Added TestBuildSafeJobsEnvExpressionHoisting covering the mixed expression/literal case, asserting the expression never appears inline in run: and that the shell variable reference and env: block are both present.

Changeset\n\n- Type: patch\n- Description: Hoist expression-based safe job environment variables into step env: blocks so compiled run: scripts no longer inline GitHub Actions expressions and trigger the guardrail.

Generated by 📋 Changeset Generator for issue #32532 ·



✨ PR Review Safe Output Test - Run 25953787843

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

💥 [THE END] — Illustrated by Smoke Claude · ● 3.9M ·


pr-sous-chef: attempted branch update (run: https://github.com/github/gh-aw/actions/runs/25956153961)

Generated by 👨‍🍳 PR Sous Chef ·

Copilot AI and others added 3 commits May 16, 2026 02:42
…cripts into env blocks

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…to avoid run script inline expressions

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…orted slices

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Update daily AW compatibility summary for 2026-05-16 fix(safe_jobs): hoist expression env vars into step env: block to prevent run-script guardrail failure May 16, 2026
Copilot AI requested a review from pelikhan May 16, 2026 02:51
@pelikhan pelikhan marked this pull request as ready for review May 16, 2026 02:53
Copilot AI review requested due to automatic review settings May 16, 2026 02:53
@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot secrets like github.token should never be written to output

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a compiler regression guardrail failure for safe-jobs when job env: values contain GitHub Actions expressions (e.g. ${{ github.token }}), by ensuring expressions are not inlined inside run: scripts in the compiled lock output.

Changes:

  • Update buildSafeJobs to split job env vars into expression-based vs literal, hoisting expression-based entries into the step-level env: block and referencing them via shell variables in run:.
  • Sort env keys within both categories for deterministic compiled output.
  • Add a unit test covering mixed expression + literal env var behavior.
Show a summary per file
File Description
pkg/workflow/safe_jobs.go Hoists expression-based env vars into step env: and avoids ${{ ... }} in run: by echoing ${VAR} instead.
pkg/workflow/safe_jobs_test.go Adds coverage to ensure expressions are not inlined in run: and are present in env:.
.github/workflows/daily-model-inventory.lock.yml Regenerated lock file output reflecting the updated compilation behavior.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 3/3 changed files
  • Comments generated: 0

…T to prevent secret leaks

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 16, 2026

@copilot secrets like github.token should never be written to output

Fixed. Expression-based env vars (values containing ${{ ... }}) are no longer written to $GITHUB_OUTPUT at all. Instead they are injected with their original expression directly into each downstream step's env: block, where the Actions runner evaluates them safely — they never touch the output file. Only literal values continue to flow through $GITHUB_OUTPUT. See commit fix(safe_jobs): never write expression-based env vars to GITHUB_OUTPUT to prevent secret leaks.

@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot review the safe_job code generation and the ensure secrets are never stored in outputs

…tten to GITHUB_OUTPUT in compiled lock file

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 16, 2026

@copilot review the safe_job code generation and the ensure secrets are never stored in outputs

Reviewed all code generation paths in safe_jobs.go. The only place $GITHUB_OUTPUT is written is the "Configure Safe Outputs Job Environment Variables" step. Expression-based env: values (those containing ${{, e.g. ${{ github.token }}, ${{ secrets.FOO }}) are classified at compile time and are never echoed to $GITHUB_OUTPUT — they are injected directly into each downstream step's env: block with the original expression. Literal values continue to flow through step outputs as before.

Added TestSafeJobsExpressionEnvNeverWrittenToOutput (commit test(safe_jobs): add integration test verifying...) which does a full CompileWorkflow and then scans every line of the compiled lock file to assert no ${{ expression ever appears on a line writing to GITHUB_OUTPUT.

@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot review why the environment variables need to be written to the output

… env vars directly into step env: blocks

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 16, 2026

@copilot review why the environment variables need to be written to the output

They don't need to be. The original design wrote env vars to $GITHUB_OUTPUT so downstream steps could reference them via ${{ steps.setup-safe-job-env.outputs.KEY }}. But since all job-level env vars are known at compile time, they can be injected directly into each step's env: block — including GH_AW_AGENT_OUTPUT, which now uses the ${{ runner.temp }} Actions expression instead of capturing the shell ${RUNNER_TEMP} through an output.

Removed all $GITHUB_OUTPUT writes from buildSafeJobs in commit fix(safe_jobs): eliminate $GITHUB_OUTPUT writes entirely — inject all env vars directly into step env: blocks. Literal values, expression-based values, and the artifact path are all injected directly — nothing sensitive ever touches the output file.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 16, 2026

🚀 Smoke Pi MISSION COMPLETE! Pi delivered. 🥧

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 16, 2026

🚀 Smoke Gemini MISSION COMPLETE! Gemini has spoken. ✨

Caution

agentic threat detected
Threat detection flagged this output in warn mode. Manual review is REQUIRED before any follow-up automation.

Details

The threat detection results could not be parsed.

Review the workflow run logs for details.

@github-actions
Copy link
Copy Markdown
Contributor

📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing...

@github-actions github-actions Bot removed the smoke label May 16, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 16, 2026

💫 TO BE CONTINUED... Smoke Claude failed to deliver outputs! Our hero faces unexpected challenges...

@github-actions
Copy link
Copy Markdown
Contributor

Agent Container Tool Check

Tool Status Version
bash 5.2.21
sh available
git 2.54.0
jq 1.7
yq 4.53.2
curl 8.5.0
gh 2.92.0
node 22.22.2
python3 3.14.5
go 1.24.13
java 10.0.300
dotnet NOT FOUND

Result: 11/12 tools available

Overall Status: FAILdotnet (.NET runtime) is not installed in the agent container.

🔧 Tool validation by Agent Container Smoke Test · ● 1.2M ·

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 16, 2026

Smoke OTEL Backends completed successfully!

@github-actions
Copy link
Copy Markdown
Contributor

Commit pushed: 85dc43c

Generated by Changeset Generator

@github-actions
Copy link
Copy Markdown
Contributor

Caution

agentic threat detected
Threat detection flagged this output in warn mode. Manual review is REQUIRED before any follow-up automation.

Details

The threat detection results could not be parsed.

Review the workflow run logs for details.

Smoke Test Results

  • GitHub MCP Testing: ✅
  • Web Fetch Testing: ✅
  • File Writing Testing: ✅
  • Bash Tool Testing: ✅
  • Build gh-aw: ❌

Overall Status: FAIL

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • localhost

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "localhost"

See Network Configuration for more information.

Smoke Gemini — Powered by Gemini ·

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Codex 25953787851: ❌ FAIL
PRs: #32541 feat: make E003 file-count error actionable and document max-patch-files; #32548 [jsweep] Clean action_input_utils.cjs
✅ GitHub MCP, Serena, Playwright, file write, bash cat, build, comment memory, cache memory, set_issue_field
❌ Web Fetch MCP: tool unavailable in this environment
Run: https://github.com/github/gh-aw/actions/runs/25953787851

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex ·

@github-actions
Copy link
Copy Markdown
Contributor

Comment Memory

Quiet tests awake
Cold logs hold steady truth
Green checks meet dawn light

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex ·

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test: Claude — Run §25953787843

Core (1–12): ✅ all passed
PR review (13–18): ✅ all passed · #19: ⚠️ skipped (no safe test PR)
Overall: PARTIAL (1 intentional skip)

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

💥 [THE END] — Illustrated by Smoke Claude · ● 3.9M ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💥 Automated smoke test review - all systems nominal! Run 25953787843.

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

💥 [THE END] — Illustrated by Smoke Claude · ● 3.9M

@github-actions
Copy link
Copy Markdown
Contributor

👋 Smoke test agent was here! Everything is running smoothly — tests pass, Copilot is awake, and the automation is humming along. 🤖✨

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot · ● 11.9M ·

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test: ✅ PASS

Test
GitHub MCP
MCP Scripts GH
Serena CLI
Playwright
Web Fetch
File Write
Build gh-aw
Artifact Upload
Discussion
PR Review
Sub-Agent

PR author: @copilot-swe-agent · Assignees: @pelikhan, @Copilot · Run

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot · ● 11.9M ·

@github-actions
Copy link
Copy Markdown
Contributor

Comment Memory

# Smoke Test Notes

Code bytes flow like data streams,
Tests pass in the night with green beams,
Copilot dreams.

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot · ● 11.9M ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick smoke-test review pass. The refactor in safe_jobs.go looks clean — hoisting env vars directly into step env: blocks is simpler and safer than routing through $GITHUB_OUTPUT.

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot · ● 11.9M

Comment thread pkg/workflow/safe_jobs.go
// All job-specific env vars (literal or expression-based) are injected with
// their original values. Nothing goes through $GITHUB_OUTPUT.
for key, value := range jobConfig.Env {
setupEnvVars[key] = value
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice simplification — removing the intermediate $GITHUB_OUTPUT write reduces one step and avoids the shell-injection risk that came with echoing arbitrary env var values. Using runner.temp expression directly is cleaner.

@github-actions
Copy link
Copy Markdown
Contributor

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@github-actions
Copy link
Copy Markdown
Contributor

@copilot review all comments

Please address the unresolved review thread about the unnecessary step.

Generated by 👨‍🍳 PR Sous Chef ·

@github-actions
Copy link
Copy Markdown
Contributor

Please post a short progress update after rerunning checks so maintainers can see the remaining blocker.

Generated by 👨‍🍳 PR Sous Chef ·

@github-actions github-actions Bot mentioned this pull request May 16, 2026
@github-actions
Copy link
Copy Markdown
Contributor

@copilot review all comments

Please address unresolved review feedback and propose fixes. — pr-sous-chef (run: https://github.com/github/gh-aw/actions/runs/25956153961)

Generated by 👨‍🍳 PR Sous Chef ·

@github-actions
Copy link
Copy Markdown
Contributor

Quick nudge: @copilot please summarize remaining blockers and next steps to get this PR merge-ready. — pr-sous-chef

Generated by 👨‍🍳 PR Sous Chef ·

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[aw-compat] Daily AW compatibility summary 2026-05-16: 18/19 repos green, 1 hard failure (microsoft/aspire)

3 participants