fix: harden release system — registry error handling, tag check, prerelease tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jordan Ritter
2026-04-12 21:57:53 -07:00
parent 9686a71cd9
commit abb87bf5f0
3 changed files with 37 additions and 3 deletions
+14
View File
@@ -74,6 +74,20 @@ jobs:
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
- name: Check for pre-existing tags
run: |
SCOPE="${{ steps.meta.outputs.scope }}"
VERSION="${{ steps.publish.outputs.version }}"
if [ "$SCOPE" == "monorepo" ]; then
TAG="v${VERSION}"
else
TAG="${SCOPE}/v${VERSION}"
fi
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "ERROR: Tag $TAG already exists" >&2
exit 1
fi
- name: Create and push git tag
run: |
SCOPE="${{ steps.meta.outputs.scope }}"
+4
View File
@@ -76,6 +76,10 @@ function main() {
console.log("\nBuilding packages...");
run("pnpm", ["run", "build"]);
// Run tests before publishing
console.log("\nRunning tests...");
run("pnpm", ["run", "test"]);
// Publish each package
console.log("\nPublishing packages...");
for (const p of getPackagesForScope(scope)) {
+19 -3
View File
@@ -43,8 +43,17 @@ function getPublishedVersion(packageName: string): string | null {
encoding: "utf8",
timeout: 15000,
});
if (result.status !== 0) return null;
return result.stdout.trim() || null;
if (result.status === 0) {
return result.stdout.trim() || null;
}
// E404 means package doesn't exist on registry — genuinely not published
if (result.stderr?.includes("E404") || result.stderr?.includes("is not in this registry")) {
return null;
}
// Any other error (network, auth, rate limit) should stop the release
throw new Error(
`npm registry check failed for ${packageName}: ${result.stderr?.trim() || "unknown error"}`
);
}
function isGreaterVersion(next: string, current: string): boolean {
@@ -87,7 +96,14 @@ async function main() {
}
// Safety check: refuse to publish if version isn't greater than what's on npm
const published = getPublishedVersion(scopeConfig.versionSource);
let published: string | null;
try {
published = getPublishedVersion(scopeConfig.versionSource);
} catch (err: any) {
console.error(`Registry check failed — aborting release to avoid publishing over an existing version.`);
console.error(err.message);
process.exit(1);
}
if (published) {
console.log(`Currently published version: ${published}`);
if (!isGreaterVersion(version, published)) {