fix(release): restore the SignPath composite action when cutting from an older ref

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
Neil
2026-07-30 21:55:09 -07:00
co-authored by Orca
parent a2d0e77143
commit be36795f59
2 changed files with 56 additions and 0 deletions
+21
View File
@@ -1015,6 +1015,27 @@ jobs:
with:
ref: refs/tags/${{ needs.cut.outputs.tag }}
# Why: `uses: ./…` resolves from the checked-out tag, not from the workflow
# ref, so cutting from an older/off-main ref whose tree predates a composite
# action would fail the step with "Can't find 'action.yml'". Restore the
# actions directory from the commit this workflow file itself came from.
- name: Restore composite actions from the workflow ref
if: matrix.platform == 'win'
shell: bash
env:
WORKFLOW_SHA: ${{ github.workflow_sha }}
run: |
set -euo pipefail
action_path=".github/actions/install-signpath-module/action.yml"
if [ -f "$action_path" ]; then
echo "Composite actions already present at the cut ref."
exit 0
fi
echo "Cut ref predates $action_path; restoring it from $WORKFLOW_SHA."
git fetch --no-tags --depth=1 origin "$WORKFLOW_SHA"
git checkout "$WORKFLOW_SHA" -- .github/actions
test -f "$action_path"
# pnpm must be on PATH before setup-node so setup-node can locate the store for caching.
- name: Setup pnpm
uses: pnpm/action-setup@v6
@@ -104,6 +104,41 @@ describe('Windows signing workflow contract', () => {
expect(installRun).toContain('throw "Unable to install the SignPath PowerShell module')
})
it('still installs SignPath when the cut ref predates the composite action', () => {
const parsedWorkflow = readWorkflow('.github/workflows/release-cut.yml')
const steps = parsedWorkflow.jobs.build.steps
const stepNames = steps.map((step) => step.name)
const checkoutIndex = stepNames.indexOf('Checkout')
const restoreIndex = stepNames.indexOf('Restore composite actions from the workflow ref')
const installIndex = stepNames.indexOf('Install SignPath PowerShell module')
// Why: the build job checks out the cut tag, which for a hotfix cut from an
// older ref can predate `.github/actions/install-signpath-module`; without
// this restore the `uses: ./…` step dies on a missing action.yml.
expect(restoreIndex).toBeGreaterThan(checkoutIndex)
expect(restoreIndex).toBeLessThan(installIndex)
const restoreStep = steps[restoreIndex]
const restoreRun = restoreStep.run
expect(restoreStep.env.WORKFLOW_SHA).toBe('${{ github.workflow_sha }}')
expect(restoreRun).toContain('.github/actions/install-signpath-module/action.yml')
expect(restoreRun).toContain('git fetch --no-tags --depth=1 origin "$WORKFLOW_SHA"')
expect(restoreRun).toContain('git checkout "$WORKFLOW_SHA" -- .github/actions')
// Why: restoring the action must not turn signing into a soft dependency —
// a missing module still has to fail the Windows job, and the CDN fallback
// still has to reject an unexpected payload.
expect(steps[installIndex]['continue-on-error']).toBeUndefined()
expect(restoreStep['continue-on-error']).toBeUndefined()
const installRun = readWorkflow('.github/actions/install-signpath-module/action.yml').runs
.steps[0].run
expect(installRun).toContain('$actualHash -ne $expectedHash.ToUpperInvariant()')
expect(installRun).toContain('throw "SHA-256 mismatch for $source')
})
it('shares one SignPath module install path between release and rehearsal', () => {
const rehearsalWorkflow = readWorkflow('.github/workflows/windows-signing-rehearsal.yml')
const stepNames = rehearsalWorkflow.jobs.rehearse.steps.map((step) => step.name)