| name | publish-package-cicd |
| description | CI/CD publishing workflow for npm packages using Changesets + npm Trusted Publishers (OIDC). Use when setting up automated npm publishing for monorepos, configuring GitHub Actions for releases, troubleshooting workspace:* protocol resolution issues, fixing "Cannot find module" errors in published packages, or debugging npm OIDC authentication. Covers Bun + Turborepo + Changesets + npm Trusted Publishers with workspace protocol resolution. |
Publish Package CI/CD
Automated npm publishing for Bun monorepos using Changesets + npm Trusted Publishers (OIDC). No npm tokens needed - GitHub Actions authenticates via OIDC.
Core Workflow
1. Create Changeset (Manual File Creation)
CRITICAL: Never run bunx changeset interactively. Create changeset files manually to avoid the interactive CLI:
cat > .changeset/your-change-name.md << 'EOF'
---
"package-name": patch
---
Description of the change
EOF
Version bump types:
patch - Bug fixes, minor updates (0.0.x)
minor - New features, backwards compatible (0.x.0)
major - Breaking changes (x.0.0)
2. Commit and Push
git add .changeset/your-change-name.md
git commit -m "feat: your feature description"
git push origin main
3. Automated Release Flow
- Changesets Action (
.github/workflows/ci.yml) detects changeset file
- Creates/updates "chore: release packages" PR with version bumps + CHANGELOG
- On PR merge → triggers publish workflow (
.github/workflows/publish.yml)
- Publishes to npm via OIDC (no npm token)
Trusted Publishers (OIDC) Setup
Initial Package Setup (One-Time)
For each package to publish:
-
Publish v0.1.0 manually:
cd packages/your-package
npm publish --access public
-
Configure Trusted Publisher:
-
Future releases: Fully automated via GitHub Actions
How OIDC Works
- No
NPM_TOKEN secret required
- GitHub Actions has
id-token: write permission
- npm packages configured with Trusted Publisher pointing to repo + workflow
- npm CLI 11.5.1+ auto-detects OIDC environment
- Provenance attestations generated automatically
workspace:* Protocol Resolution
Problem: workspace:* in package.json dependencies doesn't resolve during npm publish, causing "Cannot find module" errors for consumers.
Solution: Use custom publish script with two-step process:
bun install
bun pm pack
npm publish <tarball>
Why not bun publish? Bun resolves workspace protocols but doesn't support npm OIDC - requires npm login.
See references/publish-script.ts for full implementation.
Ignored Packages (Non-Published)
Exclude packages from publishing in .changeset/config.json:
{
"ignore": ["@swarmtools/web", "docs-app"]
}
Important: Changeset ignore only affects versioning, NOT builds. Must also exclude from turbo:
bun turbo build --filter='!@swarmtools/web'
Common Issues
CLI Bin Script "Cannot find module"
Symptom: Published package works, but CLI bin script fails with Cannot find module '@clack/prompts'.
Root cause: Bin script imports are runtime dependencies, not devDependencies.
Fix: Move ALL bin script imports to dependencies in package.json:
{
"dependencies": {
"@clack/prompts": "^0.7.0",
"commander": "^11.0.0"
}
}
Lockfile Stale After Changeset Bump
Symptom: Publish picks up old versions of workspace:* dependencies.
Root cause: bun pm pack resolves from lockfile, which is stale after version bumps.
Fix: Run bun install BEFORE bun pm pack:
bun install
bun pm pack
npm publish <tarball>
See references/publish-script.ts - automatically handles this.
Local bunx changeset version Fails
Symptom: Error: GITHUB_TOKEN not found
Root cause: Changesets needs GitHub API access for PR/changelog generation. Works in CI (has GITHUB_TOKEN), fails locally.
Fix: Don't run bunx changeset version or bunx changeset publish locally. Let CI handle it:
- Create changeset file manually
- Push to main
- CI creates release PR
- Merge PR → auto-publishes
Bun Publish vs npm Publish
Avoid bun publish - doesn't support npm OIDC (requires npm login).
Use npm publish <tarball> - supports OIDC + resolves workspace protocols when publishing tarball created by bun pm pack.
Reference Files
- references/publish-workflow.yml - Full GitHub Actions workflow with OIDC + workspace resolution
- references/changeset-config.json - Changeset configuration with ignored packages
- references/publish-script.ts - Custom publish script handling workspace:* resolution
Commands Reference
cat > .changeset/fix-thing.md << 'EOF'
---
"pkg-name": patch
---
Fixed the thing
EOF
bunx changeset status
bun turbo build --filter='!@swarmtools/web'
bun install
bun pm pack
npm publish <tarball>
Tracking Issues