Skip to content

Commit 8a2acdb

Browse files
Merge pull request #26 from syzsunshine219/fix/github-release-validated-detach
fix(release): detach only validated main commits
2 parents a41c9fd + b5443eb commit 8a2acdb

2 files changed

Lines changed: 22 additions & 17 deletions

File tree

‎.github/workflows/github-release.yml‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,9 @@ jobs:
8484
exit 1
8585
fi
8686
87-
- name: Check out trusted main history
87+
- name: Check out trusted base history
8888
uses: actions/checkout@v4
8989
with:
90-
ref: main
9190
fetch-depth: 0
9291
persist-credentials: false
9392

@@ -96,9 +95,11 @@ jobs:
9695
TARGET_SHA: ${{ steps.release.outputs.target_sha }}
9796
run: |
9897
set -euo pipefail
99-
git fetch --no-tags origin refs/heads/main:refs/remotes/origin/main
98+
git fetch --no-tags origin main
10099
git cat-file -e "$TARGET_SHA^{commit}"
101-
git merge-base --is-ancestor "$TARGET_SHA" refs/remotes/origin/main
100+
git merge-base --is-ancestor "$TARGET_SHA" origin/main
101+
git checkout --detach "$TARGET_SHA"
102+
test "$(git rev-parse HEAD)" = "$TARGET_SHA"
102103
103104
- name: Download and verify OSS artifacts
104105
env:

‎tests/release-workflow.test.ts‎

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,24 +54,28 @@ describe("GitHub release workflow", () => {
5454
});
5555

5656
it("keeps merged fork code out of the trusted release checkout", () => {
57-
const checkout = steps.find((step) => step.name === "Check out trusted main history");
57+
const checkout = steps.find((step) => step.name === "Check out trusted base history");
5858
expect(checkout?.uses).toBe("actions/checkout@v4");
59-
expect(checkout?.with).toEqual(
60-
expect.objectContaining({
61-
ref: "main",
62-
"fetch-depth": 0,
63-
"persist-credentials": false,
64-
}),
65-
);
66-
expect(JSON.stringify(checkout?.with)).not.toContain("target_sha");
59+
expect(checkout?.with).toEqual({
60+
"fetch-depth": 0,
61+
"persist-credentials": false,
62+
});
63+
expect(checkout?.with).not.toHaveProperty("ref");
64+
expect(JSON.stringify(checkout)).not.toContain("github.event.pull_request");
65+
expect(source).not.toContain("refs/pull/");
6766
expect(source).not.toContain("allow-unsafe-pr-checkout");
6867

6968
const verifyScript = script("Verify target is on main");
70-
expect(verifyScript).toContain("refs/heads/main:refs/remotes/origin/main");
69+
expect(verifyScript).toContain("git fetch --no-tags origin main");
7170
expect(verifyScript).toContain('git cat-file -e "$TARGET_SHA^{commit}"');
72-
expect(verifyScript).toContain(
73-
'git merge-base --is-ancestor "$TARGET_SHA" refs/remotes/origin/main',
74-
);
71+
const ancestorCheck = 'git merge-base --is-ancestor "$TARGET_SHA" origin/main';
72+
const detachTarget = 'git checkout --detach "$TARGET_SHA"';
73+
const verifyHead = 'test "$(git rev-parse HEAD)" = "$TARGET_SHA"';
74+
expect(verifyScript).toContain(ancestorCheck);
75+
expect(verifyScript).toContain(detachTarget);
76+
expect(verifyScript).toContain(verifyHead);
77+
expect(verifyScript.indexOf(detachTarget)).toBeGreaterThan(verifyScript.indexOf(ancestorCheck));
78+
expect(verifyScript.indexOf(verifyHead)).toBeGreaterThan(verifyScript.indexOf(detachTarget));
7579

7680
const notesScript = script("Build release notes");
7781
expect(notesScript).toContain('manual_object="${TARGET_SHA}:${manual_notes}"');

0 commit comments

Comments
 (0)