From 3166d95205d2b211c514484b0de72eceb8fb4373 Mon Sep 17 00:00:00 2001 From: Hector Martinez Date: Fri, 26 Jun 2026 14:01:37 +0200 Subject: [PATCH] refactor(workflows): replace fullsend_ai_ref by job.workflow_sha Co-Authored-By: Claude Opus 4.6 Signed-off-by: Hector Martinez --- .github/workflows/reusable-code.yml | 6 +++--- .github/workflows/reusable-dispatch.yml | 10 ++-------- .github/workflows/reusable-fix.yml | 6 +++--- .github/workflows/reusable-prioritize.yml | 6 +++--- .github/workflows/reusable-retro.yml | 6 +++--- .github/workflows/reusable-review.yml | 6 +++--- .github/workflows/reusable-triage.yml | 6 +++--- .pre-commit-config.yaml | 2 ++ docs/ADRs/0035-layered-content-resolution.md | 4 +++- docs/guides/dev/testing-workflows.md | 5 +---- internal/layers/workflows_test.go | 2 +- .../scaffold/fullsend-repo/.github/workflows/code.yml | 1 - .../scaffold/fullsend-repo/.github/workflows/fix.yml | 1 - .../fullsend-repo/.github/workflows/prioritize.yml | 1 - .../scaffold/fullsend-repo/.github/workflows/retro.yml | 1 - .../fullsend-repo/.github/workflows/review.yml | 1 - .../fullsend-repo/.github/workflows/triage.yml | 1 - .../fullsend-repo/templates/shim-per-repo.yaml | 1 - internal/scaffold/render_test.go | 6 +++--- 19 files changed, 30 insertions(+), 42 deletions(-) diff --git a/.github/workflows/reusable-code.yml b/.github/workflows/reusable-code.yml index 628e59062b..372e6e9ae0 100644 --- a/.github/workflows/reusable-code.yml +++ b/.github/workflows/reusable-code.yml @@ -32,7 +32,7 @@ on: type: string default: "per-org" fullsend_ai_ref: - description: Ref of fullsend-ai/fullsend to load actions from. Must match the ref used in the `uses:` line that calls this workflow. + description: "Deprecated: upstream defaults now use job.workflow_sha. Kept for per-org caller compatibility." type: string required: false default: v0 @@ -72,8 +72,8 @@ jobs: if: hashFiles('.defaults/action.yml', '.fullsend/.defaults/action.yml') == '' uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: - repository: fullsend-ai/fullsend - ref: ${{ inputs.fullsend_ai_ref }} + repository: ${{ job.workflow_repository }} + ref: ${{ job.workflow_sha }} path: .defaults fetch-depth: 1 sparse-checkout: | diff --git a/.github/workflows/reusable-dispatch.yml b/.github/workflows/reusable-dispatch.yml index 4195d1d5e3..4c059bcd2b 100644 --- a/.github/workflows/reusable-dispatch.yml +++ b/.github/workflows/reusable-dispatch.yml @@ -46,7 +46,7 @@ on: type: string default: "latest" fullsend_ai_ref: - description: Ref of fullsend-ai/fullsend to load actions from. Must match the ref used in the `uses:` line that calls this workflow. + description: "Deprecated: stage workflows now use job.workflow_sha. Kept so existing shims that pass this input do not break." type: string required: false default: v0 @@ -427,7 +427,7 @@ jobs: group: fullsend-triage-${{ github.repository }}-${{ github.event.issue.number || github.event.pull_request.number }} cancel-in-progress: true # @v0 is hardcoded — GHA does not support expressions in uses:. - # fullsend_ai_ref controls the ref for composite actions inside stage workflows. + # Stage workflows use job.workflow_sha to self-checkout upstream defaults. uses: fullsend-ai/fullsend/.github/workflows/reusable-triage.yml@v0 with: event_type: ${{ github.event_name }} @@ -437,7 +437,6 @@ jobs: mint_url: ${{ inputs.mint_url }} gcp_region: ${{ inputs.gcp_region }} fullsend_version: ${{ inputs.fullsend_version }} - fullsend_ai_ref: ${{ inputs.fullsend_ai_ref }} runner_image: ${{ inputs.runner_image }} secrets: FULLSEND_GCP_WIF_PROVIDER: ${{ secrets.FULLSEND_GCP_WIF_PROVIDER }} @@ -459,7 +458,6 @@ jobs: mint_url: ${{ inputs.mint_url }} gcp_region: ${{ inputs.gcp_region }} fullsend_version: ${{ inputs.fullsend_version }} - fullsend_ai_ref: ${{ inputs.fullsend_ai_ref }} runner_image: ${{ inputs.runner_image }} secrets: FULLSEND_GCP_WIF_PROVIDER: ${{ secrets.FULLSEND_GCP_WIF_PROVIDER }} @@ -481,7 +479,6 @@ jobs: mint_url: ${{ inputs.mint_url }} gcp_region: ${{ inputs.gcp_region }} fullsend_version: ${{ inputs.fullsend_version }} - fullsend_ai_ref: ${{ inputs.fullsend_ai_ref }} runner_image: ${{ inputs.runner_image }} secrets: FULLSEND_GCP_WIF_PROVIDER: ${{ secrets.FULLSEND_GCP_WIF_PROVIDER }} @@ -504,7 +501,6 @@ jobs: mint_url: ${{ inputs.mint_url }} gcp_region: ${{ inputs.gcp_region }} fullsend_version: ${{ inputs.fullsend_version }} - fullsend_ai_ref: ${{ inputs.fullsend_ai_ref }} runner_image: ${{ inputs.runner_image }} secrets: FULLSEND_GCP_WIF_PROVIDER: ${{ secrets.FULLSEND_GCP_WIF_PROVIDER }} @@ -526,7 +522,6 @@ jobs: mint_url: ${{ inputs.mint_url }} gcp_region: ${{ inputs.gcp_region }} fullsend_version: ${{ inputs.fullsend_version }} - fullsend_ai_ref: ${{ inputs.fullsend_ai_ref }} runner_image: ${{ inputs.runner_image }} secrets: FULLSEND_GCP_WIF_PROVIDER: ${{ secrets.FULLSEND_GCP_WIF_PROVIDER }} @@ -549,7 +544,6 @@ jobs: gcp_region: ${{ inputs.gcp_region }} project_number: ${{ inputs.project_number }} fullsend_version: ${{ inputs.fullsend_version }} - fullsend_ai_ref: ${{ inputs.fullsend_ai_ref }} runner_image: ${{ inputs.runner_image }} secrets: FULLSEND_GCP_WIF_PROVIDER: ${{ secrets.FULLSEND_GCP_WIF_PROVIDER }} diff --git a/.github/workflows/reusable-fix.yml b/.github/workflows/reusable-fix.yml index 298986b9b5..6fd47a2d8e 100644 --- a/.github/workflows/reusable-fix.yml +++ b/.github/workflows/reusable-fix.yml @@ -44,7 +44,7 @@ on: type: string default: "per-org" fullsend_ai_ref: - description: Ref of fullsend-ai/fullsend to load actions from. Must match the ref used in the `uses:` line that calls this workflow. + description: "Deprecated: upstream defaults now use job.workflow_sha. Kept for per-org caller compatibility." type: string required: false default: v0 @@ -88,8 +88,8 @@ jobs: if: hashFiles('.defaults/action.yml', '.fullsend/.defaults/action.yml') == '' uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: - repository: fullsend-ai/fullsend - ref: ${{ inputs.fullsend_ai_ref }} + repository: ${{ job.workflow_repository }} + ref: ${{ job.workflow_sha }} path: .defaults fetch-depth: 1 sparse-checkout: | diff --git a/.github/workflows/reusable-prioritize.yml b/.github/workflows/reusable-prioritize.yml index 18a6cf7648..d12dcc08c6 100644 --- a/.github/workflows/reusable-prioritize.yml +++ b/.github/workflows/reusable-prioritize.yml @@ -36,7 +36,7 @@ on: type: string default: "per-org" fullsend_ai_ref: - description: Ref of fullsend-ai/fullsend to load actions from. Must match the ref used in the `uses:` line that calls this workflow. + description: "Deprecated: upstream defaults now use job.workflow_sha. Kept for per-org caller compatibility." type: string required: false default: v0 @@ -73,8 +73,8 @@ jobs: if: hashFiles('.defaults/action.yml', '.fullsend/.defaults/action.yml') == '' uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: - repository: fullsend-ai/fullsend - ref: ${{ inputs.fullsend_ai_ref }} + repository: ${{ job.workflow_repository }} + ref: ${{ job.workflow_sha }} path: .defaults fetch-depth: 1 sparse-checkout: | diff --git a/.github/workflows/reusable-retro.yml b/.github/workflows/reusable-retro.yml index e576256d78..c307b290f8 100644 --- a/.github/workflows/reusable-retro.yml +++ b/.github/workflows/reusable-retro.yml @@ -32,7 +32,7 @@ on: type: string default: "per-org" fullsend_ai_ref: - description: Ref of fullsend-ai/fullsend to load actions from. Must match the ref used in the `uses:` line that calls this workflow. + description: "Deprecated: upstream defaults now use job.workflow_sha. Kept for per-org caller compatibility." type: string required: false default: v0 @@ -69,8 +69,8 @@ jobs: if: hashFiles('.defaults/action.yml', '.fullsend/.defaults/action.yml') == '' uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: - repository: fullsend-ai/fullsend - ref: ${{ inputs.fullsend_ai_ref }} + repository: ${{ job.workflow_repository }} + ref: ${{ job.workflow_sha }} path: .defaults fetch-depth: 1 sparse-checkout: | diff --git a/.github/workflows/reusable-review.yml b/.github/workflows/reusable-review.yml index 14f77099a1..3cb8bee9d7 100644 --- a/.github/workflows/reusable-review.yml +++ b/.github/workflows/reusable-review.yml @@ -32,7 +32,7 @@ on: type: string default: "per-org" fullsend_ai_ref: - description: Ref of fullsend-ai/fullsend to load actions from. Must match the ref used in the `uses:` line that calls this workflow. + description: "Deprecated: upstream defaults now use job.workflow_sha. Kept for per-org caller compatibility." type: string required: false default: v0 @@ -70,8 +70,8 @@ jobs: if: hashFiles('.defaults/action.yml', '.fullsend/.defaults/action.yml') == '' uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: - repository: fullsend-ai/fullsend - ref: ${{ inputs.fullsend_ai_ref }} + repository: ${{ job.workflow_repository }} + ref: ${{ job.workflow_sha }} path: .defaults fetch-depth: 1 sparse-checkout: | diff --git a/.github/workflows/reusable-triage.yml b/.github/workflows/reusable-triage.yml index 4707609412..23ea79f241 100644 --- a/.github/workflows/reusable-triage.yml +++ b/.github/workflows/reusable-triage.yml @@ -33,7 +33,7 @@ on: type: string default: "per-org" fullsend_ai_ref: - description: Ref of fullsend-ai/fullsend to load actions from. Must match the ref used in the `uses:` line that calls this workflow. + description: "Deprecated: upstream defaults now use job.workflow_sha. Kept for per-org caller compatibility." type: string required: false default: v0 @@ -70,8 +70,8 @@ jobs: if: hashFiles('.defaults/action.yml', '.fullsend/.defaults/action.yml') == '' uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: - repository: fullsend-ai/fullsend - ref: ${{ inputs.fullsend_ai_ref }} + repository: ${{ job.workflow_repository }} + ref: ${{ job.workflow_sha }} path: .defaults fetch-depth: 1 sparse-checkout: | diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6d184c911a..82e95f2391 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -88,6 +88,8 @@ repos: - -ignore - property "workflow_repository" is not defined - -ignore + - property "workflow_sha" is not defined + - -ignore - SC2016 - -ignore - '__REUSABLE_(WORKFLOW|DISPATCH)__' diff --git a/docs/ADRs/0035-layered-content-resolution.md b/docs/ADRs/0035-layered-content-resolution.md index ba86c0a181..e3ea761bfc 100644 --- a/docs/ADRs/0035-layered-content-resolution.md +++ b/docs/ADRs/0035-layered-content-resolution.md @@ -61,7 +61,9 @@ they are populated at runtime from upstream. "Prepare workspace" step that checks out upstream defaults from `fullsend-ai/fullsend` at the ref supplied via `fullsend_ai_ref` (PR #1278 replaced the earlier checkout at `@v0` with a checkout at a -caller-controlled ref), copies them into the main dirs (`agents/`, `skills/`, +caller-controlled ref; since superseded by `job.workflow_sha` which +eliminates the need for the caller to pass a ref — see PR #2689), +copies them into the main dirs (`agents/`, `skills/`, etc.), then copies customizations on top so override files replace upstream defaults. When `--vendor` has committed upstream mirror content under `.defaults/`, the sparse checkout is skipped (see diff --git a/docs/guides/dev/testing-workflows.md b/docs/guides/dev/testing-workflows.md index d274c627c6..973ac826e4 100644 --- a/docs/guides/dev/testing-workflows.md +++ b/docs/guides/dev/testing-workflows.md @@ -9,13 +9,12 @@ There are independent version reference inputs that control different parts of t | Input | Controls | Where set | |-------|----------|-----------| | `@` on `uses:` | Which reusable workflow YAML runs | The `uses:` line in the caller workflow | -| `fullsend_ai_ref` | Which ref composite actions (`action.yml`) and defaults are loaded from at runtime | Passed as a `with:` input | | `fullsend_version` | Which fullsend CLI binary is installed | Passed as a `with:` input | When no release exists for `fullsend_version`, `action.yml` falls back to cloning and building from source at that ref (see the `install-method=source` path). -If `uses:`, `fullsend_ai_ref` and `fullsend_version` diverge, the workflows, agents and harnesses, and +If `uses:` and `fullsend_version` diverge, the workflows/agents and CLI diverge, potentially causing mismatch in behavior and failures. ## Vendored installs (recommended for PR testing) @@ -65,7 +64,6 @@ jobs: uses: fullsend-ai/fullsend/.github/workflows/reusable-dispatch.yml@ with: # [...] - fullsend_ai_ref: fullsend_version: # [...] ``` @@ -86,7 +84,6 @@ jobs: uses: fullsend-ai/fullsend/.github/workflows/reusable-triage.yml@ with: # [...] - fullsend_ai_ref: fullsend_version: # [...] ``` diff --git a/internal/layers/workflows_test.go b/internal/layers/workflows_test.go index 0a989ca43e..4df51e9017 100644 --- a/internal/layers/workflows_test.go +++ b/internal/layers/workflows_test.go @@ -259,7 +259,7 @@ func TestWorkflowsLayer_Install_PinnedSHA(t *testing.T) { require.NotEmpty(t, triageContent, "triage.yml should have been written") assert.Contains(t, triageContent, "@abc123def456abc123def456abc123def456abcd") assert.Contains(t, triageContent, "# v0.19.0") - assert.Contains(t, triageContent, "fullsend_ai_ref: abc123def456abc123def456abc123def456abcd # v0.19.0") + assert.NotContains(t, triageContent, "fullsend_ai_ref:") assert.NotContains(t, triageContent, "@v0") } diff --git a/internal/scaffold/fullsend-repo/.github/workflows/code.yml b/internal/scaffold/fullsend-repo/.github/workflows/code.yml index f05bf05a19..3bf7144698 100644 --- a/internal/scaffold/fullsend-repo/.github/workflows/code.yml +++ b/internal/scaffold/fullsend-repo/.github/workflows/code.yml @@ -37,7 +37,6 @@ jobs: mint_url: ${{ vars.FULLSEND_MINT_URL }} gcp_region: ${{ vars.FULLSEND_GCP_REGION }} install_mode: per-org - fullsend_ai_ref: __FULLSEND_AI_REF__ runner_image: __GH_RUNNER__ secrets: FULLSEND_GCP_WIF_PROVIDER: ${{ secrets.FULLSEND_GCP_WIF_PROVIDER }} diff --git a/internal/scaffold/fullsend-repo/.github/workflows/fix.yml b/internal/scaffold/fullsend-repo/.github/workflows/fix.yml index b230c16f5e..56c50840dc 100644 --- a/internal/scaffold/fullsend-repo/.github/workflows/fix.yml +++ b/internal/scaffold/fullsend-repo/.github/workflows/fix.yml @@ -61,7 +61,6 @@ jobs: mint_url: ${{ vars.FULLSEND_MINT_URL }} gcp_region: ${{ vars.FULLSEND_GCP_REGION }} install_mode: per-org - fullsend_ai_ref: __FULLSEND_AI_REF__ runner_image: __GH_RUNNER__ secrets: FULLSEND_GCP_WIF_PROVIDER: ${{ secrets.FULLSEND_GCP_WIF_PROVIDER }} diff --git a/internal/scaffold/fullsend-repo/.github/workflows/prioritize.yml b/internal/scaffold/fullsend-repo/.github/workflows/prioritize.yml index 4472a3ce37..6aa1b5305b 100644 --- a/internal/scaffold/fullsend-repo/.github/workflows/prioritize.yml +++ b/internal/scaffold/fullsend-repo/.github/workflows/prioritize.yml @@ -36,7 +36,6 @@ jobs: gcp_region: ${{ vars.FULLSEND_GCP_REGION }} project_number: ${{ vars.FULLSEND_PROJECT_NUMBER }} install_mode: per-org - fullsend_ai_ref: __FULLSEND_AI_REF__ runner_image: __GH_RUNNER__ secrets: FULLSEND_GCP_WIF_PROVIDER: ${{ secrets.FULLSEND_GCP_WIF_PROVIDER }} diff --git a/internal/scaffold/fullsend-repo/.github/workflows/retro.yml b/internal/scaffold/fullsend-repo/.github/workflows/retro.yml index a58c77c4a8..d9b38f7b57 100644 --- a/internal/scaffold/fullsend-repo/.github/workflows/retro.yml +++ b/internal/scaffold/fullsend-repo/.github/workflows/retro.yml @@ -42,7 +42,6 @@ jobs: mint_url: ${{ vars.FULLSEND_MINT_URL }} gcp_region: ${{ vars.FULLSEND_GCP_REGION }} install_mode: per-org - fullsend_ai_ref: __FULLSEND_AI_REF__ runner_image: __GH_RUNNER__ secrets: FULLSEND_GCP_WIF_PROVIDER: ${{ secrets.FULLSEND_GCP_WIF_PROVIDER }} diff --git a/internal/scaffold/fullsend-repo/.github/workflows/review.yml b/internal/scaffold/fullsend-repo/.github/workflows/review.yml index afd7d6052c..8883fc82be 100644 --- a/internal/scaffold/fullsend-repo/.github/workflows/review.yml +++ b/internal/scaffold/fullsend-repo/.github/workflows/review.yml @@ -36,7 +36,6 @@ jobs: mint_url: ${{ vars.FULLSEND_MINT_URL }} gcp_region: ${{ vars.FULLSEND_GCP_REGION }} install_mode: per-org - fullsend_ai_ref: __FULLSEND_AI_REF__ runner_image: __GH_RUNNER__ secrets: FULLSEND_GCP_WIF_PROVIDER: ${{ secrets.FULLSEND_GCP_WIF_PROVIDER }} diff --git a/internal/scaffold/fullsend-repo/.github/workflows/triage.yml b/internal/scaffold/fullsend-repo/.github/workflows/triage.yml index 3c68ae049b..2c102f6af0 100644 --- a/internal/scaffold/fullsend-repo/.github/workflows/triage.yml +++ b/internal/scaffold/fullsend-repo/.github/workflows/triage.yml @@ -35,7 +35,6 @@ jobs: mint_url: ${{ vars.FULLSEND_MINT_URL }} gcp_region: ${{ vars.FULLSEND_GCP_REGION }} install_mode: per-org - fullsend_ai_ref: __FULLSEND_AI_REF__ runner_image: __GH_RUNNER__ secrets: FULLSEND_GCP_WIF_PROVIDER: ${{ secrets.FULLSEND_GCP_WIF_PROVIDER }} diff --git a/internal/scaffold/fullsend-repo/templates/shim-per-repo.yaml b/internal/scaffold/fullsend-repo/templates/shim-per-repo.yaml index f3a2546d58..3e5f9035c9 100644 --- a/internal/scaffold/fullsend-repo/templates/shim-per-repo.yaml +++ b/internal/scaffold/fullsend-repo/templates/shim-per-repo.yaml @@ -48,7 +48,6 @@ jobs: install_mode: per-repo mint_url: ${{ vars.FULLSEND_MINT_URL }} gcp_region: ${{ vars.FULLSEND_GCP_REGION }} - fullsend_ai_ref: __FULLSEND_AI_REF__ runner_image: __GH_RUNNER__ secrets: FULLSEND_GCP_WIF_PROVIDER: ${{ secrets.FULLSEND_GCP_WIF_PROVIDER }} diff --git a/internal/scaffold/render_test.go b/internal/scaffold/render_test.go index b4c0d1d098..1cdb67bdfb 100644 --- a/internal/scaffold/render_test.go +++ b/internal/scaffold/render_test.go @@ -157,7 +157,7 @@ func TestRenderThinCallerPinnedSHA(t *testing.T) { out := string(rendered) assert.Contains(t, out, "uses: fullsend-ai/fullsend/.github/workflows/reusable-triage.yml@abc123def456") assert.Contains(t, out, "# v0.19.0") - assert.Contains(t, out, "fullsend_ai_ref: abc123def456 # v0.19.0") + assert.NotContains(t, out, "fullsend_ai_ref:") assertFreeOfRenderPlaceholders(t, out) } @@ -174,7 +174,7 @@ func TestRenderPerRepoShimPinnedSHA(t *testing.T) { out := string(rendered) assert.Contains(t, out, "uses: fullsend-ai/fullsend/.github/workflows/reusable-dispatch.yml@abc123def456") assert.Contains(t, out, "# v0.19.0") - assert.Contains(t, out, "fullsend_ai_ref: abc123def456 # v0.19.0") + assert.NotContains(t, out, "fullsend_ai_ref:") assertFreeOfRenderPlaceholders(t, out) } @@ -225,5 +225,5 @@ func TestRenderFallbackToDefaultRef(t *testing.T) { require.NoError(t, err) out := string(rendered) assert.Contains(t, out, "@v0") - assert.Contains(t, out, "fullsend_ai_ref: v0") + assert.NotContains(t, out, "fullsend_ai_ref:") }