agentleFS
wyattjohwyattjoh/skills/skills/release-please/SKILL.md

release-please

Skill3 starsChanged 47 days agoMITView on GitHub

Configure, operate, and debug release-please. Triggers on "release-please", "force version bump", "force release", "Release-As", "force-run label", "skip release", "release PR stale", "tag didn't fire", "trigger release", "bump version".

  • Reads credentials
  • Commits and pushes

3 other projects use a version of this.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

17 rules. 0 are common, 5 are distinctive, and 12 are very specific to this project.

  • 0

    Common

    Most of the 3 edited versions we read keep these.

  • 5

    Distinctive

    This author's own choices. Worth a look.

  • 12

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Always fetch current documentation: before configuring release-please.

    line 14
  2. Very specific:

    Use WebFetch on these URLs to get current documentation before proceeding.

    line 22
  3. Distinctive:

    Read the project's manifest file to determine:

    line 40
  4. Distinctive:

    Monorepo or single package: Check for workspaces, multiple package dirs

    line 45
  5. Very specific:

    Pre-1.0 projects: add "bump-minor-pre-major": true so a breaking change bumps minor (0.2.0 -> 0.3.0) instead of cutting 1.0.0.

    line 66
  6. Very specific:

    Read .github/workflows/ for existing publish/release workflows.

    line 70
  7. Distinctive:

    Publish on push to main: Should be changed to publish conditionally via release-please.

    line 72
  8. Distinctive:

    No existing workflow: Create a single release workflow with both jobs.

    line 74
  9. Very specific:

    Deno: Add "exclude": ["CHANGELOG.md"] to the fmt section in deno.json

    line 173
  10. Very specific:

    Prettier: Add CHANGELOG.md to .prettierignore

    line 174
  11. Very specific:

    ESLint: Add CHANGELOG.md to .eslintignore or ignorePatterns

    line 175
  12. Very specific:

    If the project has an existing publish workflow triggered on push: main:

    line 179
  13. Very specific:

    Remove the push trigger (publishing now runs inside the release workflow).

    line 181
  14. Very specific:

    Use extra-files with jsonpath to keep version in sync across deno.json, plugin manifests, README badges, etc:

    line 212
  15. Very specific:

    Remove release-as after the release is cut, or every subsequent PR keeps forcing 2.0.0.

    line 297
  16. Very specific:

    Use ! after the type, or add a BREAKING CHANGE: (or BREAKING-CHANGE:) footer:

    line 324
  17. Very specific:

    Per-commit: use a non-releasable type (chore:, docs:, ci:, style:, test:, refactor:, build:).

    line 353

“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Release-Please Setup

Configures release-please in a project for automated version bumping, changelog generation, GitHub releases, and optional registry publishing.

Before You Start

Always fetch current documentation before configuring release-please. The action and config schema evolve across versions.

Use WebFetch on these URLs to get current documentation before proceeding.

Action version pin: @v5 (Apr 2026) and @v4 are both usable. v5 only changes the runner runtime from Node 20 to Node 24 (no input/output changes). v4 received library bumps through v4.4.1 (2026-02-20, bundling release-please v17.3.0) and is the safer pin for self-hosted runners that haven't upgraded to Node 24, but no v4 release has shipped since v5.0.0, so treat "still maintained" as provisional and check for a newer v4 tag before relying on it. Avoid @v3: its last release was v3.7.13 (Nov 2023), it runs on Node 16, and it predates the config-file-only manifest model (v4 removed most per-input configuration in favor of release-please-config.json). Both release_created (root) and releases_created (aggregate) outputs exist in v3 and v4 alike; the split is root-vs-aggregate, not a version difference.

Library version: release-please-action v5.0.0 is the latest action release and bundles release-please library v17.6.0. The latest published library is v17.11.2 (see the release-please CHANGELOG), several minor versions ahead of what v5.0.0 bundles. Last verified 2026-10-05. Check the action's own package-lock.json at your pinned tag if you need the exact bundled version.

