diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8399717..615a2fd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -359,7 +359,7 @@ jobs: compatibility: name: Release compatibility (${{ matrix.target }}) - if: needs.resolve.outputs.mode == 'publish' || needs.resolve.outputs.mode == 'repair' + if: needs.resolve.outputs.mode == 'publish' needs: - resolve - candidate @@ -406,7 +406,13 @@ jobs: package: name: Prove release candidate - if: needs.resolve.outputs.mode == 'publish' || needs.resolve.outputs.mode == 'repair' + if: >- + always() && + needs.resolve.result == 'success' && + needs.candidate.result == 'success' && + (needs.resolve.outputs.mode == 'publish' || needs.resolve.outputs.mode == 'repair') && + (needs.compatibility.result == 'success' || + (needs.resolve.outputs.mode == 'repair' && needs.compatibility.result == 'skipped')) needs: - resolve - candidate diff --git a/scripts/release-validate.test.ts b/scripts/release-validate.test.ts index 24f8454..c1ca255 100644 --- a/scripts/release-validate.test.ts +++ b/scripts/release-validate.test.ts @@ -257,6 +257,10 @@ test("release validation rejects a duplicate changelog heading", () => { test("release workflow is pinned and publishes proven assets after validation", () => { const workflow = readFileSync(join(root, ".github", "workflows", "release.yml"), "utf8") + const parsedWorkflow = Bun.YAML.parse(workflow) as { + jobs: Record + } + const normalizePredicate = (predicate: string | undefined) => predicate?.replace(/\s+/g, " ") const finalReleaseJob = workflow.slice(workflow.indexOf(" release:\n")) const compareStepStart = finalReleaseJob.indexOf(" - name: Compare release assets before mutation\n") const uploadStepStart = finalReleaseJob.indexOf(" - name: Add or replace admitted release assets\n") @@ -339,6 +343,12 @@ test("release workflow is pinned and publishes proven assets after validation", ) expect(candidateJob).toContain(" permissions:\n actions: read\n contents: read\n") expect(candidateJob).toContain("persist-credentials: false") + expect(normalizePredicate(parsedWorkflow.jobs.compatibility.if)).toBe( + "needs.resolve.outputs.mode == 'publish'", + ) + expect(normalizePredicate(parsedWorkflow.jobs.package.if)).toBe( + "always() && needs.resolve.result == 'success' && needs.candidate.result == 'success' && (needs.resolve.outputs.mode == 'publish' || needs.resolve.outputs.mode == 'repair') && (needs.compatibility.result == 'success' || (needs.resolve.outputs.mode == 'repair' && needs.compatibility.result == 'skipped'))", + ) expect(workflow.match(/--dir "\$RUNNER_TEMP\/platform-candidate"/g)).toHaveLength(2) expect(maintainJob).toContain("persist-credentials: false") expect(maintainJob).toContain("group: release-maintenance")