fix(ci): publish packages in topological (dependency) order - fixes #3045#3052
fix(ci): publish packages in topological (dependency) order - fixes #3045#3052hbmartin wants to merge 5 commits intoresend:canaryfrom
Conversation
…ing to pnpm changeset publish - Halt publishing when a dependency fails: if any package fails to publish, all of its dependents are transitively skipped, preventing @react-email/components from referencing versions that don't exist on npm - Add --dry-run flag to scripts/release.mts: builds all packages, checks the npm registry, and prints the topological publish plan with build status without actually publishing - Add unit tests for the publish pipeline ### Motivation `@react-email/components` re-exports all 18+ component packages as direct dependencies. If any one of those packages fails during `npm publish`, `changeset publish` continues publishing the rest. There is no built-in way to make changeset publish bail on failure or respect dependency order. These leads to errors such as resend#3041 and resend#3047 ### Implementation `scripts/release-utils.mts` implements the publish pipeline: 1. Determine what to publish: each non-private workspace package is checked against the npm registry via npm view <pkg>@<version> 2. Build a dependency graph scoped to the publish set: using dependencies and devDependencies from each package.json (via @manypkg/get-packages, already a dev dependency) 3. Topological sort (Kahn's algorithm): leaf packages with no workspace dependencies in the publish set are published first 4. Publish with failure tracking: a failed set tracks any package that errors. Before publishing each package, its workspace dependencies are checked against the failed set; if any dependency failed, the package is skipped and added to the failed set transitively 5. Exit with non-zero code if any packages failed, failing the workflow `scripts/release.mts` changes are intentionally minimal i.e. getChangelogEntry, createRelease, and the git tag/release loop are unchanged. The middle section replaces the single pnpm release call (which ran `turbo build && changeset publish` as a black box) with explicit build + `topologicalPublish()`. ### Testing - The dry run command will show publishing order and status: `node --import tsx/esm ./scripts/release.mts --dry-run` - The pipeline test can be run as: `pnpm vitest run scripts/release-utils.test.mts`
|
@hbmartin is attempting to deploy a commit to the resend Team on Vercel. A member of the Team first needs to authorize it. |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
…04 npm errors instead of treating them as “unpublished”, publish ordering now uses runtime deps only (dependencies plus optionalDependencies), and prerelease publishing now restores the per-package Changesets fallback so only-pre packages publish to latest while brand-new prerelease packages stay on the prerelease tag.
| @@ -0,0 +1,432 @@ | |||
| import fs from 'node:fs/promises'; | |||
There was a problem hiding this comment.
I'd rather this be in release.mts
(n.b. over half of the added lines are tests, see below for testing directions)
Motivation
@react-email/componentsre-exports all 18+ component packages as direct dependencies. If any one of those packages fails duringnpm publish,changeset publishcontinues publishing the rest. There is no built-in way to make changeset publish bail on failure or respect dependency order. These leads to errors such as #3041 and #3047Implementation
scripts/release-utils.mtsimplements the publish pipeline:npm view <pkg>@<version>@manypkg/get-packages, already a dev dependency)scripts/release.mtschanges are intentionally minimal i.e. getChangelogEntry, createRelease, and the git tag/release loop are unchanged. The middle section replaces the single pnpm release call (which ranturbo build && changeset publishas a black box) with explicit build +topologicalPublish().Testing
node --import tsx/esm ./scripts/release.mts --dry-runpnpm vitest run scripts/release-utils.test.mtsSummary by cubic
Publishes workspace packages in topological dependency order (including required peer deps) and skips dependents if any publish fails. Adds a
--dry-runmode to preview the plan with dist-tags, build status, and dependency info, and hardens registry checks and prerelease tag selection.New Features
--dry-runshows order, per-package dist-tag, build status, and dependencies, and continues even if build failed.latest; brand-new prerelease packages use the prerelease tag.Bug Fixes
@react-email/componentsreleases by enforcing dependency order.Written for commit 97bc996. Summary will update on new commits.