Keep git credentials in safe_outputs job checkouts#40161
Merged
Conversation
The safe_outputs job reuses the agent job's checkout generators, which emit persist-credentials: false so actions/checkout strips the credential http.extraheader in its post-checkout "Removing auth" step. That default is correct for the untrusted agent job, but the safe_outputs job legitimately runs git fetch/push (create_pull_request, push_to_pull_request_branch), so stripping auth leaves it relying on a fragile re-auth dance and can break bundle/branch fetches. Add a keepCredentialsForPush mode to CheckoutManager that the safe_outputs path enables. In that mode the default and additional checkout generators emit persist-credentials: true and skip the credential-cleanup step, leaving the push-capable token on disk for the handlers. The agent job is unchanged. Fixes #40159
Contributor
Comment MemoryNote This comment is managed by comment memory.It stores persistent context for this thread in the code block at the top of this comment.
|
Contributor
There was a problem hiding this comment.
Pull request overview
Updates gh-aw’s safe_outputs checkout generation so git credentials are retained after actions/checkout, enabling reliable git fetch / git push from safe_outputs handlers (e.g., create_pull_request, push_to_pull_request_branch) while keeping the agent job’s credential-stripping behavior unchanged.
Changes:
- Add a
CheckoutManagermode (keepCredentialsForPush) to emitpersist-credentials: trueand suppress the post-checkout credential cleanup step. - Enable that mode for the safe_outputs PR checkout path (
buildSharedPRCheckoutSteps) and update the associated unit test expectations. - Recompile workflows so safe_outputs checkouts in generated
.lock.ymlfiles reflectpersist-credentials: true.
Show a summary per file
| File | Description |
|---|---|
| pkg/workflow/compiler_safe_outputs_steps.go | Enables checkout manager “keep credentials” mode for safe_outputs PR operations. |
| pkg/workflow/compiler_safe_outputs_steps_test.go | Updates assertions to expect persist-credentials: true in safe_outputs checkout steps. |
| pkg/workflow/checkout_step_generator.go | Threads “keep credentials” mode into default/additional checkout YAML generation and suppresses cleanup step. |
| pkg/workflow/checkout_manager.go | Adds keepCredentialsForPush flag + setter on CheckoutManager. |
| .github/workflows/weekly-safe-outputs-spec-review.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/weekly-editors-health-check.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/weekly-blog-post-writer.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/update-astro.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/unbloat-docs.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/ubuntu-image-analyzer.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/tidy.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/test-create-pr-error-handling.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/technical-doc-writer.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/spec-extractor.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/spec-enforcer.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/smoke-update-cross-repo-pr.lock.yml | Recompiled lock: safe_outputs checkouts persist credentials; cross-repo git credential config env updated. |
| .github/workflows/smoke-project.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/smoke-multi-pr.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/smoke-create-cross-repo-pr.lock.yml | Recompiled lock: safe_outputs checkouts persist credentials; cross-repo git credential config env updated. |
| .github/workflows/slide-deck-maintainer.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/schema-feature-coverage.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/ruflo-backed-task.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/refiner.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/q.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/pr-sous-chef.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/necromancer.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/mergefest.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/linter-miner.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/layout-spec-maintainer.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/jsweep.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/instructions-janitor.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/hourly-ci-cleaner.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/go-logger.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/glossary-maintainer.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/github-mcp-tools-report.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/functional-pragmatist.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/dictation-prompt.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/developer-docs-consolidator.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/design-decision-gate.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/dependabot-worker.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/dependabot-repair.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/dead-code-remover.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/daily-workflow-updater.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/daily-safeoutputs-git-simulator.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/daily-safe-output-integrator.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/daily-rendering-scripts-verifier.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/daily-doc-updater.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/daily-doc-healer.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/daily-compiler-threat-spec-optimizer.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/daily-community-attribution.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/daily-caveman-optimizer.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/daily-astrostylelite-markdown-spellcheck.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/daily-architecture-diagram.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/daily-agent-of-the-day-blog-writer.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/craft.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/code-simplifier.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/code-scanning-fixer.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/cloclo.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/ci-coach.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/chaos-pr-bundle-fuzzer.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/changeset.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
| .github/workflows/avenger.lock.yml | Recompiled lock: safe_outputs checkout now persists credentials. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 62/62 changed files
- Comments generated: 2
Comment on lines
+35
to
+39
| // checked-out repositories (create_pull_request, push_to_pull_request_branch), so its | ||
| // checkouts must retain credentials (persist-credentials: true) instead of stripping | ||
| // them. This keeps the push-capable token on disk for the handlers; the trusted | ||
| // safe_outputs handler code (not the untrusted agent) is the only consumer. | ||
| checkoutMgr.SetKeepCredentialsForPush(true) |
Comment on lines
292
to
+296
| cleanCreds := override != nil && override.cleanCreds | ||
| if cleanCreds { | ||
| if cm.keepCredentialsForPush { | ||
| // safe_outputs job: retain credentials so later git fetch/push can authenticate | ||
| // using the push-capable token installed at checkout time. | ||
| sb.WriteString(" persist-credentials: true\n") |
github-actions Bot
added a commit
that referenced
this pull request
Jun 18, 2026
The previous commit (#40161) left a doc comment in buildSafeOutputsJobs unformatted, which fails CI's fmt-check (make lint). Reformat the comment block to satisfy gofmt. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 18, 2026
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.
Keep git credentials in safe_outputs job checkouts
Summary
The safe_outputs job's checkout steps previously cleared credentials after checkout (
persist-credentials: false). This brokecreate_pull_requestandpush_to_pull_request_branchhandlers that need a push-capable token on disk at execution time. This change wires akeepCredentialsForPushflag through the checkout pipeline so that the safe_outputs job retains credentials.Changes
pkg/workflow/checkout_manager.gokeepCredentialsForPush boolfield toCheckoutManager.SetKeepCredentialsForPush(bool)setter to expose the flag to callers.pkg/workflow/checkout_step_generator.goGenerateDefaultCheckoutStepandgenerateCheckoutStepLinesnow inspect thekeepCredentialsForPushflag.true: emitspersist-credentials: trueand skips the post-checkout credential-cleanup step.false(default): existing behaviour is unchanged.pkg/workflow/compiler_safe_outputs_steps.gocheckoutManager.SetKeepCredentialsForPush(true)when building checkout steps for the safe_outputs job, so the job's git token survives to the handler execution phase.pkg/workflow/compiler_safe_outputs_steps_test.goTestBuildSharedPRCheckoutStepsupdated to assertpersist-credentials: truein the generated YAML.checkNotContainsassertion to confirm the credential-cleanuppersist-credentials: falseline is no longer present.Risk assessment
CheckoutManagerAPIfalse)All other job types (non-safe_outputs) continue to strip credentials by default. No breaking changes.