Skip to content

chore: Fix changeset config + add version cleanup scripts#810

Merged
kingston merged 6 commits into
mainfrom
kingston/eng-986-eng-986-fix-changeset-config-add-version-cleanup-scripts-pr
Mar 11, 2026
Merged

chore: Fix changeset config + add version cleanup scripts#810
kingston merged 6 commits into
mainfrom
kingston/eng-986-eng-986-fix-changeset-config-add-version-cleanup-scripts-pr

Conversation

@kingston

@kingston kingston commented Mar 11, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • Chores
    • Release workflow normalized formatting and now assigns versions dynamically.
    • Added a release helper script and a new package.json script to post-process bumped versions to avoid duplicate publishes.
    • Added a maintained skip-list of published versions and tooling to generate or unpublish problematic versions.
    • Expanded release/package selection to include plugin packages and improved change detection across the workspace.

@changeset-bot

changeset-bot Bot commented Mar 11, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: f172c9d

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Mar 11, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@kingston has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 15 minutes and 34 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1e5b538f-c94d-4c9f-b4a3-fcc7e86e20d2

📥 Commits

Reviewing files that changed from the base of the PR and between 517f4bd and f172c9d.

📒 Files selected for processing (2)
  • package.json
  • scripts/version-fix/unpublish.js
📝 Walkthrough

Walkthrough

Changes expand Changesets fixed pattern to include plugin packages, add post-version tooling to avoid republishing already-published versions (skip list, collector, unpublisher, and a version-fix script), and update check-changesets to filter by git diff/last tag and broadened scripts matching in knip config.

Changes

Cohort / File(s) Summary
Changeset & Release Config
\.changeset/config.json, .github/workflows/release.yml, package.json
Fixed pattern now includes @baseplate-dev/* (removing previous negation); workflow quoting normalized and release step adds dynamic version; new scripts.version runs pnpm changeset version then node ./scripts/fix-versions.js.
Post-version fixer
scripts/fix-versions.js
New script that reads scripts/published-version-skip-list.json, verifies workspace versions align, increments patch versions for packages whose current version is in the skip list, updates package.json and corresponding CHANGELOG headings, and logs results.
Skip list data
scripts/published-version-skip-list.json
New static JSON mapping package scopes to arrays of versions to skip when publishing.
Version-collection & unpublish tools
scripts/version-fix/collect-bad-versions.js, scripts/version-fix/unpublish.js
New utilities: collector queries npm for published versions and writes the skip list; unpublish iterates the skip list to unpublish versions (supports dry-run) and optionally deletes git tags for plugin packages.
Project tooling config
knip.config.js
Expanded scripts glob from scripts/*.{js,ts} to scripts/**/*.{js,ts} to include nested script files.
Changeset validation
scripts/check-changesets.ts
Updated getPackagesToPublish(lastTag) signature; compute lastTag once, obtain git-diffed changed file paths, and filter affected packages to those with actual changes since lastTag.

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer
    participant Changeset as Changeset CLI
    participant FixVer as fix-versions.js
    participant Collector as collect-bad-versions.js
    participant Unpub as unpublish.js
    participant NPM as npm Registry
    participant Git as Git

    Dev->>Changeset: pnpm changeset version
    Changeset->>Changeset: bump workspace package versions
    Changeset->>FixVer: run post-version script
    FixVer->>FixVer: read published-version-skip-list.json
    FixVer->>FixVer: detect skipped versions and bump patch
    FixVer->>FixVer: update package.json and CHANGELOG.md

    Dev->>Collector: run collect-bad-versions
    Collector->>NPM: fetch published versions & latest tags
    Collector->>Collector: compute bad versions
    Collector->>Collector: write published-version-skip-list.json

    Dev->>Unpub: run unpublish [--dry-run]
    Unpub->>Unpub: read published-version-skip-list.json
    Unpub->>NPM: check & unpublish listed versions
    Unpub->>Git: optionally delete git tags for plugin packages
    Unpub->>Unpub: report results
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: fixing changeset config and adding version cleanup scripts, which aligns with the core modifications across .changeset/config.json, package.json scripts, and new version-fix scripts.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch kingston/eng-986-eng-986-fix-changeset-config-add-version-cleanup-scripts-pr

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/version-fix/unpublish.js`:
- Around line 178-197: The early continue prevents cleanup of stale plugin git
tags when the npm version is already gone; adjust the logic in the block that
checks isDryRun and isVersionPublished so that for plugins (use isPlugin and
semverMajor(version)) you still call deleteGitTag(tag) before continuing. Keep
the existing behavior for totalSkipped/totalUnpublished and only call
unpublishVersion(packageName, version) when appropriate (preserve the existing
unpublish path with unpublishVersion and its success handling).
- Around line 97-103: The isVersionPublished(packageName, version) function
currently swallows all errors from the `run('npm view ...')` call and returns
false; change it to detect an actual 404 (package/version not found) and return
false only in that case, while re-throwing any other errors (auth, network,
registry) so they propagate. Concretely, catch the error thrown by run in
isVersionPublished, inspect the error output/code/message for the npm 404
pattern (e.g., "404" or "npm ERR! 404" / ENOTFOUND depending on run's error
shape), return false when it matches the 404 case, and otherwise re-throw the
error; keep the function signature and callers (unpublishVersion, main loop)
unchanged so they will now fail on transient failures instead of treating them
as "already gone."

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9597e0da-a3cd-4dc2-b088-e96a9672aa29

📥 Commits

Reviewing files that changed from the base of the PR and between 3ee6717 and ca8866a.

📒 Files selected for processing (7)
  • .changeset/config.json
  • .github/workflows/release.yml
  • package.json
  • scripts/fix-versions.js
  • scripts/published-version-skip-list.json
  • scripts/version-fix/collect-bad-versions.js
  • scripts/version-fix/unpublish.js

Comment thread scripts/version-fix/unpublish.js
Comment thread scripts/version-fix/unpublish.js

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/check-changesets.ts`:
- Around line 299-317: The prefix-comparison in the affectedPackageNames
calculation can miss matches on Windows because changedFilePaths (from git diff)
uses POSIX-style '/' while packageItem.path may contain platform separators;
normalize both sides before comparing: transform each entry of changedFilePaths
and packageItem.path to a consistent POSIX-style form (e.g., replace backslashes
with '/' and run a normalization) before performing the startsWith check in the
affectedPackageNames mapping over turboData.packages.items so the comparison
correctly detects changed files across platforms.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 863196e9-ee11-4ce0-bc57-0956a429f463

