Skip to content

chore: migrate release process from semantic-release to release-please - #255

Merged
chrisleekr merged 2 commits into
mainfrom
chore/migrate-release-please
Jul 2, 2026
Merged

chore: migrate release process from semantic-release to release-please#255
chrisleekr merged 2 commits into
mainfrom
chore/migrate-release-please

Conversation

@chrisleekr

@chrisleekr chrisleekr commented Jul 2, 2026

Copy link
Copy Markdown
Owner

What changed

Replaces semantic-release v25 with release-please as the release engine. Deleted release.config.mjs, .github/workflows/release.yml, and .github/workflows/dev-release.yml; added .github/workflows/release-please.yml plus two config/manifest pairs (release-please-config.json + .release-please-manifest.json for main, and the .beta.json variants for a new beta branch).

Why

semantic-release's per-branch dev-prerelease rail (a prerelease cut from every non-main push) added noise without much value, and its config/plugin surface (release.config.mjs) was another thing to keep patched. release-please is PR-based: it maintains a standing "Release PR" that accumulates the changelog, and cutting a release is just merging that PR, no separate release commit step, no local semantic-release invocation.

New release flow

flowchart LR
    DEV["Feature branch<br/>PR merged"]:::keep --> MAIN["main branch"]:::keep
    DEV --> BETA["beta branch"]:::keep
    MAIN --> RPMAIN["release-please.yml<br/>config: release-please-config.json"]:::proc
    BETA --> RPBETA["release-please.yml<br/>config: release-please-config.beta.json"]:::proc
    RPMAIN --> PRMAIN["Release PR<br/>vX.Y.Z + CHANGELOG"]:::pr
    RPBETA --> PRBETA["Release PR<br/>vX.Y.Z-beta + CHANGELOG"]:::pr
    PRMAIN -- merge --> RELMAIN["GitHub release<br/>tag vX.Y.Z"]:::rel
    PRBETA -- merge --> RELBETA["GitHub release<br/>tag vX.Y.Z-beta"]:::rel
    RELMAIN --> DOCKERMAIN["docker-build.yml<br/>prod image + latest"]:::img
    RELBETA --> DOCKERBETA["docker-build.yml<br/>beta image, no latest"]:::img

    classDef keep fill:#2c3e50,color:#ffffff
    classDef proc fill:#34495e,color:#ffffff
    classDef pr fill:#8e44ad,color:#ffffff
    classDef rel fill:#27ae60,color:#ffffff
    classDef img fill:#ecf0f1,color:#2c3e50
Loading
  • main: stable channel. Merging the Release PR cuts v<x.y.z>, updates CHANGELOG.md + package.json, creates a GitHub release, and builds/pushes the prod image tagged :latest.
  • beta: prerelease channel (versioning-strategy: prerelease + prerelease: true + prerelease-type: beta). Merging its Release PR cuts v<x.y.z>-beta and builds a beta image, no :latest.
  • Both config/manifest pairs ship on both branches; release-please.yml selects the right pair at runtime via github.ref_name so main and beta state never mixes.
  • docker-build.yml's tag-validation regex was widened to accept the beta suffix format, and its secrets: block was tightened from secrets: inherit to explicit DOCKER_USERNAME/DOCKER_PASSWORD so the RELEASE_TOKEN PAT used by release-please.yml is never forwarded into the image-build graph.

Preservation guarantees

  • CHANGELOG.md is not rewritten, release-please prepends new sections the same way semantic-release did.
  • The existing v1.14.0 tag is auto-detected by release-please for changelog/version continuity (manifests seeded to 1.14.0).
  • include-component-in-tag: false keeps the existing v<version> tag scheme, matching both the current tags and docker-build.yml's tag regex. (In manifest mode this option defaults to true, which would have produced github-app-v1.15.0 and broken continuity + the docker build, so it is set explicitly.)

Fidelity note

Only feat, fix, and breaking (!) commits bump the version now. Under the old semantic-release ruleset, refactor/perf/revert alone could also cut a release; release-please's default Conventional Commits mapping does not treat those as release-triggering by themselves. The old per-feature-branch dev-prerelease rail is retired entirely in favor of the single beta branch channel.

Other changes

  • docs/build/conventions.md, docs/build/contributing.md, CLAUDE.md, CONTRIBUTING.md: updated to describe the release-please flow.
  • .gitlab-ci.yml: removed the already-disabled, commented-out semantic-release job; left a pointer comment that GitHub (via release-please) is now the single source of releases.
  • eslint.config.mjs: dropped now-dead ignore entries for release.config.mjs / release.config.dev.mjs.
  • .github/workflows/ci.yml / secrets-scan.yml: comment-only updates reflecting the new release trigger.

Reviewer notes / follow-ups

  • Branch protection on both main and beta must require the ci.yml PR checks. Unlike the old pipeline, release-please.yml does not itself invoke ci.yml: the Release PR is gated purely by branch-protection-required status checks, and docker-build.yml only runs post-merge when release_created == true.
  • The beta branch does not exist yet, it must be created off main after this PR merges before the beta release channel can produce its first Release PR.
  • RELEASE_TOKEN (a PAT, not the default GITHUB_TOKEN) must be present as a repo secret so the Release PR itself can trigger downstream required-checks workflows.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added automated release management for stable and beta branches.
    • Beta releases now follow a separate prerelease flow.
  • Bug Fixes

    • Simplified the release process to reduce duplicate or conflicting releases.
    • Improved release/version detection for more reliable changelogs and tags.
  • Documentation

    • Updated contributor and build docs to reflect the new release flow and branch behavior.
    • Clarified release and CI guidance across project documentation.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@chrisleekr, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 43 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: a7ce9bea-f543-414b-9ae7-067f6ccc871b

📥 Commits

Reviewing files that changed from the base of the PR and between d2eccba and 4e77a76.

📒 Files selected for processing (1)
  • .github/workflows/release-please.yml
📝 Walkthrough

Walkthrough

This PR migrates the release process from semantic-release (dev-release.yml, release.yml, release.config.mjs) to Google's release-please. It adds a new release-please.yml workflow with config/manifest files for main and beta branches, updates docker-build.yml's secrets interface and tag-validation regex, and updates CI/GitLab comments and documentation accordingly.

Changes

Release-please migration

Layer / File(s) Summary
Release-please config and manifests
release-please-config.json, release-please-config.beta.json, .release-please-manifest.json, .release-please-manifest.beta.json
Adds Node release-type config with changelog sections and initial version manifests (1.14.0) for main and beta branches.
Release-please workflow and docker-build interface
.github/workflows/release-please.yml, .github/workflows/docker-build.yml
New workflow opens Release PRs on push to main/beta and triggers docker-build.yml on release; docker-build.yml now declares explicit required secrets and a more permissive tag-name regex.
Removal of semantic-release workflows and config
.github/workflows/dev-release.yml, .github/workflows/release.yml, release.config.mjs, eslint.config.mjs
Deletes prior semantic-release-based workflows and config, and removes their eslint ignore entries.
CI/GitLab comment updates
.github/workflows/ci.yml, .github/workflows/secrets-scan.yml, .gitlab-ci.yml
Reworded comments describing gating and independence of scans/checks relative to the new release-please pipeline; no behavior changes.
Documentation updates
CLAUDE.md, CONTRIBUTING.md, docs/build/contributing.md, docs/build/conventions.md
Documents the four-workflow pipeline, release-please Release PR flow for main/beta, and prohibitions on manually editing changelog/version/manifest files.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • chrisleekr/github-app#27: Establishes the dev-release.yml/release.yml structure and docker-build.yml secrets/tag-validation that this PR replaces and updates.
  • chrisleekr/github-app#98: Modifies the same release.yml workflow (permissions) that this PR deletes.

Suggested labels: released

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: migrating the release process from semantic-release to release-please.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added the released label Jul 2, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release-please.yml:
- Around line 32-35: The workflow-level permissions in release-please.yml are
too broad and currently apply to both jobs; move the `contents`,
`pull-requests`, and `issues` write permissions into the `release-please` job so
only that job has them, and keep the `docker` job at minimal permissions (or
none) since it only calls `docker-build.yml`. Use the `release-please` and
`docker` job definitions to relocate the permissions without changing the job
behavior.

In `@CLAUDE.md`:
- Around line 118-121: Clarify the beta release format in the release-please
documentation by stating that prerelease tags use the full `v<x.y.z>-beta.<n>`
pattern, not just `-beta`. Update the mirrored release-process guidance in the
sections describing `release-please`, the `beta` branch, and `prerelease-type:
beta` so all docs consistently reflect the actual tagging behavior and workflow
contract.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1059d03d-735d-481b-8669-ea76dd3e2048

📥 Commits

Reviewing files that changed from the base of the PR and between 0cb6d12 and d2eccba.

📒 Files selected for processing (17)
  • .github/workflows/ci.yml
  • .github/workflows/dev-release.yml
  • .github/workflows/docker-build.yml
  • .github/workflows/release-please.yml
  • .github/workflows/release.yml
  • .github/workflows/secrets-scan.yml
  • .gitlab-ci.yml
  • .release-please-manifest.beta.json
  • .release-please-manifest.json
  • CLAUDE.md
  • CONTRIBUTING.md
  • docs/build/contributing.md
  • docs/build/conventions.md
  • eslint.config.mjs
  • release-please-config.beta.json
  • release-please-config.json
  • release.config.mjs
💤 Files with no reviewable changes (4)
  • .github/workflows/release.yml
  • .github/workflows/dev-release.yml
  • release.config.mjs
  • eslint.config.mjs

Comment thread .github/workflows/release-please.yml Outdated
Comment thread CLAUDE.md
Grants security-events:write + id-token:write to the docker job (Trivy SARIF
upload + Sigstore) which the workflow-level block had dropped vs the retired
release.yml, and confines the release-please write scopes to that job.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HgsnnsDi5ksjBJd5NvLYpB
@chrisleekr
chrisleekr merged commit 58cd2bd into main Jul 2, 2026
9 checks passed
@chrisleekr
chrisleekr deleted the chore/migrate-release-please branch July 2, 2026 10:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant