Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -379,15 +379,23 @@ jobs:
permissions:
contents: write
steps:
- name: Check out verified release source
- name: Check out trusted publication-control source
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ github.sha }}
persist-credentials: false

- name: Check out verified release content
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ needs.verify.outputs.source_sha }}
path: .release-source
fetch-depth: 0
persist-credentials: false

- name: Confirm the release tag still resolves to the verified source
shell: bash
working-directory: .release-source
env:
SOURCE_SHA: ${{ needs.verify.outputs.source_sha }}
run: |
Expand Down Expand Up @@ -444,7 +452,7 @@ jobs:
tag_name: ${{ env.RELEASE_TAG }}
generate_release_notes: true
fail_on_unmatched_files: true
body_path: docs/CURRENT_RELEASE_NOTES.md
body_path: .release-source/docs/CURRENT_RELEASE_NOTES.md
files: |
artifacts/T4-Code-*.apk
artifacts/T4-Code-*.deb
Expand Down
2 changes: 1 addition & 1 deletion scripts/check-release-consistency.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1151,7 +1151,7 @@ export function collectReleaseConsistencyErrors(files, releaseTag) {
);
requireText(
releaseWorkflow,
"body_path: docs/CURRENT_RELEASE_NOTES.md",
"body_path: .release-source/docs/CURRENT_RELEASE_NOTES.md",
".github/workflows/release.yml",
errors,
);
Expand Down
27 changes: 27 additions & 0 deletions scripts/check-release-consistency.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,33 @@ test("historical repair keeps trusted verification code separate from immutable
});
});

test("historical repair keeps trusted publication control separate from release content", () => {
const publishJob = requiredWorkflowJob(files.get(".github/workflows/release.yml"), "publish");
const controlCheckout = requiredNamedStep(
publishJob,
"Check out trusted publication-control source",
);
const contentCheckout = requiredNamedStep(publishJob, "Check out verified release content");
const tagStep = requiredNamedStep(
publishJob,
"Confirm the release tag still resolves to the verified source",
);
const prepareStep = requiredNamedStep(
publishJob,
"Preserve an exact release or prepare an incomplete release for repair",
);
const publishStep = requiredNamedStep(publishJob, "Publish GitHub release");
const verifyStep = requiredNamedStep(publishJob, "Verify the exact remote release bundle");

assert.equal(controlCheckout.with.ref, "${{ github.sha }}");
assert.equal(contentCheckout.with.ref, "${{ needs.verify.outputs.source_sha }}");
assert.equal(contentCheckout.with.path, ".release-source");
assert.equal(tagStep["working-directory"], ".release-source");
assert.match(prepareStep.run, /^node scripts\/reconcile-release-assets\.mjs/u);
assert.equal(publishStep.with.body_path, ".release-source/docs/CURRENT_RELEASE_NOTES.md");
assert.match(verifyStep.run, /^node scripts\/reconcile-release-assets\.mjs/u);
});

test("rejects published app-wire version drift until release surfaces agree", () => {
const drifted = changedRuntime("publishedAppWire", (record) => {
record.version = "0.5.1";
Expand Down
Loading