Skip to content

Commit bcec8d7

Browse files
Guard release docs tag commands
1 parent 1b0f36d commit bcec8d7

2 files changed

Lines changed: 88 additions & 0 deletions

File tree

scripts/package-runtime-coverage.test.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,64 @@ test("validatePackageRuntimeCoverage rejects lightweight release tag workflow co
11481148
);
11491149
});
11501150

1151+
test("validatePackageRuntimeCoverage rejects unsafe release tag doc commands", async (t) => {
1152+
const tempDir = await mkdtemp(path.join(tmpdir(), "ray-package-runtime-release-doc-tags-"));
1153+
t.after(async () => {
1154+
await rm(tempDir, { recursive: true, force: true });
1155+
});
1156+
1157+
const rootPackageJson = path.join(tempDir, "package.json");
1158+
await writeFile(
1159+
rootPackageJson,
1160+
JSON.stringify(
1161+
{
1162+
name: "ray-test",
1163+
packageManager: "bun@1.3.9",
1164+
engines: {
1165+
bun: ">=1.3.0",
1166+
},
1167+
scripts: {},
1168+
},
1169+
null,
1170+
2,
1171+
),
1172+
);
1173+
await writeFile(
1174+
path.join(tempDir, "README.md"),
1175+
[
1176+
"# Ray test",
1177+
"",
1178+
"```bash",
1179+
'TAG_CORE="core-v1.2.3"',
1180+
'TAG_SDK="sdk-v1.2.3"',
1181+
'git tag "$TAG_CORE"',
1182+
'git push origin "$TAG_CORE" "$TAG_SDK"',
1183+
"```",
1184+
"",
1185+
].join("\n"),
1186+
);
1187+
1188+
const summary = await validatePackageRuntimeCoverage({
1189+
cwd: tempDir,
1190+
packageJsonPaths: [rootPackageJson],
1191+
});
1192+
const diagnostics = summary.results.flatMap((result) => result.diagnostics);
1193+
1194+
assert.equal(summary.ok, false);
1195+
assert.ok(
1196+
diagnostics.some(
1197+
(diagnostic) =>
1198+
diagnostic.code === "runtime_doc_release_lightweight_tag_command" && diagnostic.line === 6,
1199+
),
1200+
);
1201+
assert.ok(
1202+
diagnostics.some(
1203+
(diagnostic) =>
1204+
diagnostic.code === "runtime_doc_release_tag_push_not_atomic" && diagnostic.line === 7,
1205+
),
1206+
);
1207+
});
1208+
11511209
test("validatePackageRuntimeCoverage requires bounded quality release gate workflow commands", async (t) => {
11521210
const tempDir = await mkdtemp(path.join(tmpdir(), "ray-package-runtime-quality-timeouts-"));
11531211
t.after(async () => {

scripts/package-runtime-coverage.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ const workflowReleaseMainAncestryPattern =
7070
const workflowIdTokenWritePattern = /^\s*id-token:\s*write\s*$/m;
7171
const workflowNpmTokenPattern = /NODE_AUTH_TOKEN:\s*\$\{\{\s*secrets\.NPM_TOKEN\s*\}\}/;
7272
const workflowLightweightReleaseTagCommentPattern = /^\s*#\s*git\s+tag\s+"\$TAG"(?:\s|$)/;
73+
const releaseTagVariablePattern = /\$(?:\{TAG(?:_(?:CORE|SDK))?\}|TAG(?:_(?:CORE|SDK))?)/;
74+
const releaseDocGitTagCommandPattern = /^git\s+tag\s+/;
75+
const releaseDocAnnotatedGitTagCommandPattern = /^git\s+tag\s+(?:-a|--annotate)\b/;
76+
const releaseDocNonAtomicTagPushPattern = /^git\s+push\s+origin\b/;
7377
const repoOwnedVpsWorkflowDocPattern =
7478
/\b(?:GitHub VPS workflow|workflow bootstrap|workflow appends|RAY_ENV_FILE_CONTENTS|repository variables|The deploy workflow)\b/;
7579

@@ -2601,6 +2605,32 @@ async function validateRuntimeDoc(
26012605
});
26022606
}
26032607

2608+
if (
2609+
releaseTagVariablePattern.test(line) &&
2610+
releaseDocGitTagCommandPattern.test(line) &&
2611+
!releaseDocAnnotatedGitTagCommandPattern.test(line)
2612+
) {
2613+
diagnostics.push({
2614+
level: "error",
2615+
code: "runtime_doc_release_lightweight_tag_command",
2616+
docPath,
2617+
line: index + 1,
2618+
message:
2619+
"Runtime release docs must use annotated git tags in executable examples so operators do not cut lightweight package release tags.",
2620+
});
2621+
}
2622+
2623+
if (releaseTagVariablePattern.test(line) && releaseDocNonAtomicTagPushPattern.test(line)) {
2624+
diagnostics.push({
2625+
level: "error",
2626+
code: "runtime_doc_release_tag_push_not_atomic",
2627+
docPath,
2628+
line: index + 1,
2629+
message:
2630+
"Runtime release docs must push package release tags with git push --atomic so linked package tags are not partially published.",
2631+
});
2632+
}
2633+
26042634
if (options.enforceVpsTimeouts && isPipedShellCurl(line) && !hasPipedShellTimeout(line)) {
26052635
diagnostics.push({
26062636
level: "error",

0 commit comments

Comments
 (0)