Skip to content

Commit a55e214

Browse files
authored
Add tag_release.sh for final (non-RC) release tags + document step (#1663)
After a release vote passes and the release branch is squash-merged to main, the canonical release should be tagged with a clean, RC-less name (<package>-v<version>-incubating) on the merge commit. Previously the only tag was the -RC tag from the RC build, which points at an off-main commit and makes a poor GitHub release name (flagged by ASF mentors). - scripts/tag_release.sh: create + optionally push the annotated final tag; validates the package name, warns if the target commit isn't on main, refuses to clobber an existing tag, and leaves the -RC tag intact. - scripts/README.md: add step 7 (create final release tag) to the finalize sequence and list the script in the scripts table.
1 parent 9d8f577 commit a55e214

2 files changed

Lines changed: 169 additions & 0 deletions

File tree

scripts/README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ The core `apache-hamilton` package must be released first. The other four packag
5959
|---|---|
6060
| `scripts/apache_release_helper.py` | Build artifacts, sign, tag, upload RC to SVN, generate vote email |
6161
| `scripts/promote_rc.sh` | Move a voted RC from SVN dev to SVN release |
62+
| `scripts/tag_release.sh` | Create the final (non-RC) `-incubating` release tag on the merge commit |
6263
| `scripts/verify_apache_artifacts.py` | Verify GPG signatures, checksums, and license headers |
6364
| `scripts/verification-script.sh` | End-to-end RC validation (download, verify, build, test, examples) |
6465
| `scripts/generate_announce_email.py` | Generate vote result, announcement email, and Slack message |
@@ -226,6 +227,39 @@ git commit -m "Release apache-hamilton ${VERSION}"
226227
git push origin main
227228
```
228229

230+
#### 7. Create the final (non-RC) release tag
231+
232+
The RC build created an `-incubating-RC${RC}` tag pointing at the commit the
233+
artifacts were built from (typically on the release branch). After the vote
234+
passes and the release branch is squash-merged to main (step 6), create a
235+
clean, RC-less release tag on the merge commit. This keeps the release tag
236+
reachable from `main` and gives GitHub release pages a sensible name --
237+
ASF mentors flag `-RC`-suffixed tags as poor release names.
238+
239+
`scripts/tag_release.sh` creates an annotated `<package>-v<version>-incubating`
240+
tag on the target commit (default: current `HEAD`, i.e. the squash-merge
241+
commit on main). The original `-RC` tag is left intact as the record of
242+
exactly what was voted on.
243+
244+
```bash
245+
# On main, at the squash-merge commit from step 6:
246+
scripts/tag_release.sh --push ${PACKAGE} ${VERSION}
247+
248+
# Or tag a specific commit / hold off on pushing:
249+
scripts/tag_release.sh --commit <sha> ${PACKAGE} ${VERSION} # creates locally
250+
git push origin refs/tags/${PACKAGE}-v${VERSION}-incubating # push when ready
251+
```
252+
253+
For a multi-package release (e.g. the apache-hamilton-{sdk,lsp,ui,contrib}
254+
sub-packages), run it once per package against the same merge commit:
255+
256+
```bash
257+
scripts/tag_release.sh --push apache-hamilton-sdk 0.9.0
258+
scripts/tag_release.sh --push apache-hamilton-lsp 0.2.0
259+
scripts/tag_release.sh --push apache-hamilton-ui 0.0.18
260+
scripts/tag_release.sh --push apache-hamilton-contrib 0.0.9
261+
```
262+
229263
# For Voters: Verifying a Release
230264

231265
If you're voting on a release, you can either use the automated script or follow the

scripts/tag_release.sh

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#!/usr/bin/env bash
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing,
13+
# software distributed under the License is distributed on an
14+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
# KIND, either express or implied. See the License for the
16+
# specific language governing permissions and limitations
17+
# under the License.
18+
19+
# Create the final (non-RC) release tag(s) for a voted Apache Hamilton release.
20+
#
21+
# During the RC build, apache_release_helper.py creates a tag like
22+
# <package>-v<version>-incubating-RC<rc>
23+
# pointing at the commit the artifacts were built from. That RC commit often
24+
# lives only on the release branch. After the vote passes and the release
25+
# branch is squash-merged to main, the canonical release should be tagged
26+
# with a clean, RC-less name on the merge commit so:
27+
# - the tag is reachable from main
28+
# - GitHub release pages / archives resolve to a sensible name
29+
# (ASF mentors flag RC-suffixed tags as poor release names)
30+
#
31+
# This script creates (and optionally pushes) an annotated tag
32+
# <package>-v<version>-incubating
33+
# on a target commit (default: current HEAD, expected to be main at the
34+
# squash-merge commit). The original -RC tag is left intact as the record
35+
# of exactly what was voted on.
36+
#
37+
# Usage:
38+
# scripts/tag_release.sh [--commit <sha>] [--remote <name>] [--push] \
39+
# <package> <version>
40+
#
41+
# package : one of apache-hamilton, apache-hamilton-sdk,
42+
# apache-hamilton-lsp, apache-hamilton-ui, apache-hamilton-contrib
43+
# version : e.g. 0.9.0
44+
#
45+
# Examples:
46+
# # dry: create the tag locally on current HEAD, don't push
47+
# scripts/tag_release.sh apache-hamilton-sdk 0.9.0
48+
#
49+
# # create on a specific commit and push to origin
50+
# scripts/tag_release.sh --commit 1a2b3c4 --push apache-hamilton-sdk 0.9.0
51+
52+
set -eu
53+
54+
REMOTE="origin"
55+
COMMIT="HEAD"
56+
PUSH="false"
57+
58+
while [ $# -gt 0 ]; do
59+
case "$1" in
60+
--commit) COMMIT="$2"; shift 2 ;;
61+
--remote) REMOTE="$2"; shift 2 ;;
62+
--push) PUSH="true"; shift ;;
63+
--) shift; break ;;
64+
-*) echo "Unknown option: $1" >&2; exit 1 ;;
65+
*) break ;;
66+
esac
67+
done
68+
69+
if [ $# -ne 2 ]; then
70+
echo "Usage: $0 [--commit <sha>] [--remote <name>] [--push] <package> <version>" >&2
71+
echo " package: apache-hamilton | apache-hamilton-sdk | apache-hamilton-lsp | apache-hamilton-ui | apache-hamilton-contrib" >&2
72+
exit 1
73+
fi
74+
75+
PACKAGE="$1"
76+
VERSION="$2"
77+
78+
case "$PACKAGE" in
79+
apache-hamilton|apache-hamilton-sdk|apache-hamilton-lsp|apache-hamilton-ui|apache-hamilton-contrib) ;;
80+
*) echo "ERROR: unknown package '$PACKAGE'" >&2; exit 1 ;;
81+
esac
82+
83+
TAG="${PACKAGE}-v${VERSION}-incubating"
84+
RC_TAG_GLOB="${PACKAGE}-v${VERSION}-incubating-RC*"
85+
86+
# Resolve target commit
87+
TARGET_SHA="$(git rev-parse --verify "${COMMIT}^{commit}")"
88+
89+
echo "Package: ${PACKAGE}"
90+
echo "Version: ${VERSION}"
91+
echo "Release tag: ${TAG}"
92+
echo "Target commit ${TARGET_SHA}"
93+
echo
94+
95+
# Sanity: warn if the target commit is not on main
96+
if git rev-parse --verify main >/dev/null 2>&1; then
97+
if git merge-base --is-ancestor "${TARGET_SHA}" main; then
98+
echo " OK: target commit is reachable from main."
99+
else
100+
echo " WARNING: target commit is NOT reachable from 'main'."
101+
echo " The final release tag should point at the squash-merge"
102+
echo " commit on main. Continue only if you know what you're doing."
103+
fi
104+
fi
105+
106+
# Show the RC tag(s) for reference (what was voted on)
107+
RC_TAGS="$(git tag -l "${RC_TAG_GLOB}" || true)"
108+
if [ -n "${RC_TAGS}" ]; then
109+
echo " RC tag(s) for this release (kept as-is):"
110+
for t in ${RC_TAGS}; do
111+
echo " ${t} -> $(git rev-list -n1 "$t")"
112+
done
113+
fi
114+
echo
115+
116+
# Refuse to clobber an existing final tag
117+
if git rev-parse --verify "refs/tags/${TAG}" >/dev/null 2>&1; then
118+
echo "ERROR: tag '${TAG}' already exists (-> $(git rev-list -n1 "${TAG}"))." >&2
119+
echo " Delete it first if you intend to move it: git tag -d ${TAG}" >&2
120+
exit 1
121+
fi
122+
123+
# Create the annotated tag
124+
git tag -a "${TAG}" "${TARGET_SHA}" -m "Apache ${PACKAGE} ${VERSION}-incubating"
125+
echo "Created annotated tag ${TAG} -> ${TARGET_SHA}"
126+
127+
if [ "${PUSH}" = "true" ]; then
128+
echo "Pushing ${TAG} to ${REMOTE}..."
129+
git push "${REMOTE}" "refs/tags/${TAG}"
130+
echo "Pushed."
131+
else
132+
echo
133+
echo "Tag created locally. To push:"
134+
echo " git push ${REMOTE} refs/tags/${TAG}"
135+
fi

0 commit comments

Comments
 (0)