Skip to content

dmno-dev/bumpy

Repository files navigation

Bumpy banner


npm package license build status discord chat


@varlock/bumpy 🐸

A modern package versioning and changelog generation tool β€” built for monorepos (works great in single packages too).

How It Works

Bumpy uses bump files (you may know them as "changesets" if coming from that tool) β€” small markdown files that declare which packages changed and how (patch/minor/major), along with a description that ends up in changelogs. Developers create these files as part of their PRs. As PRs merge to the base branch, a "release PR" is kept up to date showing what packages will be released and their changelogs β€” including packages bumped automatically due to dependency relationships. When the release PR is merged, bump files are consumed (deleted), and packages are published with updated versions and changelogs.

Example bump file

.bumpy/add-user-language.md:

---
'@myorg/core': minor
'@myorg/utils': patch
---

Added user language preference to the core config.
Fixed locale fallback logic in utils.

The typical CI driven workflow is:

  1. bumpy add β€” developers create bump files as part of their PRs
  2. bumpy ci check β€” CI comments on each PR with a release plan preview
  3. bumpy ci release β€” on merge to main, CI opens a "Version Packages" PR that bumps versions and updates changelogs. When that PR is merged, it publishes packages.

All of this is automated via two simple GitHub Actions workflows (see CI setup below). You can also run everything locally with bumpy status, bumpy version, and bumpy publish.

Features

  • All package managers β€” npm, pnpm, yarn, and bun workspaces
  • Smart dependency propagation β€” configurable rules for how version bumps cascade through your dependency graph (see version propagation docs)
  • Pack-then-publish β€” by default, publishes to npm (resolving workspace: and catalog: protocols, with OIDC/provenance support). Per-package custom publish commands let you target anything β€” VSCode extensions, Docker images, JSR, private registries, etc.
  • Flexible package management β€” include/exclude any package individually via per-package config, glob patterns, or privatePackages setting
  • Non-interactive CLI β€” bumpy add works fully non-interactively for CI/CD and AI-assisted development
  • Aggregated GitHub releases β€” optionally create a single consolidated release instead of one per package
  • Conventional commits bridge β€” bumpy generate auto-creates bump files from conventional commit messages
  • Pluggable changelog formatters β€” built-in "default" and "github" formatters, or write your own
  • Zero runtime dependencies β€” dependencies are minimal and bundled at release time

Getting Started

# Install
bun add -d @varlock/bumpy  # or npm/pnpm/yarn

# Initialize (creates .bumpy/ config directory)
bumpy init

# Create a bump file
bumpy add

# Preview the release plan
bumpy status

Then set up CI to automate versioning and publishing (see below).

CI / GitHub Actions

No separate action to install β€” just call bumpy ci directly in your workflows. Two commands handle the entire release lifecycle:

  • bumpy ci check β€” runs on every PR. Computes the release plan from pending bump files and posts/updates a comment on the PR showing what versions would be released. Warns if any changed packages are missing bump files.
  • bumpy ci release β€” runs on push to main. If pending bump files exist, it opens (or updates) a "Version Packages" PR that applies all version bumps and changelog updates. If the current push is the Version Packages PR being merged, it publishes the new versions, creates git tags, and creates GitHub releases.

PR check workflow

# .github/workflows/bumpy-check.yml
name: Bumpy Check
on: pull_request

jobs:
  check:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
    steps:
      - uses: actions/checkout@v6
      - uses: oven-sh/setup-bun@v2
      - run: bun install
      - run: bunx @varlock/bumpy ci check
        env:
          GH_TOKEN: ${{ github.token }}

Release workflow

# .github/workflows/bumpy-release.yml β€” trusted publishing (OIDC, no secret needed)
name: Bumpy Release
on:
  push:
    branches: [main]

jobs:
  release:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
      id-token: write # required for npm trusted publishing (OIDC)
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0
      - uses: oven-sh/setup-bun@v2
      - uses: actions/setup-node@v6
        with:
          node-version: lts/*
      - run: bun install
      - run: bunx @varlock/bumpy ci release
        env:
          GH_TOKEN: ${{ github.token }}

Trusted publishing setup: Configure each package on npmjs.com β†’ Package Settings β†’ Trusted Publishers β†’ GitHub Actions. Specify your org/user, repo, and the workflow filename (bumpy-release.yml). No NPM_TOKEN secret needed. Requires npm >= 11.5.1 β€” bumpy will warn if your version is too old.

Alternative: token-based auth (NPM_TOKEN secret)
# .github/workflows/bumpy-release.yml β€” token-based auth
name: Bumpy Release
on:
  push:
    branches: [main]

jobs:
  release:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0
      - uses: oven-sh/setup-bun@v2
      - run: bun install
      - run: bunx @varlock/bumpy ci release
        env:
          GH_TOKEN: ${{ github.token }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

You can also use bumpy ci release --auto-publish to version + publish directly on merge without the intermediate PR.

Token setup

The default github.token works for basic functionality, but GitHub's anti-recursion guard means PRs created by the default token won't trigger other workflows β€” so your regular CI (tests, linting, etc.) won't run automatically on the Version Packages PR. To fix this, provide a BUMPY_GH_TOKEN secret using either a fine-grained PAT or a GitHub App token. See the full token setup guide for details.

Run bumpy ci setup for interactive guidance, or set it up manually:

  1. Create a fine-grained personal access token with:
    • Repository access: your repo only
    • Permissions: Contents (read & write), Pull requests (read & write)
  2. Add it as a repository secret named BUMPY_GH_TOKEN
  3. Add it to your release workflow:
    - run: bunx @varlock/bumpy ci release
      env:
        GH_TOKEN: ${{ github.token }}
        BUMPY_GH_TOKEN: ${{ secrets.BUMPY_GH_TOKEN }}

Local versioning and publishing

If you prefer to version and publish locally instead of via CI:

bumpy version   # consume bump files, update versions and changelogs
bumpy publish   # pack and publish, create git tags, push tags, and create GitHub releases

AI Integration

Bumpy ships with an AI skill that teaches LLMs how to create bump files.

bumpy ai setup --target claude    # installs Claude Code plugin
bumpy ai setup --target opencode  # creates OpenCode command file
bumpy ai setup --target cursor    # creates Cursor rule file
bumpy ai setup --target codex     # creates Codex instruction file

The skill teaches the AI to examine git changes, identify affected packages, choose bump levels, and run bumpy add with the right arguments.

Documentation

Why files instead of conventional commits?

Tools like semantic-release infer version bumps from commit messages (feat: β†’ minor, fix: β†’ patch). This works for simple projects but breaks down in monorepos β€” a single PR often touches multiple packages with different bump levels, squash merges lose per-commit metadata, and commit messages are a poor place to write user-facing changelog entries. Bump files are explicit, reviewable in the PR diff, and can describe changes in language meant for consumers rather than developers. If you prefer conventional commits, bumpy generate can bridge the gap by auto-creating bump files from commit history.

Why not just use changesets?

Bumpy is built as a successor to @changesets/changesets. Changesets is mature and widely adopted, but has stagnated β€” hundreds of open issues around core design problems that are unlikely to be fixed without a rewrite. See DIFFERENCES_FROM_CHANGESETS.md for a detailed comparison with links to specific issues. The biggest pain points bumpy addresses:

  • Sane dependency propagation β€” changesets hardcodes aggressive behavior where a minor bump triggers a major bump on all peer dependents. Bumpy uses a three-phase algorithm with sensible defaults and full configurability.
  • Workspace protocol resolution β€” changesets uses npm publish even in pnpm/yarn workspaces, so workspace:^ and catalog: protocols are NOT resolved, resulting in broken published packages.
  • Custom publish commands β€” changesets is hardcoded to npm publish. Bumpy supports per-package custom publish for VSCode extensions, Docker images, JSR, etc.
  • Flexible package management β€” changesets treats all private packages the same. Bumpy lets you include/exclude any package individually.
  • CI without a separate action β€” just bunx @varlock/bumpy ci check in any workflow, no bot or action to install.
  • bumpy migrate β€” converts .changeset/ config and pending changeset files to .bumpy/.

Development

bun install
bun test
bun src/cli.ts --help

Roadmap

  • Prerelease mode (for now, use pkg.pr.new for preview packages)
  • Bun standalone binary for use outside of JS projects
  • Better support for versioning non-JS packages and usage without package.json files
  • Tracking workspace-level / non-publishable changes

About

🐸 Modern monorepo friendly version management + changelog tool

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors