Skip to content

Commit dc1f57e

Browse files
authored
Merge pull request #12 from scalar/release-please--branches--scalar-next
release: 0.3.2
2 parents 2deefe3 + 23c8eaf commit dc1f57e

11 files changed

Lines changed: 302 additions & 1312 deletions
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
name: Release PR Version
2+
3+
on:
4+
# `edited` is not one of the default pull_request types, but it is the point of this
5+
# workflow: retitling the release PR is how a maintainer picks an exact version. The
6+
# other types keep the consistency check attached to the PR as it evolves.
7+
pull_request:
8+
types: [opened, reopened, edited, synchronize]
9+
10+
# Read-only by default; only the job that pushes the Release-As commit widens this.
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
version-consistency:
16+
# Also the check name the release PR's footer tells maintainers to wait for.
17+
name: Release PR version
18+
# Only the platform's release PR carries a version in its title; every other pull request
19+
# skips this job, which GitHub reports as neutral. The release may be presented from
20+
# scalar-next itself or from the release-please branch rendered off it, so both heads
21+
# count as the release PR.
22+
if: >-
23+
${{ github.event.pull_request.base.ref == 'main'
24+
&& (github.event.pull_request.head.ref == 'scalar-next'
25+
|| startsWith(github.event.pull_request.head.ref, 'release-please--branches--scalar-next--')) }}
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
29+
with:
30+
# The version committed on the PR head is what merging would actually release.
31+
ref: ${{ github.event.pull_request.head.sha }}
32+
# Fails while the title version and the committed version disagree — the window between
33+
# a maintainer's retitle and the platform re-rendering the PR from it. Without this a
34+
# merge in that window would tag a release whose own files self-report the old version,
35+
# and a title release-please cannot parse would silently cut no release at all.
36+
- name: Compare the title version with the committed version
37+
env:
38+
# The title is human input, so it is bound through the environment (never
39+
# interpolated into the script) and matched against a strict semver pattern
40+
# before it is read.
41+
PR_TITLE: ${{ github.event.pull_request.title }}
42+
run: |
43+
pattern='^release: ((0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?)$'
44+
if [[ ! "$PR_TITLE" =~ $pattern ]]; then
45+
echo "::error::Release PR title must be \"release: X.Y.Z\" with a full semver version, got: $PR_TITLE"
46+
exit 1
47+
fi
48+
title_version="${BASH_REMATCH[1]}"
49+
manifest_version="$(jq -r '.["."]' .release-please-manifest.json)"
50+
if [[ "$title_version" != "$manifest_version" ]]; then
51+
echo "::error::Release PR title says $title_version but the pull request is versioned $manifest_version. Wait for the release PR to be re-rendered at $title_version before merging."
52+
exit 1
53+
fi
54+
echo "Release PR title and committed version agree on $title_version."
55+
56+
apply-title-version:
57+
name: Apply edited release version
58+
# A human retitle of the open release PR is bridged into the canonical explicit-version
59+
# mechanism (a Release-As commit on scalar-next, which the platform re-renders the
60+
# release PR from). `changes.title` is only set when the title itself changed, and bot
61+
# senders are ignored so the platform's own retitles cannot bounce back into another
62+
# commit.
63+
if: >-
64+
${{ github.event.action == 'edited'
65+
&& github.event.changes.title != null
66+
&& github.event.sender.type != 'Bot'
67+
&& github.event.pull_request.state == 'open'
68+
&& github.event.pull_request.base.ref == 'main'
69+
&& (github.event.pull_request.head.ref == 'scalar-next'
70+
|| startsWith(github.event.pull_request.head.ref, 'release-please--branches--scalar-next--')) }}
71+
# One bridge run at a time per pull request, newest retitle wins. Two retitles in quick
72+
# succession (a version typo corrected seconds later) would otherwise start two runs that
73+
# both read the version committed on the PR head, both get past the no-op guard, and both
74+
# push — and since each fetches scalar-next immediately before committing, the second
75+
# push fast-forwards instead of failing. release-please honours the newest Release-As
76+
# footer, so the release would land on whichever run happened to push last, not on the
77+
# title the maintainer actually left behind.
78+
concurrency:
79+
group: release-title-edit-${{ github.event.pull_request.number }}
80+
cancel-in-progress: true
81+
runs-on: ubuntu-latest
82+
permissions:
83+
contents: write
84+
steps:
85+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
86+
with:
87+
# The PR head, so the version the pull request currently carries can be read before
88+
# deciding whether anything needs to change.
89+
ref: ${{ github.event.pull_request.head.sha }}
90+
- name: Push a Release-As commit for the edited version
91+
env:
92+
PR_TITLE: ${{ github.event.pull_request.title }}
93+
run: |
94+
set -euo pipefail
95+
pattern='^release: ((0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?)$'
96+
if [[ ! "$PR_TITLE" =~ $pattern ]]; then
97+
echo "::error::Release PR title must be \"release: X.Y.Z\" with a full semver version, got: $PR_TITLE"
98+
exit 1
99+
fi
100+
# Only ever a validated semver from here on, so it is safe in a commit message.
101+
version="${BASH_REMATCH[1]}"
102+
manifest_version="$(jq -r '.["."]' .release-please-manifest.json)"
103+
# The re-rendered PR is retitled to the version it now carries; stopping here keeps
104+
# that from producing an endless chain of Release-As commits.
105+
if [[ "$version" == "$manifest_version" ]]; then
106+
echo "This release PR already carries $version; nothing to do."
107+
exit 0
108+
fi
109+
git config user.name "github-actions[bot]"
110+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
111+
git fetch origin scalar-next
112+
git checkout -B scalar-next origin/scalar-next
113+
git commit --allow-empty -m "chore: release $version" -m "Release-As: $version"
114+
# Plain (non-force) push: losing a race against a regeneration push fails loudly
115+
# rather than discarding it, and the retitle can simply be repeated.
116+
git push origin scalar-next
117+
echo "Pushed Release-As: $version to scalar-next. The release PR will be re-rendered at that version."

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "0.3.1"
2+
".": "0.3.2"
33
}

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## [0.3.2](https://github.com/scalar/scalar-python/compare/v0.3.1...v0.3.2) (2026-07-28)
4+
5+
6+
### Chores
7+
8+
* **api:** regenerate SDK ([099aa9f](https://github.com/scalar/scalar-python/commit/099aa9f8b3261e0ef995755200c397cfae9a0a80))
9+
* **api:** update generated SDK content ([5d70014](https://github.com/scalar/scalar-python/commit/5d70014cc5b36aab6db5eaa4d487c4bd5b7258f0))
10+
* **api:** update generated SDK content ([a06d6cc](https://github.com/scalar/scalar-python/commit/a06d6cc862a5f29399a26aedb7d6c5ad124e7ff7))
11+
312
## [0.3.1](https://github.com/scalar/scalar-python/compare/v0.3.0...v0.3.1) (2026-07-27)
413

514

VERSIONING.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,26 @@ Release PRs are opened by the Scalar platform from `scalar-next` against the def
2525
branch — so the PR diff shows the full pending release — and are versioned from
2626
[Conventional Commits](https://www.conventionalcommits.org). Merging a release PR tags the
2727
release, publishes it, and syncs the version bump and changelog back to `scalar-next`.
28-
Pre-1.0, breaking changes bump the minor version; to cut `1.0.0` (or any explicit
29-
version), push an empty commit with a `Release-As` footer to `scalar-next`:
28+
Pre-1.0, breaking changes bump the minor version.
29+
30+
### Choosing an exact version
31+
32+
To release a specific version — `1.0.0`, a hotfix number, anything the commit history would
33+
not have picked — **edit the release PR title** to the version you want:
34+
35+
```text
36+
release: 1.0.0
37+
```
38+
39+
The `Release PR version` check turns red as soon as you save, because the version in the
40+
title no longer matches the version committed in the PR. The Scalar platform then re-renders
41+
the release PR at your version (changelog, manifest, and every version-bearing file), the
42+
title comes back as `release: 1.0.0`, and the check turns green. **Wait for it to be green
43+
before merging** — merging in between would tag a release whose own files still carry the
44+
old version.
45+
46+
The git-native equivalent, if you would rather not touch the PR: push an empty commit with a
47+
`Release-As` footer to `scalar-next`. This is exactly what the title edit does for you.
3048

3149
```sh
3250
git commit --allow-empty -m "chore: release 1.0.0" -m "Release-As: 1.0.0"

0 commit comments

Comments
 (0)