Fix Copilot PAT rotation for gh-aw v0.77.5 runtime - #736
Merged
Conversation
The PAT-rotation stop-gap wired the rotated token into engine.env via needs.pre_activation.outputs.copilot_pat_number. Because the compiled agent job depends only on 'activation' (not the built-in 'pre_activation'), that needs reference evaluated to an empty string in the agent job, so the case() fell through to the default COPILOT_GITHUB_TOKEN and rotation never reached the agent. gh-aw v0.77.5 surfaces this as a compiler warning. Replace the pre_activation step-injection with a 'select_copilot_pat' custom job wired via on.needs. As a user-defined job referenced in engine.env, the compiler makes it a direct dependency of the agent job, so needs.select_copilot_pat.outputs.copilot_pat_number resolves correctly in both the activation and agent jobs. Same action, same secret pool, same case() expression. Recompiled all workflows with gh-aw v0.77.5.
Non-destructive pull_request-triggered workflow that selects a pool token and asserts, in the agent job, that needs.select_copilot_pat.outputs.copilot_pat_number is non-empty (the exact value that was silently empty with the old pre_activation wiring). To be removed after validation.
gh-aw v0.77.5 emits the top-level frontmatter `if:` on the built-in
pre_activation job WITHOUT a ${{ }} wrapper. When the condition starts with
`!` (the fork guards), the emitted `if: !(...)` is invalid YAML (a leading `!`
starts a YAML tag), which GitHub rejects as a workflow-file startup failure.
v0.68.3 wrapped it (valid); v0.77.5 does not. Confirmed independent of the
PAT-rotation change via a minimal probe.
Wrap the fork-guard conditions in parentheses so the emitted scalar starts
with `(` instead of `!` (semantically identical). Affects close-stale-prs,
devops-health-check, devops-health-groom, markdown-linter, pr-malicious-scan.
JanKrivanek
marked this pull request as ready for review
June 9, 2026 16:54
JanKrivanek
enabled auto-merge (squash)
June 9, 2026 16:54
Contributor
There was a problem hiding this comment.
Pull request overview
This PR repairs Copilot PAT rotation in agentic GitHub Actions workflows when compiled with gh-aw v0.77.5 by moving token selection into an explicit custom job (select_copilot_pat) that becomes a direct dependency for jobs consuming engine.env.
Changes:
- Replace
pre_activationstep-injection with a dedicatedselect_copilot_patjob and updateengine.envto referenceneeds.select_copilot_pat.outputs.copilot_pat_number. - Recompile affected agentic workflows/lockfiles with gh-aw v0.77.5 and update the select-copilot-pat documentation accordingly.
- Update maintenance/dependabot config to align with the new gh-aw runtime/tooling behavior.
Show a summary per file
| File | Description |
|---|---|
| .github/workflows/pr-malicious-scan.agent.md | Introduces select_copilot_pat job and updates engine.env to consume its output. |
| .github/workflows/markdown-linter.md | Same PAT selection job wiring and engine.env update. |
| .github/workflows/issue-triage.md | Same PAT selection job wiring and engine.env update. |
| .github/workflows/issue-investigate.md | Same PAT selection job wiring and engine.env update. |
| .github/workflows/devops-health-investigate.md | Same PAT selection job wiring and engine.env update for the worker workflow. |
| .github/workflows/devops-health-investigate.lock.yml | Recompiled lockfile with PAT selection dependency and runtime/tooling updates. |
| .github/workflows/devops-health-groom.md | Same PAT selection job wiring and engine.env update. |
| .github/workflows/devops-health-check.md | Same PAT selection job wiring and engine.env update. |
| .github/workflows/close-stale-prs.agent.md | Same PAT selection job wiring and engine.env update. |
| .github/workflows/close-stale-prs.agent.lock.yml | Recompiled lockfile with PAT selection dependency and runtime/tooling updates. |
| .github/workflows/agentics-maintenance.yml | Recompiled maintenance workflow with gh-aw v0.77.5 and new operations. |
| .github/dependabot.yml | Adjusts dependabot configuration (including ignoring gh-aw managed actions). |
| .github/aw/actions-lock.json | Removes an old action pin entry; file now appears stale vs workflow references. |
| .github/actions/select-copilot-pat/README.md | Updates documentation to recommend select_copilot_pat custom job + on.needs. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (1)
.github/aw/actions-lock.json:32
.github/aw/actions-lock.jsonno longer contains any entry for thegithub/gh-aw-actions/*actions that the workflows now reference (for examplegithub/gh-aw-actions/setup@v0.77.5). It also still contains an entry forgithub/gh-aw/actions/setup@v0.71.5, which doesn’t appear to be used anywhere in.github/workflows. This file looks stale/inconsistent with the workflow pins and should be updated (or removed) so it accurately reflects the action refs used by the repo.
"github/gh-aw/actions/setup@v0.71.5": {
"repo": "github/gh-aw/actions/setup",
"version": "v0.71.5",
"sha": "19ac811a4a85389c33b15128e1d7b7d4507f814a"
}
- Files reviewed: 20/20 changed files
- Comments generated: 3
Contributor
|
👋 @JanKrivanek — this PR has 3 unresolved review thread(s). When you're ready, please address the feedback and push an update; the triage bot will pick up the next state automatically. (Add the |
ViktorHofer
approved these changes
Jun 9, 2026
JanKrivanek
added a commit
that referenced
this pull request
Jun 9, 2026
Adopt the shared workflow import pattern from dotnet/runtime PR #127946, replacing the per-workflow select-copilot-pat action + custom job (shipped in #736) with a reusable shared/pat_pool.md import. What changed: - Add .github/workflows/shared/pat_pool.md: an import that defines a `pat_pool` job (inline bash, no separate action) exposing a `pat_number` output, plus an import-schema mapping COPILOT_PAT_0..7 to this repo's pool secrets (COPILOT_GITHUB_TOKEN, COPILOT_GITHUB_TOKEN_2..8). - Add .github/workflows/shared/pat_pool.README.md documenting the pattern. - Convert all 8 agentic workflows to `imports: - shared/pat_pool.md` + `engine.env` `case(needs.pat_pool.outputs.pat_number ...)`. - Delete the now-unused .github/actions/select-copilot-pat action. - Add .github/workflows/validate-pat-pool.yml: a daily standalone workflow that validates each pool PAT with a Copilot CLI request and summarizes pool health. Wiring note (adaptation from runtime): consuming workflows declare `on.needs: [pat_pool]` instead of runtime's `needs: [pre_activation]` + `on.permissions: {}`. This wires pat_pool ahead of the pre_activation and activation jobs so the selected PAT is validated by the activation job and used by the agent, and it works for `roles: all` workflows (issue-triage), which do not produce a pre_activation job for the runtime workaround to attach to. Compiled with gh-aw v0.77.5. Verified end-to-end with a temporary test-pat-rotation workflow (since removed): a run selected token #2 of the 3-token pool and the agent job observed pat_number='2', confirming the rotated PAT reaches the agent.
JanKrivanek
added a commit
that referenced
this pull request
Jun 10, 2026
Adopt the shared workflow import pattern from dotnet/runtime PR #127946, replacing the per-workflow select-copilot-pat action + custom job (shipped in #736) with a reusable shared/pat_pool.md import. What changed: - Add .github/workflows/shared/pat_pool.md: an import that defines a `pat_pool` job (inline bash, no separate action) exposing a `pat_number` output, plus an import-schema mapping COPILOT_PAT_0..7 to this repo's pool secrets (COPILOT_GITHUB_TOKEN, COPILOT_GITHUB_TOKEN_2..8). - Add .github/workflows/shared/pat_pool.README.md documenting the pattern. - Convert all 8 agentic workflows to `imports: - shared/pat_pool.md` + `engine.env` `case(needs.pat_pool.outputs.pat_number ...)`. - Delete the now-unused .github/actions/select-copilot-pat action. - Add .github/workflows/validate-pat-pool.yml: a daily standalone workflow that validates each pool PAT with a Copilot CLI request and summarizes pool health. Wiring note (adaptation from runtime): consuming workflows declare `on.needs: [pat_pool]` instead of runtime's `needs: [pre_activation]` + `on.permissions: {}`. This wires pat_pool ahead of the pre_activation and activation jobs so the selected PAT is validated by the activation job and used by the agent, and it works for `roles: all` workflows (issue-triage), which do not produce a pre_activation job for the runtime workaround to attach to. Compiled with gh-aw v0.77.5. Verified end-to-end with a temporary test-pat-rotation workflow (since removed): a run selected token #2 of the 3-token pool and the agent job observed pat_number='2', confirming the rotated PAT reaches the agent.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
The Copilot PAT-rotation stop-gap was silently broken in the agent job, and the newer gh-aw v0.77.5 compiler surfaces it as a warning.
Root cause
The rotation wires the selected token into
engine.envviaCOPILOT_GITHUB_TOKEN: ${{ case(needs.pre_activation.outputs.copilot_pat_number ...) }}.But the compiled
agentjob only depends onactivation, not on the built-inpre_activation. GitHub Actions'needscontext only exposes direct dependencies, so inside the agent jobneeds.pre_activation.outputs.copilot_pat_numberevaluates to an empty string — thecase()falls through to the defaultCOPILOT_GITHUB_TOKEN, and rotation never reaches the agent (the early validation step in theactivationjob worked, which masked the bug). gh-aw v0.77.5 added a compiler warning that detects exactly this.This is the same warning that led dotnet/msbuild#13919 to remove PAT rotation entirely. This PR fixes it instead.
The fix (close to the original, fully supported)
Replace the
pre_activationstep-injection with a smallselect_copilot_patcustom job wired viaon.needs:select-copilot-pataction, same secret pool, samecase()expression — onlypre_activation→select_copilot_pat.engine.env, the compiler makes it a direct dependency of the agent job, soneeds.select_copilot_pat.outputs.copilot_pat_numberresolves correctly in both the activation and agent jobs. No built-in reference → no warning → rotation actually reaches the agent.Applied to all 8 agentic workflows and recompiled with gh-aw v0.77.5.
Validation
A temporary
test-pat-rotationworkflow (pull_request-triggered, non-destructive) selects a pool token and asserts in the agent job thatneeds.select_copilot_pat.outputs.copilot_pat_numberis non-empty — the exact value that was silently empty before. It will be removed before merge.Security review (compilation manifest)
COPILOT_GITHUB_TOKEN,COPILOT_GITHUB_TOKEN_2..8). The pool secrets are only read by theselect-copilot-pataction to pick a number (never the secret value), in a deterministic job with no untrusted input; fork PRs receive no secrets.github/gh-aw-actions/setup@v0.77.5,actions/github-script@v9.0.0, firewall0.25.58, mcp-gatewayv0.3.22,github-mcp-server v1.1.0.actions/checkoutand the localselect-copilot-pataction are unchanged.Note
Draft for verification of the PAT-rotation fix. Once the test workflow run is green, I'll drop the test workflow and mark ready.