-
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 does not carry the callee workflow ref. As a result, activation checks out <org>/<platform-repo> on its default branch instead of <feature-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 an activation target_repo mismatch in the observed build. Source inspection suggests current gh-aw main already intends to handle that in resolve_host_repo.cjs, so this draft does not claim that repo-resolution path is definitely a separate source-level bug. It stays focused on the distinct target_ref gap, which source inspection does support directly.
The downstream dispatch repository-selection bug is now tracked publicly in #20694. The downstream dispatch branch/ref bug is now tracked publicly in #20696. 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.
Source inspection of gh-aw main shows:
actions/setup/js/resolve_host_repo.cjsalready exists and is intended to derivetarget_repofromGITHUB_WORKFLOW_REFpkg/workflow/compiler_activation_job.goalready emits aresolve-host-repostep and exposestarget_repopkg/workflow/checkout_manager.gorenders the activation.github/.agentscheckout withrepository:support but noref:support
So the remaining source-level problem is:
- 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:
- 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.
The correct repository is the repository that owns the currently running reusable workflow. Current source inspection suggests gh-aw already intends to derive that part via resolve_host_repo.cjs.
Affected Code
Generated activation checkout in the caller-hosted gateway.
Broken behavior:
ref:is omittedactions/checkouttherefore falls back to the target repo default branch
Result:
- relay definition points to
<platform-gateway>.lock.yml@<feature-branch> - activation checks out
<org>/<platform-repo>:main - runtime-imported prompts and
.githubassets come from the wrong branch
Proposed Fix
This is a real source-level gap and should be fixed explicitly:
- in
actions/setup/js/resolve_host_repo.cjs, 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
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_refshould be derived inactions/setup/js/resolve_host_repo.cjsfromGITHUB_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 existing
target_repobehavior unchanged - Also emit
target_ref - Derive
target_reffromGITHUB_WORKFLOW_REFwhen available - Fall back to
GITHUB_REFonly when no workflow ref is available
- Keep existing
-
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
- In
actions/setup/js/resolve_host_repo.test.cjs, add coverage fortarget_refoutput - In
pkg/workflow/compiler_activation_job_test.go, assert activation outputs include bothtarget_repoandtarget_ref - In
pkg/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
- In
-
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 that after the platform repo is selected, the checkout still uses the repo default branch instead of
<feature-branch>.
Expected:
- activation checkout uses
<org>/<platform-repo>@<feature-branch>
Observed:
- activation checkout uses
<org>/<platform-repo>@main
Private run URLs omitted.
Relationship to #20658, #20508, #20694, and #20696
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 related background. A live run on 2026-03-12 showed an observed
target_repomismatch in one event-driven caller-hosted relay, but source inspection of currentmainsuggests gh-aw already intends to handle repo resolution inresolve_host_repo.cjs. This draft therefore does not treat that as the main source-level claim. - 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. - Bug: Activation checkout resolves wrong repo/ref in caller-hosted event-driven relays #20696 tracks the later-stage downstream dispatch branch/ref bug after the dispatch destination repo is already correct. This draft is earlier in the flow: activation must first load the correct platform repo and branch before the workflow can reach safe outputs at all.
- 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) - activation must checkout the platform repo with cross-repo auth
- activation must preserve the callee workflow branch (
target_ref)