Skip to content

Commit e2555da

Browse files
authored
chore: migrate release pipeline to release-please (#194)
* ci: migrate release pipeline from semantic-release to release-please Switches releases from per-merge auto-publish (semantic-release) to an accumulating, PR-gated model (release-please): merges land on master, a single Release PR maintains the next version + CHANGELOG, and merging it cuts the tag and triggers publish. - add release-please-config.json + .release-please-manifest.json: lockstep monorepo (root '.' drives one version/tag/CHANGELOG; extra-files bump all 11 published packages to the same version) - add .github/workflows/release-please.yml: maintains the Release PR (via the bot App token so it triggers CI) and, on release, publishes with the same 'yarn workspaces foreach npm publish' step used before (handles workspace:* ) - add root package.json version (source of truth for release-please) - remove semantic-release: release.yml workflow + .releaserc.json - allow 'revert' and 'ci' PR-title prefixes (release-please understands them) Note: keeps the existing yarn-based publish/auth as-is. npm trusted publishing + provenance is a deliberate follow-up (needs per-package npm config and a yarn pack step for workspace:* ). * ci: keep the workflow file named release.yml for npm OIDC The npm trusted publisher (OIDC) is configured against the workflow file .github/workflows/release.yml. Keep the release-please + publish workflow under that filename so the OIDC exchange keeps matching; the publish job stays the entry workflow's job, so its OIDC subject is release.yml.
1 parent e557ea7 commit e2555da

6 files changed

Lines changed: 90 additions & 50 deletions

File tree

.github/workflows/release.yml

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,57 @@
11
name: Release
22

3+
# Replaces semantic-release. Instead of publishing on every qualifying merge,
4+
# release-please maintains a single "Release PR" that accumulates the Conventional
5+
# Commits landing on master (bumping every package to the same version and updating
6+
# CHANGELOG.md). Merging that PR creates the git tag (vX.Y.Z) and GitHub Release,
7+
# which then triggers the publish job below.
38
on:
4-
workflow_run:
5-
workflows: ["Build and Test"]
9+
push:
610
branches: [master]
7-
types:
8-
- completed
911

1012
permissions:
11-
id-token: write # Required for OIDC
12-
contents: write # To create releases
13+
contents: write
14+
pull-requests: write
1315

1416
jobs:
15-
release:
17+
release-please:
1618
runs-on: ubuntu-latest
17-
if: ${{ github.event.workflow_run.conclusion == 'success' }}
19+
outputs:
20+
release_created: ${{ steps.release.outputs.release_created }}
21+
tag_name: ${{ steps.release.outputs.tag_name }}
1822
steps:
19-
- name: "Generate token"
23+
# App token (not GITHUB_TOKEN) so the Release PR triggers the Build and Test
24+
# checks; PRs opened by GITHUB_TOKEN do not start workflows.
25+
- name: Generate token
26+
id: generate_token
27+
uses: tibdex/github-app-token@v1
28+
with:
29+
app_id: ${{ secrets.BOT_APP_ID }}
30+
private_key: ${{ secrets.BOT_PRIVATE_KEY }}
31+
32+
- name: Run release-please
33+
id: release
34+
uses: googleapis/release-please-action@v4
35+
with:
36+
# Reads release-please-config.json and .release-please-manifest.json from
37+
# the repo root. The root package drives one version/tag/changelog and the
38+
# config's extra-files bump every published package in lockstep.
39+
token: ${{ steps.generate_token.outputs.token }}
40+
41+
# Runs only when merging the Release PR just cut a release. Publishing reuses the
42+
# exact steps from the previous semantic-release setup (yarn npm publish, which
43+
# rewrites the workspace:* dependency ranges to concrete versions). At this point
44+
# the package versions are already bumped by the merged Release PR, so there is no
45+
# version step here.
46+
publish:
47+
needs: release-please
48+
if: ${{ needs.release-please.outputs.release_created == 'true' }}
49+
runs-on: ubuntu-latest
50+
permissions:
51+
contents: read
52+
id-token: write
53+
steps:
54+
- name: Generate token
2055
id: generate_token
2156
uses: tibdex/github-app-token@v1
2257
with:
@@ -26,8 +61,8 @@ jobs:
2661
- name: Checkout repository
2762
uses: actions/checkout@v4
2863
with:
64+
ref: ${{ needs.release-please.outputs.tag_name }}
2965
persist-credentials: false
30-
fetch-depth: 0
3166
token: ${{ steps.generate_token.outputs.token }}
3267

3368
- name: Set up Node.js
@@ -57,7 +92,5 @@ jobs:
5792
npmRegistryServer: "https://registry.npmjs.org"
5893
EOF
5994
60-
- name: Semantic Release
61-
env:
62-
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
63-
run: npx semantic-release
95+
- name: Publish packages
96+
run: yarn workspaces foreach -A --no-private npm publish --access public --tag latest

.github/workflows/validate-branch.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
run: |
1616
PR_TITLE=$(printf "%s" "${{ github.event.pull_request.title }}")
1717
echo "PR title: $PR_TITLE"
18-
if [[ ! "$PR_TITLE" =~ ^(feat|fix|chore|docs|refactor|style|test|tests|perf|build)(\(.+\))?:\ .+ ]]; then
18+
if [[ ! "$PR_TITLE" =~ ^(feat|fix|chore|docs|refactor|style|test|tests|perf|build|revert|ci)(\(.+\))?:\ .+ ]]; then
1919
echo "::error::Invalid PR title: $PR_TITLE"
2020
echo "::error::PR title must follow Conventional Commits, e.g., 'feat(api): add user login'"
2121
exit 1

.release-please-manifest.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
".": "1.16.0"
3+
}

