-
Notifications
You must be signed in to change notification settings - Fork 296
Description
Summary
Observed on gh-aw main as of 2026-03-12, after manually patching the generated Checkout actions folder steps per #20658 and after restoring cross-repository activation auth. In a caller-hosted relay topology where <org>/<app-repo> calls <org>/<platform-repo>/.github/workflows/<platform-gateway>.lock.yml@<feature-branch>, the generated activation checkout for .github and .agents resolves the correct target repository but does not carry the callee workflow ref. As a result, activation checks out <org>/<platform-repo> on its default branch instead of <feature-branch>. The relay therefore starts with the right platform repository but the wrong platform branch.
This means a caller-hosted relay pinned to a feature branch cannot reliably test branch-local prompt content, workflow imports, or .github assets unless the generated lock file is manually patched to propagate a target_ref and use it in the activation checkout.
Important prerequisite note: live event-driven relay testing on 2026-03-12 also showed that activation target_repo resolution is still not reliable in this topology. In the failing caller run, the generated Resolve host repo for activation checkout step still produced the caller repository slug instead of the platform repository slug, so a manual target_repo override was also required to reach the branch-selection problem at all. That behavior appears to mean the fix line associated with #20567 is still incomplete or regressed for this relay shape. This draft remains focused on the separate target_ref gap once target_repo is corrected.
The downstream dispatch repository-selection bug is now tracked publicly in #20694. This draft stays focused on activation-stage repo/ref resolution before the workflow reaches safe outputs.
Root Cause
The activation checkout path is split across runtime JavaScript and Go compiler emitters, and it is still incomplete in two ways for caller-hosted event-driven relays:
- runtime host-repo resolution is still not reliable enough for
target_repoin this topology - the compiler/runtime combination does not emit or use
target_reffor the activation checkout
Current generated behavior is effectively:
- name: Resolve host repo for activation checkout
id: resolve-host-repo
uses: actions/github-script@<sha>
with:
script: |
await main();
# emits target_repo only
- name: Checkout .github and .agents folders
uses: actions/checkout@<sha>
with:
token: ${{ steps.activation-app-token.outputs.token }}
repository: ${{ steps.resolve-host-repo.outputs.target_repo }}
sparse-checkout: |
.github
.agentsWhat is missing:
target_repois still wrong in live event-driven relay runs unless manually overridden- no
target_refoutput from the host-repo resolution step - no
ref:on the.github/.agentscheckout
In a caller-hosted relay, the correct branch is not the caller repo branch and not the platform repo default branch. It is the ref encoded in the currently running platform workflow reference, i.e. the @<feature-branch> portion of GITHUB_WORKFLOW_REF.
And the correct repository is not the caller repository from the triggering event payload. It is the repository that owns the currently running reusable workflow.
Affected Code
Generated activation checkout in the caller-hosted gateway.
Broken behavior:
repository:is still wrong in live event-driven caller-hosted relays unless manually overriddenref:is omittedactions/checkouttherefore falls back to the target repo default branch
Result:
- relay definition points to
<platform-gateway>.lock.yml@<feature-branch> - activation still checks out
<org>/<platform-repo>:main - runtime-imported prompts and
.githubassets come from the wrong branch
Proposed Fix
Fix both activation checkout inputs explicitly, in the files that actually own this behavior:
- in
actions/setup/js/resolve_host_repo.cjs, resolve the platform workflow repository correctly astarget_repo, and also emittarget_ref - in the Go compiler code that emits the activation job checkout, add
target_refas an activation output and wire it into the.github/.agentscheckoutref:
The runtime helper currently exists already:
pkg/workflow/compiler_activation_job.goemits theResolve host repo for activation checkoutstep- that step calls
actions/setup/js/resolve_host_repo.cjs pkg/workflow/checkout_manager.gocurrently emits the activation.github/.agentscheckout withrepository:support but noref:support
So the minimal real fix shape is:
- name: Resolve host repo for activation checkout
id: resolve-host-repo
uses: actions/github-script@<sha>
with:
script: |
const { main } = require('/opt/gh-aw/actions/resolve_host_repo.cjs');
await main();
- name: Checkout .github and .agents folders
uses: actions/checkout@<sha>
with:
token: ${{ steps.activation-app-token.outputs.token }}
repository: ${{ steps.resolve-host-repo.outputs.target_repo }}
ref: ${{ steps.resolve-host-repo.outputs.target_ref }}
sparse-checkout: |
.github
.agentsIn other words, the issue is not “add inline YAML logic by hand”; it is:
- update the existing runtime helper in
actions/setup/js/resolve_host_repo.cjs - update the Go compiler emitters that expose outputs and render the activation checkout step
Concretely:
target_reposhould continue to be derived inactions/setup/js/resolve_host_repo.cjsfrom the reusable-workflow host repository, not from the caller event repositorytarget_refshould also be derived there fromGITHUB_WORKFLOW_REFwhen that workflow reference points at the reusable workflow being executedpkg/workflow/compiler_activation_job.goshould exposetarget_refthe same way it already exposestarget_repopkg/workflow/checkout_manager.goshould grow support for a checkoutref:so activation can checkout.github/.agentsfrom the resolved callee branch
Implementation Plan
-
Update the runtime helper in
actions/setup/js/resolve_host_repo.cjs
- Keep resolvingtarget_repofromGITHUB_WORKFLOW_REF
- Fix any remaining event-driven relay mismatch that still returns the caller repo in live runs
- Also emittarget_ref
- Derivetarget_reffromGITHUB_WORKFLOW_REFwhen available
- Fall back toGITHUB_REFonly when no workflow ref is available -
Update the Go compiler emitters
- Inpkg/workflow/compiler_activation_job.go, exposetarget_refas an activation output in the same waytarget_repois exposed today
- UpdategenerateResolveHostRepoStep()to continue calling the shared runtime helper rather than inlining separate logic -
Update checkout rendering
- Inpkg/workflow/checkout_manager.go, extendGenerateGitHubFolderCheckoutStep(...)so it can emit aref:in addition torepository:
- Ensurerepository: ${{ steps.resolve-host-repo.outputs.target_repo }}resolves to the reusable-workflow host repo in caller-hosted relays
- Addref: ${{ steps.resolve-host-repo.outputs.target_ref }}to the activation.github/.agentscheckout step -
Add tests
- Inactions/setup/js/resolve_host_repo.test.cjs, add coverage for the failing event-driven relay shape and fortarget_refoutput
- Inpkg/workflow/compiler_activation_job_test.go, assert activation outputs include bothtarget_repoandtarget_ref
- Inpkg/workflow/compiler_activation_job_test.goorpkg/workflow/activation_checkout_test.go, assert the activation checkout emits bothrepository:andref:when aworkflow_calltrigger is present
- Compile a caller-hosted relay fixture pinned to@feature-branch
- Assert branch-local.githubassets are used during activation -
Validate
- event-driven cross-repo relay on default branch: confirm activation checks out the platform repo, not the caller repo
- event-driven cross-repo relay pinned to a non-default platform branch
- confirm activation loads.githuband.agentsfrom that branch
Reproduction
- Use gh-aw
mainas of 2026-03-12. - Create
<org>/<platform-repo>/.github/workflows/<platform-gateway>.lock.ymlon a non-default branch such as<feature-branch>. - In
<org>/<app-repo>, create a caller-hosted relay that calls<platform-gateway>.lock.yml@<feature-branch>. - Trigger the relay.
- Inspect the activation checkout of
.githuband.agents. - Observe one or both of the following in current builds:
- the checkout resolves the caller repo instead of
<org>/<platform-repo> - after manually overriding
target_repo, the checkout still uses the repo default branch instead of<feature-branch>
Expected:
- activation checkout uses
<org>/<platform-repo>@<feature-branch>
Observed:
- activation checkout may first resolve
<org>/<app-repo>instead of<org>/<platform-repo> - activation checkout uses
<org>/<platform-repo>@main
Private run URLs omitted.
Relationship to #20658, #20508, and #20694
This issue is related to both, but not the same as either.
- Bug:
Checkout actions folderemitted withoutrepository:orref:—Setup Scriptsfails in cross-repo relay #20658 is about the earlierCheckout actions folderregression whererepository:andref:are missing entirely for thegithub/gh-awaction checkout. That issue preventsSetup Scriptsfrom running at all. - Activation job missing
ref:in cross-repo checkout for workflow_call triggers #20508 is related because both bugs are about preserving the correct ref in cross-repo workflows. - Cross-repo activation checkout still broken for event-driven relay workflows after #20301 #20567 is also related. Live testing on 2026-03-12 still required a manual activation
target_repooverride in an event-driven caller-hosted relay because the generated host-repo resolution returned the caller repository instead of the platform repository. That means the earlier activation-repo fix does not appear complete for this topology, and this draft now includes the concrete follow-up fix shape for that prerequisite as well. - Bug:
dispatch_workflowignorestarget-repoand dispatches tocontext.repoin cross-repo relays #20694 tracks a later-stage bug indispatch_workflowrepository selection. That bug occurs after activation succeeds. This draft is about the activation-stage repo/ref resolution that must be correct before the workflow can even reach that later dispatch step. - This issue starts after the
Setup Scriptsstage is fixed and after cross-repository activation auth is working: activation can reach the platform repo, but it still checks out the wrong platform branch because notarget_refis propagated.
In practice, caller-hosted branch testing needs all three layers to be correct:
Checkout actions foldermust checkoutgithub/gh-awcorrectly (Bug:Checkout actions folderemitted withoutrepository:orref:—Setup Scriptsfails in cross-repo relay #20658)- activation must resolve the platform repo correctly (
target_repo) — this still appears incomplete in the fix line associated with Cross-repo activation checkout still broken for event-driven relay workflows after #20301 #20567 - activation must checkout the platform repo with cross-repo auth
- activation must preserve the callee workflow branch (
target_ref)