Quick Start

  1. Detect project type (package.json, deno.json, Cargo.toml, pyproject.toml, etc.)
  2. Check for existing release workflows in .github/workflows/
  3. Create release-please config files at project root
  4. Create or update the release workflow (single workflow containing release + publish jobs)
  5. Verify the project uses conventional commits (check git log)

Detailed Workflow

Step 1: Detect Project Type and Registry

Read the project's manifest file to determine:

  • Language/ecosystem: Node (npm), Deno (JSR), Rust (crates.io), Python (PyPI), Go, etc.
  • Package name: From the manifest (package.json name, deno.json name, etc.)
  • Current version: From the manifest
  • Monorepo or single package: Check for workspaces, multiple package dirs

Map to the correct release-type:

Ecosystemrelease-typeVersion file
Node.js (npm)nodepackage.json
Deno (JSR)nodeUse extra-files with jsonpath for deno.json
RustrustCargo.toml
Pythonpythonpyproject.toml or setup.py
GogoNo version file (tag-based)
Simple/othersimpleversion.txt

For Deno/JSR projects, use release-type: node with extra-files to update deno.json:

{
  "extra-files": [{ "type": "json", "path": "deno.json", "jsonpath": "$.version" }]
}

Pre-1.0 projects: add "bump-minor-pre-major": true so a breaking change bumps minor (0.2.0 -> 0.3.0) instead of cutting 1.0.0. On 0.x, feat: already bumps minor and fix: bumps patch by default; add "bump-patch-for-minor-pre-major": true only if feat: should bump patch while pre-1.0.

Step 2: Check Existing Workflows

Read .github/workflows/ for existing publish/release workflows. Common patterns:

  • Publish on push to main: Should be changed to publish conditionally via release-please.
  • Publish on release event: Can be kept as a manual fallback, but will not auto-fire from release-please (see Gotchas).
  • No existing workflow: Create a single release workflow with both jobs.

Step 3: Create Config Files

release-please-config.json (project root):

{
  "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
  "packages": {
    ".": {
      "package-name": "<package-name>",
      "release-type": "<type>",
      "extra-files": []
    }
  }
}

For monorepos, add each package under packages with its relative path as the key. See references/monorepo.md.

.release-please-manifest.json (project root):

{ ".": "<current-version>" }

Bootstrap with the current version from the project manifest. For projects with pre-existing history that doesn't match release-please's expectations, see references/first-release-bootstrap.md.

Step 4: Create GitHub Actions Workflow

The publish job MUST live in the same workflow file as release-please. A separate workflow triggered by on: release will not fire because GitHub prevents GITHUB_TOKEN-created events from triggering other workflows.

name: Release Please

on:
  push:
    branches:
      - main

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: false

jobs:
  release-please:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      issues: write
      pull-requests: write
    outputs:
      releases_created: ${{ steps.release.outputs.releases_created }}
      tag_name: ${{ steps.release.outputs.tag_name }}
    steps:
      - uses: googleapis/release-please-action@v4
        id: release
        with:
          token: ${{ secrets.GITHUB_TOKEN }}

  publish:
    needs: release-please
    if: ${{ needs.release-please.outputs.releases_created == 'true' }}
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write # Required for OIDC (npm provenance, JSR)
    steps:
      - uses: actions/checkout@v4
      # Add setup, quality checks, and publish steps here

Step 5: Add CI Workflow for PRs

Release-please PRs created with GITHUB_TOKEN do not trigger pull_request workflows automatically. A CI workflow on PRs is still valuable for human-authored PRs:

name: CI

on:
  pull_request:
    branches:
      - main

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      # Add linting, type checking, test steps

Because release PRs skip this workflow, repeat the same quality checks inside the publish job before the actual publish step.

Step 6: Handle Formatter Conflicts

Release-please generates CHANGELOG.md with its own formatting (e.g., * for list markers). If the project uses a formatter that enforces different conventions, exclude CHANGELOG.md from formatting:

  • Deno: Add "exclude": ["CHANGELOG.md"] to the fmt section in deno.json
  • Prettier: Add CHANGELOG.md to .prettierignore
  • ESLint: Add CHANGELOG.md to .eslintignore or ignorePatterns

