publish-package-cicd
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.
When & Why to Use This Skill
This Claude skill provides a robust CI/CD publishing workflow for npm packages, specifically optimized for Bun monorepos. It leverages Changesets for automated versioning and npm Trusted Publishers (OIDC) for secure, tokenless authentication via GitHub Actions. By addressing complex issues like workspace protocol resolution and runtime dependency management, it ensures a seamless and secure release process for modern JavaScript/TypeScript projects.
Use Cases
- Automated Monorepo Releases: Streamlining the versioning and publishing of multiple packages within a Turborepo or Bun monorepo using Changesets.
- Secure Tokenless Publishing: Implementing npm Trusted Publishers (OIDC) to eliminate the security risks associated with long-lived NPM_TOKEN secrets in CI/CD pipelines.
- Workspace Protocol Resolution: Fixing 'Cannot find module' errors and ensuring 'workspace:*' dependencies are correctly resolved to actual versions during the npm publish process.
- GitHub Actions Workflow Optimization: Configuring automated release flows that handle everything from changeset detection and PR creation to final package distribution and provenance attestation.
| 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 publicConfigure Trusted Publisher:
- Go to https://www.npmjs.com/package/your-package/access
- Click "Trusted Publishers" → "Add"
- Fill in:
- Organization:
your-github-org - Repository:
your-repo-name - Workflow:
publish.yml
- Organization:
- Save
Future releases: Fully automated via GitHub Actions
How OIDC Works
- No
NPM_TOKENsecret required - GitHub Actions has
id-token: writepermission - 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:
# 1. Sync lockfile (resolves workspace:* from lockfile)
bun install
# 2. Pack tarball (resolves workspace:* to actual versions)
bun pm pack
# 3. Publish tarball (supports npm OIDC)
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:
# In CI, exclude ignored packages from build
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", // Used by bin/cli.ts
"commander": "^11.0.0" // Used by bin/cli.ts
}
}
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 # Sync lockfile with new versions
bun pm pack # Now packs with correct versions
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
# Create changeset (manual file creation)
cat > .changeset/fix-thing.md << 'EOF'
---
"pkg-name": patch
---
Fixed the thing
EOF
# Preview version bumps (optional, informational only)
bunx changeset status
# Build packages (exclude ignored)
bun turbo build --filter='!@swarmtools/web'
# Publish (in CI only, via publish.yml)
bun install # Sync lockfile
bun pm pack # Create tarball with resolved workspace:*
npm publish <tarball> # Publish with OIDC
Tracking Issues
- Bun native npm token support: https://github.com/oven-sh/bun/issues/15601
- When resolved, can switch to
bun publishdirectly - Currently must use
npm publishfor OIDC support
- When resolved, can switch to