You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
if ! echo "$BRANCH" | grep -Eq '^release-v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$'; then
59
-
echo "Error: Branch '$BRANCH' must match 'release-v<semver>' (e.g., release-v1.2.3)." >&2
60
-
exit 1
61
-
fi
79
+
# 1) NEW_VERSION must be valid semver
80
+
node -e "const v=process.env.NEW_VERSION; const semver=/^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?$/; if(!semver.test(v)){ console.error('Error: version is not valid semver:', v); process.exit(1); }"
62
81
63
-
# 2) NEW_VERSION must be valid semver
64
-
node -e "const v=process.env.NEW_VERSION; const semver=/^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?$/; if(!semver.test(v)){ console.error('Error: NEW_VERSION is not valid semver:', v); process.exit(1); }"
65
-
if [ $? -ne 0 ]; then
66
-
exit 1
67
-
fi
68
-
69
-
# 3) NEW_VERSION must differ from CURRENT_VERSION
70
-
if [ "$NEW_VERSION" = "$CURRENT_VERSION" ]; then
71
-
echo "Error: NEW_VERSION equals CURRENT_VERSION ($CURRENT_VERSION). Nothing to release." >&2
72
-
exit 1
73
-
fi
82
+
# 2) NEW_VERSION must be a forward bump (strictly greater than CURRENT_VERSION
83
+
# by SemVer precedence) so a typo can't downgrade the published version.
84
+
node -e '
85
+
const cmp = (a, b) => {
86
+
const parse = (v) => {
87
+
const noBuild = v.split("+")[0];
88
+
const [core, pre] = noBuild.split("-");
89
+
const nums = core.split(".").map(Number);
90
+
return { nums, pre: pre ? pre.split(".") : null };
91
+
};
92
+
const A = parse(a), B = parse(b);
93
+
for (let i = 0; i < 3; i++) if (A.nums[i] !== B.nums[i]) return A.nums[i] - B.nums[i];
94
+
if (!A.pre && !B.pre) return 0;
95
+
if (!A.pre) return 1; // release outranks prerelease
96
+
if (!B.pre) return -1;
97
+
const n = Math.max(A.pre.length, B.pre.length);
98
+
for (let i = 0; i < n; i++) {
99
+
const x = A.pre[i], y = B.pre[i];
100
+
if (x === undefined) return -1;
101
+
if (y === undefined) return 1;
102
+
const xn = /^\d+$/.test(x), yn = /^\d+$/.test(y);
103
+
if (xn && yn) { const d = Number(x) - Number(y); if (d !== 0) return d; }
message: "chore(release): bump version to ${{ env.NEW_VERSION }}"
119
174
token: ${{ steps.gh-app-token.outputs.token }}
120
-
ref: ${{ github.ref_name }}
175
+
ref: ${{ env.BUMP_BRANCH }}
121
176
files: ${{ steps.changes.outputs.files }}
177
+
178
+
- name: Open pull request
179
+
env:
180
+
GH_TOKEN: ${{ steps.gh-app-token.outputs.token }}
181
+
BASE_BRANCH: ${{ github.ref_name }}
182
+
run: |
183
+
BODY=$(printf 'Automated version bump to `%s`.\n\nMerging this PR into `%s` cuts `v%s` and publishes to npm after the release approval gate.' "$NEW_VERSION" "$BASE_BRANCH" "$NEW_VERSION")
184
+
gh pr create \
185
+
--base "$BASE_BRANCH" \
186
+
--head "$BUMP_BRANCH" \
187
+
--title "chore(release): bump version to $NEW_VERSION" \
This will usually be `main` except in the event of a hotfix.
5
-
For hotfixes, checkout the release branch you want to fix.
6
-
7
-
(2) Create a new release branch.
8
-
9
-
```sh
10
-
git checkout -b release-v0.2.0
11
-
```
12
-
13
-
(3) Push and open a PR targeting `main` to carefully review the release changes.
14
-
This will trigger a GitHub workflow that automatically bumps the version number throughout the project.
15
-
16
-
```sh
17
-
git push origin release-v0.2.0
18
-
```
19
-
20
-
(4) Once merged, pull the changes from the release branch.
21
-
Then, create a tag on the release branch and push it to the main repository.
22
-
Note that the version changes must be pulled *before* the tag is created;
23
-
otherwise, the version validation check will fail in the release workflow.
24
-
25
-
```sh
26
-
git pull
27
-
git tag v0.2.0
28
-
git push origin v0.2.0
29
-
```
30
-
31
-
(5) After that, go to the repo's [releases page](https://github.com/OpenZeppelin/compact-contracts/releases/).
32
-
[Create a new release](https://github.com/OpenZeppelin/compact-contracts/releases/new) with the new tag and the base branch as target (`main` except in the event of a hotfix).
33
-
Make sure to write a detailed release description and a short changelog.
34
-
Once published, this will trigger a workflow to upload the release tarball to npm.
35
-
36
-
(6) Finally, from the released tag,
37
-
create and push a doc branch to deploy the corresponding version to the doc-site.
38
-
39
-
```sh
40
-
git checkout -b docs-v0.2.0
41
-
git push origin docs-v0.2.0
42
-
```
3
+
Releases are automated. You bump the version via a workflow, merge the bump PR,
4
+
and the tag, GitHub Release, and npm publish happen on their own (behind a
5
+
manual approval gate).
6
+
7
+
Notation: `X.Y.Z` is a concrete SemVer; `release/X.Y.x` is the audit branch for
8
+
the `X.Y` line (the `x` is literal — it denotes the patch line, not a point);
9
+
`N` is a prerelease counter.
10
+
11
+
## Branch model
12
+
13
+
-**`main`** — the alpha line; always exists.
14
+
-**`release/X.Y.x`** — the `X.Y` patch line; cut from `main` when an audit
15
+
starts, carries `X.Y.0-rc.N → X.Y.0` (and any later `X.Y.Z` hotfixes). Deleted
16
+
after back-merge; recreate it from the `vX.Y.Z` tag if a later hotfix is needed.
17
+
18
+
There is no long-lived per-version branch: a version bump is just a PR into
19
+
`main` or a `release/X.Y.x` branch.
20
+
21
+
## How it works
22
+
23
+
1. Run **Prepare release** (`prepare-release.yml`) via *Actions → Run workflow*:
24
+
pick the branch, type the exact target version. It opens a `chore/bump-<version>`
25
+
PR into that branch.
26
+
2. Review and merge the bump PR.
27
+
3. On merge, **Create release** (`create-release.yml`) cuts `v<version>` + a
28
+
GitHub Release from that branch (`--prerelease` for any `-alpha`/`-rc`
29
+
version).
30
+
4. That fires **Publish** (`release.yml`), which pauses at the `release`
31
+
approval gate. An authorized reviewer approves, then it publishes to npm.
0 commit comments