Step 7: Update Existing Publish Workflows

If the project has an existing publish workflow triggered on push: main:

  1. Remove the push trigger (publishing now runs inside the release workflow).
  2. Optionally keep release: types: [published] as a manual fallback (it will not auto-fire from release-please, but works for gh release create).

Common Patterns

OIDC-Authenticated Publishing

JSR supports OIDC out of the box. npm requires enabling Trusted Publishing (GA 2025-07-31) per-package on npmjs.com first, linking the org/repo/workflow filename, plus npm CLI >= 11.5.1 and Node.js >= 22.14.0 in the runner. Once configured, a plain npm publish authenticates via OIDC and attaches provenance automatically; --provenance alone does not replace the need for a token without Trusted Publishing configured, since it only adds a build attestation, not authentication. Skip long-lived API tokens entirely once set up:

permissions:
  contents: read
  id-token: write
steps:
  - uses: actions/checkout@v4
  # npm with Trusted Publishing configured on npmjs.com:
  - run: npm publish --access public
  # OR JSR:
  - run: deno publish

No NPM_TOKEN or JSR auth secret required. See references/token-strategy.md for when OIDC is insufficient.

Syncing Version Across Multiple Files

Use extra-files with jsonpath to keep version in sync across deno.json, plugin manifests, README badges, etc:

{
  "extra-files": [
    { "type": "json", "path": "deno.json", "jsonpath": "$.version" },
    { "type": "json", "path": "plugin.json", "jsonpath": "$.version" },
    { "type": "json", "path": "plugin.json", "jsonpath": "$.mcpServers[*].version" }
  ]
}

Supported types: json, yaml, toml, xml, pom, generic (regex-based). See manifest-releaser.md for full syntax.

Floating Major-Version Tag

Consumers of reusable GitHub Actions often pin to @v1. Maintain a floating major tag with a post-release job:

major-tag:
  needs: release-please
  if: ${{ needs.release-please.outputs.releases_created == 'true' }}
  runs-on: ubuntu-latest
  permissions:
    contents: write
  steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0
    - name: Update major version tag
      env:
        TAG: ${{ needs.release-please.outputs.tag_name }}
      run: |
        MAJOR=$(echo "$TAG" | sed -E 's/^v?([0-9]+).*/v\1/')
        git tag -f "$MAJOR" "$TAG"
        git push origin "$MAJOR" --force

Concurrency Control

Prevent overlapping release runs when multiple commits land in quick succession:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: false # Let in-flight releases finish rather than kill them

Downstream Post-Release Updates

Common need: after release, update a Homebrew tap, docs site, catalog, Docker Hub, etc. See references/downstream-updates.md for the general pattern. Short version: GITHUB_TOKEN cannot cross repo boundaries; use a PAT or GitHub App token.

Binary Release Artifacts

For projects that ship compiled binaries (Go, Rust, Deno compile, Bun compile), see references/binary-artifacts.md for the multi-target build + checksum + release upload pattern.

Manual Overrides

Day-to-day, you'll often need to force a version bump, skip a release, or recover from a stuck release pipeline. Release-please supports several override mechanisms; pick the most local one for the job.

Force a specific version

Via commit footer (most common, no config change):

chore: release 2.0.0

Release-As: 2.0.0

Or as an empty commit:

git commit --allow-empty -m "chore: release 2.0.0" -m "Release-As: 2.0.0"
git push

The footer is case-insensitive (Release-As: / release-as:). When present, release-please uses the footer value instead of computing a bump from commits.

Via config field (sticky until removed):

{ "packages": { ".": { "release-as": "2.0.0" } } }

Remove release-as after the release is cut, or every subsequent PR keeps forcing 2.0.0.

Via action input (added in release-please-action@v4.4.0):

- uses: googleapis/release-please-action@v4
  with:
    release-as: 2.0.0

Useful when paired with workflow_dispatch for ad-hoc releases triggered from the GitHub UI. Caveat: the action only honors the release-as (and versioning-strategy) inputs when the release-type input is also set (config-less mode). In manifest mode (release-please-config.json), both inputs are ignored; use the commit footer or the config field instead (source).

