Skip to content

Commit 1e15fa4

Browse files
authored
ci: replace the two-stage release flow with release-please (#143)
1 parent 7b97208 commit 1e15fa4

8 files changed

Lines changed: 110 additions & 97 deletions

File tree

.github/workflows/initiate_release.yml

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

.github/workflows/pr_title.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: Lint PR title
2+
3+
on:
4+
pull_request:
5+
types: [opened, edited, reopened, synchronize]
6+
7+
permissions:
8+
pull-requests: read
9+
10+
jobs:
11+
pr_title:
12+
name: 👮 Conventional PR title
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: amannn/action-semantic-pull-request@v6
16+
env:
17+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/release.yml

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,55 @@
11
name: Release
22

33
on:
4-
pull_request:
5-
types: [closed]
4+
push:
65
branches:
76
- main
7+
- '*.x'
8+
workflow_dispatch:
9+
10+
permissions:
11+
contents: write
12+
issues: write
13+
pull-requests: write
14+
15+
concurrency:
16+
group: release-${{ github.ref_name }}
17+
cancel-in-progress: false
818

919
jobs:
10-
Release:
20+
release:
1121
name: 🚀 Release
12-
if: github.event.pull_request.merged && startsWith(github.head_ref, 'release-')
1322
runs-on: ubuntu-latest
1423
steps:
1524
- uses: actions/checkout@v4
1625

17-
- uses: actions/github-script@v6
26+
# Reversible half: keep the Release PR current. Never gated.
27+
- uses: googleapis/release-please-action@v4
1828
with:
19-
script: |
20-
// Getting the release version from the PR source branch
21-
// Source branch looks like this: release-1.0.0
22-
const version = context.payload.pull_request.head.ref.split('-')[1]
23-
core.exportVariable('VERSION', version)
29+
config-file: release-please-config.json
30+
manifest-file: .release-please-manifest.json
31+
target-branch: ${{ github.ref_name }}
32+
skip-github-release: true
33+
34+
# Irreversible half is gated on this. Go resolves a v2+ module only if go.mod carries the
35+
# matching /vN suffix, and release-please never rewrites it, so a major stays a manual
36+
# migration. proxy.golang.org caches a tag permanently, so this must hold before tagging.
37+
- name: Verify go.mod major matches the version about to be tagged
38+
run: |
39+
version="$(jq -r '.["."]' .release-please-manifest.json)"
40+
expected="${version%%.*}"
41+
module_path="$(sed -n 's/^module //p' go.mod)"
42+
module_major="$(printf '%s' "$module_path" | sed -n 's|.*/v\([0-9][0-9]*\)$|\1|p')"
43+
[ -n "$module_major" ] || module_major=1
44+
if [ "$module_major" != "$expected" ]; then
45+
echo "::error::go.mod declares '$module_path' (major v$module_major) but the pending release is $version."
46+
echo "::error::A major must be migrated on main BEFORE its Release PR merges. See CONTRIBUTING.md."
47+
exit 1
48+
fi
2449
25-
- name: Create release on GitHub
26-
uses: ncipollo/release-action@v1
50+
- uses: googleapis/release-please-action@v4
2751
with:
28-
tag: ${{ env.VERSION }}
29-
token: ${{ secrets.GITHUB_TOKEN }}
30-
generateReleaseNotes: true
52+
config-file: release-please-config.json
53+
manifest-file: .release-please-manifest.json
54+
target-branch: ${{ github.ref_name }}
55+
skip-github-pull-request: true

.release-please-manifest.json

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

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Changelog
22

3-
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
3+
All notable changes to this project will be documented in this file. Releases are automated by [release-please](https://github.com/googleapis/release-please); see [Conventional Commits](https://www.conventionalcommits.org/) for commit guidelines.
44

55
## [5.3.0](https://github.com/GetStream/getstream-go/compare/v5.2.0...v5.3.0) (2026-08-17)
66

CONTRIBUTING.md

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,45 @@ You can read about conventional commits [here](https://www.conventionalcommits.o
4747

4848
## Release (for Stream developers)
4949

50-
Releasing this package involves two GitHub Action steps:
50+
Releases are driven by [release-please](https://github.com/googleapis/release-please).
5151

52-
- Kick off a job called `initiate_release` ([link](https://github.com/GetStream/stream-chat-go/actions/workflows/initiate_release.yml)).
52+
- Merge PRs to `main` with conventional-commit titles. The PR title becomes the commit subject and is what determines the next version, so a non-conventional title ships nothing.
53+
- release-please keeps a Release PR open with the version bump and the generated changelog. Review it.
54+
- The Release PR is opened by `github-actions[bot]`, so its CI runs are held at "action required" until someone clicks **Approve and run**, and it needs a code-owner approval like any other PR. If a later commit landed on `main`, click **Update branch** first.
55+
- Merge the Release PR. That creates the tag and the GitHub Release, and `proxy.golang.org` picks the tag up. There is no separate publish step.
5356

54-
The job creates a pull request with the changelog. Check if it looks good.
57+
> **Pilot only:** `release-please-config.json` currently sets `"draft": true`, so merging the Release PR creates a *draft* GitHub Release and **no git tag**. Nothing reaches `proxy.golang.org` until someone publishes the draft. Remove `"draft": true` once the pilot is signed off.
5558
56-
- Merge the pull request.
59+
Only `feat`, `fix`, `perf` and breaking changes produce a release (`revert` may also). A window of only `chore`, `ci`, `docs`, `test`, `refactor`, `style` or `build` commits produces no Release PR, which is intended.
5760

58-
Once the PR is merged, it automatically kicks off another job which will create the tag and created a GitHub release.
61+
### Forcing a specific version
62+
63+
Land a commit on `main` whose subject is conventional and whose body carries a `Release-As` footer. The footer also overrides the rule above, so it works even for a hidden commit type:
64+
65+
```bash
66+
git commit --allow-empty -m "chore: republish as 5.3.1" -m "Release-As: 5.3.1"
67+
```
68+
69+
If direct pushes to `main` are blocked, merge a PR and type `Release-As: 5.3.1` into the **commit message box** in the squash dialog. That box is blank by default and the PR description is never copied into it, so a footer left in the description is silently dropped.
70+
71+
### Hotfix while a release is pending
72+
73+
`main`'s next release includes everything merged since the last tag, so when `main` carries something you are not ready to ship, you cannot cut a patch from it. Release from a maintenance branch instead. The workflow triggers on any `*.x` branch and releases against that branch, so nothing needs editing per hotfix.
74+
75+
1. Branch from the last released tag and push it: `git switch -c 5.x v5.3.0 && git push -u origin 5.x`.
76+
2. If that tag predates release-please, copy `release-please-config.json` and `.release-please-manifest.json` onto the branch and set the manifest to that tag's version.
77+
3. Cherry-pick the `fix:` commit onto `5.x` and push.
78+
4. release-please opens a Release PR against `5.x`. Merge it to cut the patch.
79+
5. Forward-port the fix to `main`.
80+
81+
The pending Release PR on `main` is untouched throughout.
82+
83+
### Major versions
84+
85+
Go resolves a v2+ module only if `go.mod` carries the matching `/vN` suffix, and release-please does not rewrite it. The release is tagged at the Release PR's merge commit, so the migration must already be in that commit's history:
86+
87+
1. Land the `feat!` change. release-please opens a Release PR for the next major.
88+
2. Migrate `go.mod` and every self-import to `/vN` in a separate PR and merge it to `main`. The Release workflow fails on those pushes while the two disagree, which is expected and blocks nothing else.
89+
3. Click **Update branch** on the major Release PR, then merge it. The tag is created against a tree that already has the migrated `go.mod`.
90+
91+
Never merge a major Release PR before step 2. If that happens the tag is blocked, and the fix is manual: land the migration, remove the `autorelease: pending` label from the merged Release PR, then tag by hand at the migrated commit.

release-please-config.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
3+
"packages": {
4+
".": {
5+
"release-type": "go",
6+
"extra-files": ["version.go"],
7+
"draft": true
8+
}
9+
}
10+
}

version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package getstream
22

33
const (
4-
versionName = "v5.3.0"
4+
versionName = "v5.3.0" // x-release-please-version
55
)
66

77
// Version returns the version of the library. versionName is written by the release

0 commit comments

Comments
 (0)