Skip to content

Bundle-based push path skips temporary ID substitution in file contents #32834

@wtgodbe

Description

@wtgodbe

Summary

When the safe-outputs handler uses the bundle-based push path (introduced in CLI v0.72.1 / AWF v0.25.41), #aw_ temporary ID references in committed file contents are not resolved to real issue/PR numbers. The patch-based path correctly performs this substitution.

Reproduction

Two workflow runs of the same workflow (dotnet/aspnetcore daily test quarantine) demonstrate the regression:

✅ Working (May 15) ❌ Broken (May 17)
Run 25913878755 25988389764
CLI version v0.71.5 v0.72.1
AWF version v0.25.40 v0.25.41
Change delivery .patch file .bundle file
Substitution log Resolved temporary ID references in patch content (missing — never logged)
Result PR #66694 — real issue number in code PR #66711 — literal #aw_redirect1 in code

Working run (patch path)

safe_outputs  Resolved temporary ID references in patch content
safe_outputs  Applying patch...
safe_outputs  +    [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/66693")]

Broken run (bundle path)

safe_outputs  Bundle file path: /tmp/gh-aw/aw-quarantine-tests-2026-05-17.bundle
safe_outputs  Applying changes from bundle: /tmp/gh-aw/aw-quarantine-tests-2026-05-17.bundle
safe_outputs  pushSignedCommits: replaying 1 commit(s) via GraphQL createCommitOnBranch

No Resolved temporary ID references in patch content log line. The committed code contains literal [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/#aw_passkeys1")].

Root cause

The patch-based path has a substitution step that rewrites #aw_<temporary_id> references in the patch content before applying it. The bundle-based path (which fetches a git bundle, checks out the branch, and replays commits via pushSignedCommits / GraphQL createCommitOnBranch) skips this substitution entirely — it pushes the committed file contents as-is.

The bundle path appears to have been introduced or became the default path with the changes in CLI v0.72.0/v0.72.1 and AWF v0.25.41. The refactor: decouple safe-outputs checkout from event trigger context (#30071) PR may be related, as it changed the safe-outputs checkout flow and recompiled all lock files.

Suggested fix

Before pushSignedCommits replays commits from a bundle, apply the same temporary ID substitution that the patch path uses. Specifically:

  1. After fetching/checking out the bundle branch but before calling pushSignedCommits, iterate over the files in each commit
  2. For each file, check if its content contains any registered #aw_<id> references
  3. If found, rewrite the file content with the resolved values (e.g., #aw_passkeys166708), amend the commit, then proceed with pushSignedCommits

Alternatively, the substitution could happen inside pushSignedCommits itself, right before the createCommitOnBranch GraphQL mutation — rewrite the file addition contents in-memory before sending them to the API.

Impact

Any workflow that uses create_issue with temporary_id and references #aw_<id> in committed source code will produce PRs with unresolved placeholder strings when the bundle path is used. PR body and title substitution still works correctly — only the committed file contents are affected.

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