Force a bump direction (always-bump-*)

versioning-strategy overrides Conventional Commits parsing entirely. versioning-strategy is the GitHub Action input name (added in v4.4.0, and honored only when the release-type input is also set, not in manifest mode); the equivalent config-file field is versioning (e.g. { "packages": { ".": { "versioning": "always-bump-minor" } } }); both accept the same enum values:

StrategyEffect
defaultConventional Commits (feat -> minor, fix -> patch, ! -> major)
always-bump-patchEvery release is a patch bump
always-bump-minorEvery release is a minor bump
always-bump-majorEvery release is a major bump
service-packIncrements the patch suffix (for service-pack release lines)
prereleaseBumps the prerelease identifier

Force a major bump from a single commit

Use ! after the type, or add a BREAKING CHANGE: (or BREAKING-CHANGE:) footer:

feat!: rename `foo` to `bar`

Or:

feat: rename `foo` to `bar`

BREAKING CHANGE: `foo` is now `bar`

For pre-1.0 projects, a breaking change bumps to 1.0.0 by default. Set "bump-minor-pre-major": true to bump minor instead. "bump-patch-for-minor-pre-major": true is separate: it makes feat: bump patch while pre-1.0.

Force release-please to re-run

If a release PR didn't open after qualifying commits, or didn't tag after merge, re-run the failed (or latest) release-please workflow run; for the action, this is the upstream-documented fix. The release-please:force-run label only applies to the Release Please GitHub App: the action does not watch labels, and adding one does not trigger a push workflow. Also check older, already-released PRs for a stale autorelease: pending (or autorelease: triggered) label; remove it, then re-run.

You can also push an empty commit to kick the workflow:

git commit --allow-empty -m "chore: trigger release-please"
git push

