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