Release Please
Practical guide for setting up and operating Release Please using
googleapis/release-please
and
googleapis/release-please-action
.
When to Use
Use this skill when you need:
- Automated version bumps + changelog from Conventional Commits
- GitHub release PR automation on /
- Monorepo or multi-package release orchestration (manifest mode)
- Migration from manual version/changelog/tag release workflows
Use single-package mode when one version stream exists.
Use manifest mode when multiple packages/paths version independently.
Prerequisites
1) Commit and branching hygiene
- Conventional Commits are required for accurate semver bumping and changelog sections.
- Protected default branch recommended ()
- CI must run on release PRs and direct pushes to default branch
2) Repository permissions and token strategy
Choose one and stay consistent:
- (simpler, default)
- PAT / GitHub App token (when cross-repo, stricter org policy, or release-trigger chaining is needed)
Minimum permissions for workflow job:
- (optional but useful for labeling/commenting behavior)
3) Required files (depending on mode)
Single-package (minimal):
.github/workflows/release-please.yml
Manifest mode (monorepo / multiple packages):
.github/workflows/release-please.yml
release-please-config.json
.release-please-manifest.json
Implementation Playbooks
Playbook A — Action-based setup (single package)
Create
.github/workflows/release-please.yml
:
yaml
name: release-please
on:
push:
branches: [main]
permissions:
contents: write
pull-requests: write
jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
id: release
with:
token: ${{ secrets.GITHUB_TOKEN }}
What happens:
- On push to , action evaluates commit history
- Creates/updates a Release PR when a releasable change exists
- After Release PR merge, creates tag + GitHub release
Playbook B — Config-driven setup (manifest mode)
release-please-config.json
json
{
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
"release-type": "node",
"packages": {
".": {
"release-type": "node"
},
"packages/pkg-a": {
"release-type": "node"
},
"packages/pkg-b": {
"release-type": "node"
}
}
}
.release-please-manifest.json
json
{
".": "0.1.0",
"packages/pkg-a": "0.1.0",
"packages/pkg-b": "0.1.0"
}
Workflow (manifest)
yaml
name: release-please
on:
push:
branches: [main]
permissions:
contents: write
pull-requests: write
jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
manifest-file: .release-please-manifest.json
config-file: release-please-config.json
Notes:
- Package keys must match real repo paths exactly
- Manifest versions are the source of truth for next bumps
Playbook C — Migration from manual releases
- Normalize commit style to Conventional Commits from now onward.
- Add workflow (single or manifest mode).
- Seed versions in
.release-please-manifest.json
to current released versions (manifest mode).
- Merge first Release PR.
- Stop manual tag/changelog edits on default branch.
Operational Workflows
Bootstrap first automated release
Checklist:
Expected result: first Release PR appears (
release-please--branches--main
style).
Ongoing release PR lifecycle
- Developers merge Conventional Commit PRs.
- Release Please updates existing release PR (or opens a new one).
- CI validates release PR.
- Merge release PR when ready.
- Action creates tag + GitHub Release.
Tag/release behavior
- Tag/release happens after merge of release PR to tracked branch.
- Changelog + version files are authored in the release PR.
- Don’t hand-edit generated release PR content unless required by policy.
Dry-run/testing strategy
- Validate config/manifest paths via PR checks before enabling strict branch rules.
- In test repos/branches, run with same workflow first.
- For production repos, start with one package path, then expand manifest coverage.
Troubleshooting
No release PR created
Check:
- No releasable commit types since last release (docs/chore only)
- Workflow not firing on tracked branch
- Token lacks /
- Existing stale release PR already open
Wrong version bump
Usually commit semantics mismatch:
- => patch
- => minor
- breaking change footer / => major
Audit merged commit messages first; Release Please is usually doing exactly what commits say.
Changelog missing/incorrect entries
- Confirm commits are Conventional Commit compliant
- Check release type + package path mapping in config
- Ensure squash merge titles are also Conventional Commit compatible
Manifest sync issues (monorepo)
Symptoms: wrong package bumped or no bump.
- Path key mismatch between config and actual directory
.release-please-manifest.json
has stale/missing package key
- Package moved/renamed without updating both files
Token/permissions failures
Resource not accessible by integration
=> wrong token scope/permissions
- Org policy may block default ; use PAT/App token
- Ensure workflow-level block is explicitly set
Best Practices and Guardrails
- Enforce Conventional Commit linting in CI
- Keep release cadence predictable (e.g., weekly or on-demand but explicit)
- Protect default branch and require CI on release PRs
- Avoid manual tags/changelog edits on release-managed branches
- Keep release PR small; don’t batch unrelated long-lived work
- In monorepos, add packages incrementally and verify each path mapping
- Document release ownership (who merges release PRs)
Quick Verification Checklist
References
Primary upstream sources:
- Core project:
googleapis/release-please
- GitHub Action (current):
googleapis/release-please-action
Historical/migration context:
- Archived old action:
google-github-actions/release-please-action