Skip a release

  • Per-commit: use a non-releasable type (chore:, docs:, ci:, style:, test:, refactor:, build:). These are excluded from version bumps by default.
  • Per-workflow run: set skip-github-release: true and/or skip-github-pull-request: true on the action.
  • Skip changelog only (cut the release tag, don't touch CHANGELOG): "skip-changelog": true in config (release-please v17.1+).

Skip CI labeling

Set skip-labeling: true on the action (added in v4.2.0) if branch protection rules or repo policies make the auto-applied labels (autorelease: pending, autorelease: tagged) inconvenient. The state machine still works because release-please reads commit + PR metadata too. Recovery for action users is re-running the workflow either way, since the force-run label only applies to the GitHub App.

Prereleases

Alpha, beta, rc, and custom prerelease identifiers are a dedicated topic. See references/prereleases.md.

Troubleshooting

The single most useful debugging signal is the PR label: autorelease: pending vs autorelease: tagged. Pending means the release PR exists and is awaiting merge. Tagged means the release has been cut (post-merge state).

SymptomLikely causeFix
No release PR createdNo qualifying commits since last release (all docs:/chore:/ci:)Check git log since last tag. Add a feat: or fix:.
No release PR despite qualifying commitsBranch protection blocks GITHUB_TOKEN PRsAllow Actions to open PRs in repo settings (Settings > Actions > General).
Release PR stale / state machine stuckRace or transient API failure left release-please mid-stateRemove any stale autorelease: pending label from an already-released PR, then re-run the workflow.
Tag wasn't created after release PR mergeRelease-please missed the tag step (workflow killed, API timeout, label mishap)Check for a stale autorelease: pending label, then re-run the workflow (add workflow_dispatch: if needed).
0.x project jumped to 1.0.0Breaking change without bump-minor-pre-majorAdd the flag.
Release PR shows stale forced versionOld release-as still in configRemove after use.
Tag format wrong (missing v, missing component)Missing include-v-in-tag or component configSee customizing docs.
Release PR merged but no GitHub releaseWorkflow failed after release-please step, or skip-github-release: trueCheck workflow run logs.
Publish job didn't run on mergeWrong output name in if:v4 manifest mode uses releases_created (plural).
Version in manifest but not in extra-files targetWrong type or jsonpathTest jsonpath against the file; json type requires valid JSON.
Release PR body shows old version/changelogPR description stale after force-push; the release branch has the correct contentInspect the release branch's CHANGELOG.md directly, not the PR body.
Cannot manually rerun the release workflowNo workflow_dispatch: triggerAdd workflow_dispatch: to the workflow's on: block.
New fix: commit not in the open release PRRelease-please folds new commits into the in-flight PR on the next workflow runExpected behavior. Wait for the next push to main, or push an empty commit to force a refresh.

Gotchas

  1. GITHUB_TOKEN releases don't trigger other workflows. The publish job MUST live in the same workflow file as release-please. A separate publish.yml with on: release will not fire from release-please automation.

    Caveat: on: release does fire for manually-created releases (via gh release create or the GitHub UI). A few projects rely on this for a one-time bootstrap, then depend on in-workflow publish thereafter. This is fragile; prefer the unified-workflow approach unless there's a compelling reason.

    Workaround when chaining is required: Pass a PAT or GitHub App token to the action's token: input. Events from those identities do trigger downstream workflows. See token-strategy.md § Bypassing the GITHUB_TOKEN Trigger Limit.

  2. Release-please PRs don't trigger PR workflows. Pushes made with GITHUB_TOKEN don't create pull_request events. Repeat quality checks inside the publish job.
  3. Formatter conflicts with CHANGELOG.md. Release-please uses * for list items. Most formatters rewrite to -. Exclude CHANGELOG.md from formatting or CI will fail.
  4. Deno projects use node release-type, not simple. simple only manages version.txt. node generates proper changelogs. Use extra-files with jsonpath for deno.json.
  5. After merging a release PR, pull locally. The PR modifies the manifest and CHANGELOG.md. Pull before pushing new commits.
  6. Conventional commits are required. feat: = minor, fix: = patch, feat!: or BREAKING CHANGE: = major. Default releasable types are feat, fix, and deps (source: release-please README, "Release Please bot does not create a release PR", verified 2026-10-05; the README lists these three prefixes explicitly and does not include perf). Everything else (chore, build, docs, style, test, ci, refactor, perf) is non-releasable by default; customize via changelog-sections.
  7. The config JSON schema lags reality. Upstream tracks this in release-please#2518. Verify config field support against the library version your action pin bundles, not against the schema alone.

Known Upstream Issues (verify if affected)

The three linked issues are open upstream; last verified 2026-10-01. Re-check before recommending workarounds.

  • separate-pull-requests: true with Go monorepos can fail with "A pull request already exists" on release-please library v17.6.0. Confirmed open as release-please#2773 (opened 2026-05-09, explicitly reproduces on v17.6.0). No action release avoids it: the issue also reproduces on library v17.3.0 (bundled by action v4.4.1), and no v4.x release bundles v17.5.x. If affected, use separate-pull-requests: false until upstream ships a fix.
  • include-commit-authors (v17.5.0) is a no-op: author metadata is dropped. Tracked as release-please#2761 (P2); a fix, PR #2892, exists but is unmerged.
  • chore(deps) commits are recognized by the dependency manifest plugin but don't trigger releases. Use fix(deps): to trigger a patch release from a dependency bump. Confirmed open as release-please#2764 (P2, "DependencyManifest recognizes chore(deps) commits but never releases them").
  • Label-application races: occasional 422s when release-please tries to label a freshly created PR. Workflow retry usually clears it. No upstream issue tracks this.

References

Focused reference docs:

  • First-release bootstrap: Adopting release-please in a project with existing history.
  • Monorepo setup: Multi-package configs, separate-pull-requests, linked versions.
  • Downstream updates: Post-release jobs that touch other repos.
  • Binary artifacts: Multi-target compile + checksum + release upload.
  • Token strategy: GITHUB_TOKEN vs OIDC vs PAT vs GitHub App token.
  • Prereleases: Alpha/beta/rc configurations.

Upstream:

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.