-
Notifications
You must be signed in to change notification settings - Fork 38
Expand file tree
/
Copy pathprepare-github-release.sh
More file actions
executable file
·142 lines (111 loc) · 4.86 KB
/
Copy pathprepare-github-release.sh
File metadata and controls
executable file
·142 lines (111 loc) · 4.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/env bash
#
# prepare-github-release.sh — Apply the local file changes for a release.
#
# Run this on a working branch off the release-source branch (e.g. off
# `main` for a minor release, off `release/vX.Y` for a patch). The script
# only touches files and commits — branch creation, push, and PR opening
# are the operator's responsibility.
#
# Steps:
# 1. Generate changelog section with git-cliff
# 2. Bump workspace version in Cargo.toml
# 3. Verify and update contract ABI snapshot
# 4. Regenerate third-party licenses
# 5. Commit the release changes
#
# Usage: ./scripts/ops/prepare-github-release.sh <VERSION>
# Example: ./scripts/ops/prepare-github-release.sh 3.6.0
#
set -euo pipefail
REPO_ROOT="$(git rev-parse --show-toplevel)"
# --- Argument parsing ---
usage() {
echo "Usage: $0 <VERSION> (e.g. 3.6.0)"
exit 1
}
if [[ $# -ne 1 ]]; then
echo "Error: Expected exactly one argument, got $#."
usage
fi
VERSION="$1"
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Error: '$VERSION' is not valid semver (expected MAJOR.MINOR.PATCH)."
exit 1
fi
# --- Helper functions ---
die() {
printf 'Error: %s\n' "$1" >&2
exit 1
}
require_cmds() {
local missing=0
for cmd in "$@"; do
command -v "$cmd" >/dev/null 2>&1 || {
printf 'Missing dependency: %s\n' "$cmd" >&2
missing=1
}
done
[[ "${missing}" -eq 0 ]] || die "Please install the missing dependencies above (hint: run from within 'nix develop')."
}
# --- Dependency checks ---
require_cmds git-cliff cargo-about cargo-insta
# git-cliff needs a GitHub token to avoid API rate limits when resolving PR links.
if [[ -z "${GITHUB_TOKEN:-}" ]]; then
if command -v gh &>/dev/null && gh auth status &>/dev/null; then
echo "==> GITHUB_TOKEN not set, obtaining from 'gh auth token'."
GITHUB_TOKEN=$(gh auth token)
export GITHUB_TOKEN
else
echo "WARNING: GITHUB_TOKEN is not set and 'gh' CLI is not authenticated."
echo " PR links in the changelog may be missing. Fix: export GITHUB_TOKEN=<token> or 'gh auth login'."
fi
fi
echo "==> Preparing release v${VERSION}"
cd "$REPO_ROOT"
# --- Clean working tree check ---
if ! git diff --quiet || ! git diff --cached --quiet; then
die "Working tree has uncommitted changes. Please commit or stash them first."
fi
# --- Generate changelog ---
# Use --prepend so the new release section is added on top of CHANGELOG.md,
# preserving any manually authored sections (e.g. for releases whose tag does not
# live on main, like 3.9.1 on release/v3.9.1). When new sections need to be
# hand-written, append the relevant duplicate cherry-pick commits to .cliffignore
# so they don't reappear in the next auto-generated release block.
#
# git-cliff fetches PR/author metadata for the ref at the range head. The literal
# `HEAD` resolves to the default branch (main), missing PRs merged only into a
# release branch, so we pass an explicit range ending at a concrete SHA. The base
# is the latest semver tag reachable from HEAD; --match skips stray non-semver tags.
echo "==> Generating changelog..."
BASE_TAG=$(git describe --tags --abbrev=0 --match '[0-9]*.[0-9]*.[0-9]*' HEAD) \
|| die "Could not find a previous semver tag reachable from HEAD."
git-cliff --prepend CHANGELOG.md -t "$VERSION" "${BASE_TAG}..$(git rev-parse HEAD)"
# --- Bump workspace version in Cargo.toml ---
# `grep -P` (PCRE) and `sed -i` without a suffix are GNU-only; use POSIX
# forms so this works on both Linux and macOS (BSD userland).
CARGO_TOML="${REPO_ROOT}/Cargo.toml"
OLD_VERSION=$(awk -F'"' '/^version = "[0-9]+\.[0-9]+\.[0-9]+"/ {print $2; exit}' "$CARGO_TOML")
[[ -n "$OLD_VERSION" ]] || die "Could not find a workspace 'version = \"X.Y.Z\"' line in $CARGO_TOML."
echo "==> Bumping workspace version: ${OLD_VERSION} -> ${VERSION}"
sed -i.bak -E "s/^version = \"[0-9]+\.[0-9]+\.[0-9]+\"/version = \"${VERSION}\"/" "$CARGO_TOML" && rm "${CARGO_TOML}.bak"
# --- Verify contract ABI has changed ---
# The version bump should cause the ABI snapshot to differ. We expect
# the test to fail — if it passes, the ABI was not affected.
echo "==> Verifying contract ABI changed after version bump..."
if cargo nextest run --cargo-profile=test-release -p mpc-contract abi_has_not_changed 2>/dev/null; then
die "abi_has_not_changed test passed unexpectedly — ABI was not affected by version bump."
fi
# --- Update ABI snapshot ---
echo "==> Accepting updated ABI snapshot..."
cargo insta accept
# --- Update third-party licenses ---
echo "==> Regenerating third-party licenses..."
cd "${REPO_ROOT}/third-party-licenses"
cargo about generate --locked -m ../Cargo.toml about.hbs > licenses.html
cd "$REPO_ROOT"
# --- Commit release changes ---
git add -A
git commit -m "release: v${VERSION}"
echo "==> Done. Review the commit, push your branch, and open a PR against the release-source branch."