Introduction to pubm
Relevant source files
The following files were used as context for generating this wiki page:
pubm is a release orchestrator and CLI tool designed for repositories that publish to multiple registries, ecosystems, or packages simultaneously. It streamlines the publishing workflow by automating versioning, preflight validation, and multi-registry deployment (npm, JSR, crates.io, and private registries) within a single pipeline.
The system is built with a "zero-config" philosophy, where it auto-detects project structures and target registries by reading manifest files like package.json, jsr.json, and Cargo.toml. A key architectural feature is its automatic rollback mechanism, which ensures that if a publish task fails at any registry, the tool undoes version bumps, git tags, and commits to maintain repository integrity.
Sources: README.md:1-15, website/public/INFORMATION.md:1-12
Core Architecture and Layout
The pubm repository is structured as a monorepo using Turborepo and Bun workspaces. It separates core logic from the CLI interface and plugin extensions to ensure modularity and extensibility.
Repository Structure
| Path | Component | Description |
|---|---|---|
packages/core | @pubm/core | The Core SDK containing logic for ecosystems, registries, changesets, and plugins. |
packages/pubm | pubm | The Commander-based CLI that consumes the Core SDK. |
packages/plugins | Official Plugins | Specialized extensions like @pubm/plugin-brew or @pubm/plugin-external-version-sync. |
.pubm/changesets/ | Release Input | Storage for pending changesets used to drive version bumps. |
Sources: CLAUDE.md:11-26, website/public/INFORMATION.md:20-26
Ecosystem Detection Logic
pubm determines the target registry by scanning for specific manifest files in the project root or workspace directories.
| Manifest File | Target Registry | Ecosystem |
|---|---|---|
package.json | npm | JavaScript/TypeScript |
jsr.json / deno.json | JSR | JavaScript/TypeScript (Deno) |
Cargo.toml | crates.io | Rust |
Sources: README.md:31-38, plugins/pubm-plugin/skills/publish-setup/SKILL.md:46-52
Release Workflow and Pipeline
The pubm pipeline follows a strict sequence of tasks designed for reliability. This flow is consistent whether running in a local TTY environment or a headless CI environment.
Pipeline Stages
- Preflight Checks: Validates branch state, working tree cleanliness, and remote synchronization.
- Registry Validation: Pings registries and verifies authentication tokens/permissions before any changes occur.
- Build & Test: Executes configured npm/cargo scripts to ensure project stability.
- Version Bump: Consumes changesets to update manifests and create git commits/tags.
- Publish: Simultaneously pushes packages to all detected registries.
- Post-Release: Pushes tags to GitHub and creates GitHub Releases.
Sources: README.md:88-100, packages/core/src/i18n/locales/en.json:11-133
Workflow Diagram
The following diagram illustrates the lifecycle of a single release command and the integrated rollback protection.
The diagram shows the linear progression of a release and the critical branch to a rollback state upon failure.
Sources: README.md:88-102, CLAUDE.md:7-10
Versioning and Changesets
pubm utilizes a changeset-based workflow to manage versioning, particularly in monorepos. Changesets are small markdown files stored in .pubm/changesets/ that describe a change and its impact (patch, minor, or major).
Changeset Interaction
Users interact with changesets through specific CLI commands:
pubm init: Initializes the changeset directory and GitHub Action workflows.pubm changesets add: Interactively creates a new changeset file.pubm changesets version: Consumes pending changesets to calculate and apply new versions to manifests.
Sources: website/public/INFORMATION.md:14-19, plugins/pubm-plugin/skills/publish-setup/SKILL.md:149-165
Versioning Strategies
| Strategy | Description |
|---|---|
| Fixed | All packages in the workspace share the same version number. |
| Independent | Each package is versioned separately based on its own changesets. |
| Linked Groups | Groups of packages that are bumped together even if only one changed. |
Sources: plugins/pubm-plugin/skills/publish-setup/references/config-examples.md:46-60, README.md:60-63
Configuration and Extensibility
While pubm supports zero-config operation, a pubm.config.ts file can be used to override auto-detection or integrate plugins.
Configuration Options
The defineConfig helper provides type safety for the following key areas:
// Example from pubm.config.ts
import { defineConfig } from 'pubm'
export default defineConfig({
versioning: 'independent',
branch: 'main',
packages: [
{ path: 'packages/core', registries: ['npm', 'jsr'] }
],
plugins: []
})
Sources: plugins/pubm-plugin/skills/publish-setup/references/config-examples.md:21-44
Plugin System
The plugin system allows developers to hook into the release pipeline at various stages. Official plugins include:
- externalVersionSync: Syncs versions to non-manifest files like READMEs or source constants.
- brewTap / brewCore: Automates the update of Homebrew formulae upon release.
Sources: plugins/pubm-plugin/skills/publish-setup/references/official-plugins.md:3-15
Security and Privacy
pubm prioritizes security by using native OS mechanisms for token storage.
- Token Storage: Tokens are stored in the OS native keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service) using
@napi-rs/keyring. - Encryption: If a native keychain is unavailable, an AES-256-CBC encrypted fallback is used at
~/.pubm/. - Environment Variables:
PUBMalways prioritizes environment variables (likeNODE_AUTH_TOKENorJSR_TOKEN) over stored tokens, which is essential for CI environments.
Sources: README.md:111-125, website/public/INFORMATION.md:35-39
Summary
pubm serves as a robust release orchestrator that bridges the gap between different package ecosystems. By providing zero-config detection, mandatory preflight checks, and a reliable rollback system, it minimizes the risks associated with publishing complex, multi-package projects. Its integration with changesets and a flexible plugin architecture makes it suitable for projects ranging from single-package libraries to large-scale, multi-language monorepos.