You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hamilton.apache.org by je...@apache.org on 2026/08/13 08:34:40 UTC
(hamilton) branch main updated: Add tag_release.sh for final (non-RC) release tags + document step (#1663)
This is an automated email from the ASF dual-hosted git repository.
jernejfrank pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hamilton.git
The following commit(s) were added to refs/heads/main by this push:
new a55e214b Add tag_release.sh for final (non-RC) release tags + document step (#1663)
a55e214b is described below
commit a55e214b0cd6b1d44f06170698a32599ac1efe62
Author: Stefan Krawczyk <st...@cs.stanford.edu>
AuthorDate: Thu Aug 13 01:34:35 2026 -0700
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.
---
scripts/README.md | 34 +++++++++++++
scripts/tag_release.sh | 135 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 169 insertions(+)
diff --git a/scripts/README.md b/scripts/README.md
index dad0e69a..cc56edfb 100644
--- a/scripts/README.md
+++ b/scripts/README.md
@@ -59,6 +59,7 @@ The core `apache-hamilton` package must be released first. The other four packag
|---|---|
| `scripts/apache_release_helper.py` | Build artifacts, sign, tag, upload RC to SVN, generate vote email |
| `scripts/promote_rc.sh` | Move a voted RC from SVN dev to SVN release |
+| `scripts/tag_release.sh` | Create the final (non-RC) `-incubating` release tag on the merge commit |
| `scripts/verify_apache_artifacts.py` | Verify GPG signatures, checksums, and license headers |
| `scripts/verification-script.sh` | End-to-end RC validation (download, verify, build, test, examples) |
| `scripts/generate_announce_email.py` | Generate vote result, announcement email, and Slack message |
@@ -226,6 +227,39 @@ git commit -m "Release apache-hamilton ${VERSION}"
git push origin main
```
+#### 7. Create the final (non-RC) release tag
+
+The RC build created an `-incubating-RC${RC}` tag pointing at the commit the
+artifacts were built from (typically on the release branch). After the vote
+passes and the release branch is squash-merged to main (step 6), create a
+clean, RC-less release tag on the merge commit. This keeps the release tag
+reachable from `main` and gives GitHub release pages a sensible name --
+ASF mentors flag `-RC`-suffixed tags as poor release names.
+
+`scripts/tag_release.sh` creates an annotated `<package>-v<version>-incubating`
+tag on the target commit (default: current `HEAD`, i.e. the squash-merge
+commit on main). The original `-RC` tag is left intact as the record of
+exactly what was voted on.
+
+```bash
+# On main, at the squash-merge commit from step 6:
+scripts/tag_release.sh --push ${PACKAGE} ${VERSION}
+
+# Or tag a specific commit / hold off on pushing:
+scripts/tag_release.sh --commit <sha> ${PACKAGE} ${VERSION} # creates locally
+git push origin refs/tags/${PACKAGE}-v${VERSION}-incubating # push when ready
+```
+
+For a multi-package release (e.g. the apache-hamilton-{sdk,lsp,ui,contrib}
+sub-packages), run it once per package against the same merge commit:
+
+```bash
+scripts/tag_release.sh --push apache-hamilton-sdk 0.9.0
+scripts/tag_release.sh --push apache-hamilton-lsp 0.2.0
+scripts/tag_release.sh --push apache-hamilton-ui 0.0.18
+scripts/tag_release.sh --push apache-hamilton-contrib 0.0.9
+```
+
# For Voters: Verifying a Release
If you're voting on a release, you can either use the automated script or follow the
diff --git a/scripts/tag_release.sh b/scripts/tag_release.sh
new file mode 100755
index 00000000..857c5ff8
--- /dev/null
+++ b/scripts/tag_release.sh
@@ -0,0 +1,135 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Create the final (non-RC) release tag(s) for a voted Apache Hamilton release.
+#
+# During the RC build, apache_release_helper.py creates a tag like
+# <package>-v<version>-incubating-RC<rc>
+# pointing at the commit the artifacts were built from. That RC commit often
+# lives only on the release branch. After the vote passes and the release
+# branch is squash-merged to main, the canonical release should be tagged
+# with a clean, RC-less name on the merge commit so:
+# - the tag is reachable from main
+# - GitHub release pages / archives resolve to a sensible name
+# (ASF mentors flag RC-suffixed tags as poor release names)
+#
+# This script creates (and optionally pushes) an annotated tag
+# <package>-v<version>-incubating
+# on a target commit (default: current HEAD, expected to be main at the
+# squash-merge commit). The original -RC tag is left intact as the record
+# of exactly what was voted on.
+#
+# Usage:
+# scripts/tag_release.sh [--commit <sha>] [--remote <name>] [--push] \
+# <package> <version>
+#
+# package : one of apache-hamilton, apache-hamilton-sdk,
+# apache-hamilton-lsp, apache-hamilton-ui, apache-hamilton-contrib
+# version : e.g. 0.9.0
+#
+# Examples:
+# # dry: create the tag locally on current HEAD, don't push
+# scripts/tag_release.sh apache-hamilton-sdk 0.9.0
+#
+# # create on a specific commit and push to origin
+# scripts/tag_release.sh --commit 1a2b3c4 --push apache-hamilton-sdk 0.9.0
+
+set -eu
+
+REMOTE="origin"
+COMMIT="HEAD"
+PUSH="false"
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --commit) COMMIT="$2"; shift 2 ;;
+ --remote) REMOTE="$2"; shift 2 ;;
+ --push) PUSH="true"; shift ;;
+ --) shift; break ;;
+ -*) echo "Unknown option: $1" >&2; exit 1 ;;
+ *) break ;;
+ esac
+done
+
+if [ $# -ne 2 ]; then
+ echo "Usage: $0 [--commit <sha>] [--remote <name>] [--push] <package> <version>" >&2
+ echo " package: apache-hamilton | apache-hamilton-sdk | apache-hamilton-lsp | apache-hamilton-ui | apache-hamilton-contrib" >&2
+ exit 1
+fi
+
+PACKAGE="$1"
+VERSION="$2"
+
+case "$PACKAGE" in
+ apache-hamilton|apache-hamilton-sdk|apache-hamilton-lsp|apache-hamilton-ui|apache-hamilton-contrib) ;;
+ *) echo "ERROR: unknown package '$PACKAGE'" >&2; exit 1 ;;
+esac
+
+TAG="${PACKAGE}-v${VERSION}-incubating"
+RC_TAG_GLOB="${PACKAGE}-v${VERSION}-incubating-RC*"
+
+# Resolve target commit
+TARGET_SHA="$(git rev-parse --verify "${COMMIT}^{commit}")"
+
+echo "Package: ${PACKAGE}"
+echo "Version: ${VERSION}"
+echo "Release tag: ${TAG}"
+echo "Target commit ${TARGET_SHA}"
+echo
+
+# Sanity: warn if the target commit is not on main
+if git rev-parse --verify main >/dev/null 2>&1; then
+ if git merge-base --is-ancestor "${TARGET_SHA}" main; then
+ echo " OK: target commit is reachable from main."
+ else
+ echo " WARNING: target commit is NOT reachable from 'main'."
+ echo " The final release tag should point at the squash-merge"
+ echo " commit on main. Continue only if you know what you're doing."
+ fi
+fi
+
+# Show the RC tag(s) for reference (what was voted on)
+RC_TAGS="$(git tag -l "${RC_TAG_GLOB}" || true)"
+if [ -n "${RC_TAGS}" ]; then
+ echo " RC tag(s) for this release (kept as-is):"
+ for t in ${RC_TAGS}; do
+ echo " ${t} -> $(git rev-list -n1 "$t")"
+ done
+fi
+echo
+
+# Refuse to clobber an existing final tag
+if git rev-parse --verify "refs/tags/${TAG}" >/dev/null 2>&1; then
+ echo "ERROR: tag '${TAG}' already exists (-> $(git rev-list -n1 "${TAG}"))." >&2
+ echo " Delete it first if you intend to move it: git tag -d ${TAG}" >&2
+ exit 1
+fi
+
+# Create the annotated tag
+git tag -a "${TAG}" "${TARGET_SHA}" -m "Apache ${PACKAGE} ${VERSION}-incubating"
+echo "Created annotated tag ${TAG} -> ${TARGET_SHA}"
+
+if [ "${PUSH}" = "true" ]; then
+ echo "Pushing ${TAG} to ${REMOTE}..."
+ git push "${REMOTE}" "refs/tags/${TAG}"
+ echo "Pushed."
+else
+ echo
+ echo "Tag created locally. To push:"
+ echo " git push ${REMOTE} refs/tags/${TAG}"
+fi