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
3 changes: 2 additions & 1 deletion .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ jobs:
echo "projects=" >> "$GITHUB_OUTPUT"
exit 0
fi
if [[ "$HEAD_MESSAGE" == *"chore(release):"* || "$HEAD_MESSAGE" == *"[skip release]"* ]] || [ "$BETA_TRANSITIONS" -gt 0 ]; then
HEAD_SUBJECT=${HEAD_MESSAGE%%$'\n'*}
if [[ "$HEAD_SUBJECT" == *"chore(release):"* || "$HEAD_SUBJECT" == *"[skip release]"* ]] || [ "$BETA_TRANSITIONS" -gt 0 ]; then
echo "suspicious release-shaped master push; refusing preparation" >&2
exit 1
fi
Expand Down
29 changes: 26 additions & 3 deletions scripts/release-policy-contract.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@
const buildCommand = /^pnpm nx run-many -t build "--projects=\$PROJECTS" --parallel=3$/
const testCommand = /^pnpm nx run-many -t test "--projects=\$PROJECTS" --parallel=3 --passWithNoTests$/
const contractCommand = /^node --test scripts\/release-policy-contract\.test\.mjs$/
const releaseSubjectGuard =
'[[ "$HEAD_SUBJECT" == *"chore(release):"* || "$HEAD_SUBJECT" == *"[skip release]"* ]] || [ "$BETA_TRANSITIONS" -gt 0 ]'
const rr8Commands = [
/^pnpm nx test @effectify\/react-router$/,
/^pnpm nx run @effectify\/react-router-example:migration:test$/,
Expand Down Expand Up @@ -251,6 +253,12 @@
violations.push("beta mode resolver")
} else {
const commands = resolve.commands.join("\n")
if (!resolve.commands.includes("HEAD_SUBJECT=${HEAD_MESSAGE%%$'\\n'*}")) {
violations.push("beta first-line release subject")
}
if (!resolve.commands.includes(`if ${releaseSubjectGuard}; then`)) {
violations.push("beta subject-only message defense")
}
for (const [pattern, name] of [
[/mode=prepare/, "prepare mode"],
[/mode=finalize/, "finalize mode"],
Expand Down Expand Up @@ -481,10 +489,10 @@

const releasePolicyBootstrapViolations = (source) => {
const steps = extractSteps(extractJob(source, "release-policy"))
const setupNodeIndex = steps.findIndex((step) => /^actions\/setup-node@/.test(step.uses))

Check warning on line 492 in scripts/release-policy-contract.test.mjs

View workflow job for this annotation

GitHub Actions / 🔍 Lint & Format

unicorn(prefer-string-starts-ends-with)

Prefer String#startsWith over a regex with a caret.
if (setupNodeIndex === -1) return ["release-policy setup-node"]

const pnpmIndex = steps.findIndex((step) => /^pnpm\/action-setup@/.test(step.uses))

Check warning on line 495 in scripts/release-policy-contract.test.mjs

View workflow job for this annotation

GitHub Actions / 🔍 Lint & Format

unicorn(prefer-string-starts-ends-with)

Prefer String#startsWith over a regex with a caret.
const cacheDisabled = steps[setupNodeIndex].packageManagerCache === "false"
return pnpmIndex !== -1 && pnpmIndex < setupNodeIndex ? [] : cacheDisabled ? [] : ["release-policy setup-node cache"]
}
Expand Down Expand Up @@ -520,6 +528,20 @@
assert.deepEqual(betaViolations(workflows.beta), [])
})

test("beta release message guards classify only the first-line subject", () => {
const hasReleaseSubjectToken = (message) => {
const subject = message.split("\n", 1)[0]
return subject.includes("chore(release):") || subject.includes("[skip release]")
}
const mergeMessage =
"Merge pull request #232 from devx-op/dev\n\nchore(release): promote protected beta orchestration"

assert.equal(hasReleaseSubjectToken(mergeMessage), false)
assert.equal(hasReleaseSubjectToken("chore(release): prepare beta\nordinary body"), true)
assert.equal(hasReleaseSubjectToken("ordinary subject\n[skip release] in body"), false)
assert.equal(hasReleaseSubjectToken("ordinary subject [skip release]\nbody"), true)
})

test("beta FINALIZE is exact-SHA, tag-only, prerelease-first, and retryable", () => {
assert.deepEqual(betaViolations(workflows.beta), [])
})
Expand Down Expand Up @@ -619,10 +641,11 @@
'[ "$HAS_CHANGELOG" = "true" ] && [ "$UNEXPECTED" = "false" ]',
'[ "$HAS_CHANGELOG" = "true" ] && [ "$UNEXPECTED" = "true" ]',
],
["trust release message without structure", releaseSubjectGuard, '[ "$BETA_TRANSITIONS" -gt 0 ]'],
[
"trust release message without structure",
'[[ "$HEAD_MESSAGE" == *"chore(release):"* || "$HEAD_MESSAGE" == *"[skip release]"* ]] || [ "$BETA_TRANSITIONS" -gt 0 ]',
'[ "$BETA_TRANSITIONS" -gt 0 ]',
"classify release tokens from the full merge message",
releaseSubjectGuard,
releaseSubjectGuard.replaceAll("HEAD_SUBJECT", "HEAD_MESSAGE"),
],
[
"suppress a suspicious shape",
Expand Down
Loading