📥 Commits

Reviewing files that changed from the base of the PR and between ca8866a and 517f4bd.

📒 Files selected for processing (2)
  • knip.config.js
  • scripts/check-changesets.ts

Comment on lines +299 to +317
if (lastTag) {
const { stdout: diffOutput } = await execAsync(
`git diff "${lastTag}"..HEAD --name-only`,
);
changedFilePaths = new Set(diffOutput.trim().split('\n').filter(Boolean));
}

const affectedPackageNames = turboData.packages.items
.map((item) => item.name)
.filter((name) => {
if (!changedFilePaths) return true;
const packageItem = turboData.packages.items.find(
(i) => i.name === name,
);
if (!packageItem) return true;
return [...changedFilePaths].some((f) =>
f.startsWith(`${packageItem.path}/`),
);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Normalize both path sources before the prefix check.

git diff --name-only uses /, but packageItem.path can be platform-native. On Windows, the current startsWith(${packageItem.path}/) check can miss every changed package and silently skip validation.

💡 Suggested fix
     if (lastTag) {
       const { stdout: diffOutput } = await execAsync(
         `git diff "${lastTag}"..HEAD --name-only`,
       );
       changedFilePaths = new Set(diffOutput.trim().split('\n').filter(Boolean));
     }

-    const affectedPackageNames = turboData.packages.items
-      .map((item) => item.name)
-      .filter((name) => {
-        if (!changedFilePaths) return true;
-        const packageItem = turboData.packages.items.find(
-          (i) => i.name === name,
-        );
-        if (!packageItem) return true;
-        return [...changedFilePaths].some((f) =>
-          f.startsWith(`${packageItem.path}/`),
-        );
-      });
+    const normalizeRepoPath = (value: string): string =>
+      value.replaceAll('\\', '/').replace(/\/+$/, '');
+
+    const normalizedChangedFilePaths = changedFilePaths
+      ? [...changedFilePaths].map(normalizeRepoPath)
+      : null;
+
+    const affectedPackageNames = turboData.packages.items
+      .filter((item) => {
+        if (!normalizedChangedFilePaths) return true;
+        const packagePathPrefix = `${normalizeRepoPath(item.path)}/`;
+        return normalizedChangedFilePaths.some((file) =>
+          file.startsWith(packagePathPrefix),
+        );
+      })
+      .map((item) => item.name);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (lastTag) {
const { stdout: diffOutput } = await execAsync(
`git diff "${lastTag}"..HEAD --name-only`,
);
changedFilePaths = new Set(diffOutput.trim().split('\n').filter(Boolean));
}
const affectedPackageNames = turboData.packages.items
.map((item) => item.name)
.filter((name) => {
if (!changedFilePaths) return true;
const packageItem = turboData.packages.items.find(
(i) => i.name === name,
);
if (!packageItem) return true;
return [...changedFilePaths].some((f) =>
f.startsWith(`${packageItem.path}/`),
);
});
if (lastTag) {
const { stdout: diffOutput } = await execAsync(
`git diff "${lastTag}"..HEAD --name-only`,
);
changedFilePaths = new Set(diffOutput.trim().split('\n').filter(Boolean));
}
const normalizeRepoPath = (value: string): string =>
value.replaceAll('\\', '/').replace(/\/+$/, '');
const normalizedChangedFilePaths = changedFilePaths
? [...changedFilePaths].map(normalizeRepoPath)
: null;
const affectedPackageNames = turboData.packages.items
.filter((item) => {
if (!normalizedChangedFilePaths) return true;
const packagePathPrefix = `${normalizeRepoPath(item.path)}/`;
return normalizedChangedFilePaths.some((file) =>
file.startsWith(packagePathPrefix),
);
})
.map((item) => item.name);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/check-changesets.ts` around lines 299 - 317, The prefix-comparison in
the affectedPackageNames calculation can miss matches on Windows because
changedFilePaths (from git diff) uses POSIX-style '/' while packageItem.path may
contain platform separators; normalize both sides before comparing: transform
each entry of changedFilePaths and packageItem.path to a consistent POSIX-style
form (e.g., replace backslashes with '/' and run a normalization) before
performing the startsWith check in the affectedPackageNames mapping over
turboData.packages.items so the comparison correctly detects changed files
across platforms.

@kingston kingston merged commit 72d83ff into main Mar 11, 2026
6 checks passed
@kingston kingston deleted the kingston/eng-986-eng-986-fix-changeset-config-add-version-cleanup-scripts-pr branch March 11, 2026 20:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant