bumpp

repository·main·Indexed 21 days ago

https://github.com/antfu-collective/bumpp

A tool for automating package version bumping, supporting monorepos, conventional commits, and a Pull Request-based release workflow. It allows users to bump versions, commit changes, tag, and push to Git, with support for custom configuration via bump.config.ts and integration with GitHub Actions for automated publishing.

Tokens
9.6K
Snippets
33
Records
44
Agent score
75%

What's inside bumpp

  1. Overview of bumpp

    main

    bumpp is a tool for bumping package versions, designed as a fork of version-bump-prompt. It is optimized for modern workflows, supporting monorepos, conventional commits, and ESM/CJS.

    Key features include:

    • Direct usage via npx bumpp.
    • Support for monorepos with the -r or --recursive flag.
    • Automatic use of preid when available.
    • Default enablement of --commit, --tag, and --push (can be opted-out via --no-push, etc.).
    • Support for a bump.config.ts configuration file.
    • Ability to execute custom commands or functions via --execute before committing.
  2. Use template tokens in bumpp

    main

    When customizing commit messages, tags, or pull request details, you can use named tokens to inject version information. This is the recommended way to format release metadata.

    Available Tokens:

    • {version}: The new version number (e.g., 1.2.3)
    • {oldVersion}: The previous version number (e.g., 1.2.2)
    • {tag}: The formatted tag name (e.g., v1.2.3)
    • {releaseType}: The release type (e.g., patch, minor, major; empty for explicit versions)
    • {major}: The major segment of the new version
    • {minor}: The minor segment of the new version
    • {patch}: The patch segment of the new version
    • {date}: The current date in YYYY-MM-DD format

    Note: The legacy %s placeholder is soft-deprecated. If a template contains any named tokens, %s substitution is disabled.

    bumpp --commit "chore: release {tag}" --tag "{version}"
  3. Release via a Pull Request using --pr

    main

    For teams requiring code review and branch protection, use the --pr flag. Instead of pushing directly to main, bumpp --pr drives the release through a Pull Request workflow.

    Workflow steps:

    1. Validates that the working tree is clean, you are on the base branch, and you are not behind the remote.
    2. Creates a release branch (default: release/v{version}).
    3. Bumps the version and runs the execute script.
    4. Commits the bump (no local tag is created; tags are created by CI after merge).
    5. Pushes the branch and switches you back to your original branch.
    6. Attempts to open a PR via the gh CLI (use --yes to automate).

    Important: The release/ branch prefix is used by CI to recognize release PRs. Do not change this prefix unless you also update your CI configuration.

    bumpp --pr
  4. Set up GitHub Actions for PR-based releases

    main

    To automate publishing after a release PR is merged, use a GitHub Actions workflow. This workflow reacts to pull_request events being closed and checks if they were merged.

    Security Requirements for the Workflow:

    • Use pull_request, not pull_request_target, to ensure the workflow runs code from your default branch.
    • Include a check github.event.pull_request.head.repo.full_name == github.repository to prevent forks from triggering the workflow.
    • Ensure the branch name starts with release/.
    • Use contents: write and id-token: write permissions.

    Workflow Logic:

    1. Checks if the PR was merged and originated from the local repo.
    2. Checks out the merge commit (not the PR head) to ensure package.json has the bumped version.
    3. Creates a Git tag based on the version found in package.json.
    4. Generates release notes using changelogithub.
    5. Publishes to npm using OIDC trusted publishing (requires npm CLI >= 11.5.1).
    # .github/workflows/release-pr.yml
    name: Release (PR merged)
    
    on:
      pull_request:
        types: [closed]
    
    jobs:
      release:
        if: >-
          github.event.pull_request.merged == true &&
          github.event.pull_request.head.repo.full_name == github.repository &&
          startsWith(github.event.pull_request.head.ref, 'release/')
        runs-on: ubuntu-latest
        permissions:
          contents: write
          id-token: write
        steps:
          - uses: actions/checkout@v5
            with:
              ref: ${{ github.event.pull_request.merge_commit_sha }}
              fetch-depth: 0
    
          - uses: actions/setup-node@v5
            with:
              node-version: 22
              registry-url: https://registry.npmjs.org
    
          - name: Read version
            id: version
            run: echo "version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"
    
          - name: Create tag
            uses: actions/github-script@v8
            with:
              script: |
                await github.rest.git.createRef({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  ref: `refs/tags/v${{ steps.version.outputs.version }}`,
                  sha: context.payload.pull_request.merge_commit_sha,
                })
    
          - run: npm ci
          - run: npm run build --if-present
          - run: npx changelogithub
            env:
              GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          - run: npm publish
  5. Use template tokens for commit messages and tags

    main

    When configuring bumpp templates (such as commit messages, tag names, or pull request titles/bodies), you can use named placeholders wrapped in curly braces {token}. These tokens are automatically replaced with versioning information during the release process.

    Available Tokens

    TokenDescription
    versionThe new version number (e.g., 1.2.3)
    oldVersionThe previous version number (e.g., 1.2.2)
    tagThe formatted tag name (e.g., v1.2.3)
    releaseTypeThe type of release: major, minor, patch, or prerelease (empty for explicit versions)
    majorThe major segment of the new version (e.g., 1)
    minorThe minor segment of the new version (e.g., 2)
    patchThe patch segment of the new version (e.g., 3)
    dateThe current date in YYYY-MM-DD format

    Examples

    • "chore: release {tag}" becomes "chore: release v1.2.3"
    • "release/v{version}" becomes "release/v1.2.3"
    "chore: release {tag}" -> "chore: release v1.2.3"
    "release/v{version}"   -> "release/v1.2.3"
  6. How the Pull Request release flow works

    main

    The pr release mode automates the creation of a release branch and a subsequent Pull Request. The lifecycle follows these steps:

    1. Precondition Check: The tool verifies the working tree is clean, you are on the correct base branch, and your local base branch is not behind its remote.
    2. Branch Creation: A new release branch is created using the branch template. If the branch already exists locally or on origin, the tool will prompt to recreate and force-push it.
    3. Version Bump & Commit: (Handled by the core engine) The version is bumped and a commit is made.
    4. Push & Cleanup: The release branch is pushed to origin, and the tool returns you to your original branch.
    5. PR Creation: If the GitHub CLI (gh) is installed and authenticated, the tool automatically creates the Pull Request with the specified title, body, and draft status. If gh is unavailable, it prints manual instructions and a direct URL to create the PR via your browser.
  7. Configure file selection and workspace behavior

    main

    By default, bumpp targets specific files like package.json, package-lock.json, jsr.json, etc.

    Recursive Mode If the recursive option is enabled and no specific files are provided, bumpp will automatically detect and include package.json files from:

    • The current directory.
    • Monorepo workspaces (detected via pnpm-workspace.yaml, or the workspaces field in package.json).

    Manual Selection You can provide a specific list of files via the files option to override defaults.

  8. Customize the Pull Request body

    main

    The PR body can be generated in three ways:

    1. Default: If no body is provided, bumpp generates a body based on conventional commits. It groups commits into sections: Breaking Changes first, then follows the order: feat (Features), fix (Bug Fixes), perf (Performance), refactor (Refactors), docs (Documentation), build (Build), types (Types), test (Tests), style (Styles), ci (CI), chore (Chores), revert (Reverts), and finally Other Changes. Each line follows the format: - [scope]: description (PR-refs) (short-hash).
    2. String Template: Provide a string using TemplateTokens (e.g., body: 'Release v${version}').
    3. Function: Provide a function that receives TemplateTokens to programmatically construct the body.

    Available TemplateTokens:

    • tag: The git tag being created.
    • oldVersion: The previous version.
    • version: The new version.
  9. How bumpp determines the next version

    main

    bumpp calculates the next version number based on the specified release type and the project's commit history. It supports several release strategies:

    • major, minor, patch: Standard SemVer increments.
    • next: If the current version is a pre-release, it increments the pre-release identifier. Otherwise, it performs a patch bump.
    • conventional: Uses conventional commits to determine the bump type:
      • breaking change $\rightarrow$ major bump.
      • feat type $\rightarrow$ minor bump.
      • All other changes $\rightarrow$ patch bump.
    • prepatch, preminor, premajor: Increments the version and adds/updates a pre-release identifier.
    • version: Uses a specific version string provided by the user.
    • prompt: Interactively asks the user to choose a release type or enter a custom version.
    • none: Keeps the version as-is.
  10. Configure bumpp via bump.config.ts

    main

    You can provide fine-grained control over bumpp behavior using a bump.config.ts file. This is especially useful for customizing the Pull Request (PR) behavior.

    import { defineConfig } from 'bumpp'
    
    export default defineConfig({
      pr: {
        branch: 'release/v{version}', // release branch name template
        base: 'main', // PR base branch (defaults to origin/HEAD)
        title: 'chore: release {tag}', // defaults to the release commit message
        body: '{oldVersion} → {version}', // template string, or a function receiving the tokens
        draft: false, // open the PR as a draft
      },
    })
  11. Legacy %s placeholder behavior

    main

    If a template does not contain any named {token} placeholders, bumpp falls back to a legacy %s behavior:

    1. If the template contains %s, all occurrences of %s are replaced with the new version number.
    2. If the template does not contain %s, the new version number is appended to the end of the string.

    Note: The %s style is soft-deprecated. It is recommended to use named tokens like {version} instead.

  12. Configure release types in bumpp

    main

    The release option determines how the version is updated. It supports three modes:

    1. Prompt: Interactive mode where the user is asked for the version number. This requires an active input/output interface.
    2. Bump: Relative updates based on a ReleaseType (e.g., patch, minor, major). You can also specify a preid (defaulting to beta) for pre-releases.
    3. Version: A specific, absolute version string.

    Note: If release is set to 'prompt', the preid is used as a fallback if not otherwise specified.

    // Example configurations for different release modes
    
    // 1. Prompting for version
    { release: 'prompt' }
    
    // 2. Bumping a specific type
    { release: 'patch', preid: 'alpha' }
    
    // 3. Setting an absolute version
    { release: '1.2.3' }