.releaserc.json

Lines changed: 0 additions & 35 deletions
This file was deleted.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"name": "sidequest-monorepo",
33
"private": true,
4+
"version": "1.16.0",
45
"type": "module",
56
"description": "Monorepo for Sidequest.js",
67
"engines": {

release-please-config.json

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
3+
"packages": {
4+
".": {
5+
"release-type": "node",
6+
"package-name": "sidequest",
7+
"changelog-path": "CHANGELOG.md",
8+
"include-component-in-tag": false,
9+
"include-v-in-tag": true,
10+
"changelog-sections": [
11+
{ "type": "feat", "section": "Features" },
12+
{ "type": "fix", "section": "Bug Fixes" },
13+
{ "type": "perf", "section": "Performance Improvements" },
14+
{ "type": "refactor", "section": "Code Refactoring" },
15+
{ "type": "revert", "section": "Reverts" },
16+
{ "type": "docs", "section": "Documentation", "hidden": true },
17+
{ "type": "chore", "hidden": true },
18+
{ "type": "ci", "hidden": true },
19+
{ "type": "test", "hidden": true },
20+
{ "type": "build", "hidden": true },
21+
{ "type": "style", "hidden": true }
22+
],
23+
"extra-files": [
24+
{ "type": "json", "path": "packages/sidequest/package.json", "jsonpath": "$.version" },
25+
{ "type": "json", "path": "packages/engine/package.json", "jsonpath": "$.version" },
26+
{ "type": "json", "path": "packages/core/package.json", "jsonpath": "$.version" },
27+
{ "type": "json", "path": "packages/dashboard/package.json", "jsonpath": "$.version" },
28+
{ "type": "json", "path": "packages/cli/package.json", "jsonpath": "$.version" },
29+
{ "type": "json", "path": "packages/backends/backend/package.json", "jsonpath": "$.version" },
30+
{ "type": "json", "path": "packages/backends/backend-test/package.json", "jsonpath": "$.version" },
31+
{ "type": "json", "path": "packages/backends/postgres/package.json", "jsonpath": "$.version" },
32+
{ "type": "json", "path": "packages/backends/mysql/package.json", "jsonpath": "$.version" },
33+
{ "type": "json", "path": "packages/backends/sqlite/package.json", "jsonpath": "$.version" },
34+
{ "type": "json", "path": "packages/backends/mongo/package.json", "jsonpath": "$.version" }
35+
]
36+
}
37+
}
38+
}

0 commit comments

Comments
 (0)