Skip to content

Publishing packages

All five @drawnagency/* packages are published to npm under the public @drawnagency scope. The release flow is deliberate and gated — do not shortcut it.

Terminal window
bash scripts/publish.sh
bash scripts/publish.sh --dry-run # preview what would be published

Never run pnpm publish manually. The script:

  1. Detects which packages need publishing — compares each package’s local package.json version against the version on npm. Packages where the local version differs from npm are queued.
  2. Validates workspace dependencies — if a queued package depends on another workspace:* package that also has unpublished changes but is not in the queue, the script aborts.
  3. Enforces a clean working tree — if git diff or git diff --cached is non-empty, the script aborts. This prevents publishing uncommitted or stale state.
  4. Runs the test suitenpx vitest run must pass before any package is published.
  5. Publishes in dependency order — primitives → authoring → github → auth-supabase → core.
  6. Refreshes the template lockfile — after publishing, scripts/refresh-template-lockfile.mjs is run and the result is committed as chore: refresh template lockfile. This keeps newly-provisioned client sites on the just-published versions (the template lockfile is propagated downstream by the sync-template.yml workflow on push to main).

The script calls pnpm publish --access public --publish-branch main for each package. Never substitute npm publish. The reason: all packages use workspace:* for internal dependencies in package.json. pnpm resolves these to real version numbers when publishing. npm publishes them literally — as the string "workspace:^" — which silently breaks all consumer installs.

Do not bump versions ad-hoc. The release flow is:

  1. Make changes.
  2. When ready to release, create a single commit bumping the version field in package.json for each changed package. Commit message convention: chore: bump @drawnagency/primitives to 0.1.65.
  3. Run bash scripts/publish.sh.

If you bump @drawnagency/primitives, also bump @drawnagency/authoring, @drawnagency/github, @drawnagency/auth-supabase, and @drawnagency/core since they all depend on it.

All packages use 0.1.x versions. Client site package.json files use ^0.1.0 ranges. Due to semver’s 0.x rules, ^0.1.0 means >=0.1.0 <0.2.0. Publishing a 0.2.0 version would break all clients on ^0.1.0. Stay within 0.1.x until a deliberate major version bump.

Client repos have renovate.json (shipped via the template) configured with:

  • automerge: true for @drawnagency/**
  • minimumReleaseAge: "3 days" — 3-day buffer to catch a bad publish before it auto-merges into client production

This automerge posture is safe only because scripts/publish.sh runs the test suite and requires a clean tree before publishing. If the test gate is ever removed, set automerge: false.

The root renovate.json sets "enabled": false. The Renovate App is installed org-wide to manage client repos, but the monorepo’s toolchain is managed manually. Do not re-enable without understanding the interaction with workspace * internal dependencies.