This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-graalvm-distro.git


The following commit(s) were added to refs/heads/main by this push:
     new 84c5857  Add post-vote release script (#24)
84c5857 is described below

commit 84c5857735298f795c1a8ac96f9e5fe1a15e087b
Author: 吴晟 Wu Sheng <[email protected]>
AuthorDate: Mon Mar 23 21:34:00 2026 +0800

    Add post-vote release script (#24)
---
 .github/workflows/ci.yml |  22 +-
 docs/menu.yml            |   2 +
 docs/release-guide.md    |  29 +++
 docs/version-mapping.md  |  12 +-
 release/post-vote.sh     | 643 +++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 691 insertions(+), 17 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c8392bd..a34ec09 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -87,7 +87,7 @@ jobs:
           fi
 
       - name: Set up GraalVM JDK 25
-        uses: graalvm/setup-graalvm@v1
+        uses: graalvm/setup-graalvm@eec48106e0bf45f2976c2ff0c3e22395cced8243  
# v1
         with:
           java-version: '25'
           distribution: 'graalvm'
@@ -120,7 +120,7 @@ jobs:
           submodules: recursive
 
       - name: Set up GraalVM JDK 25
-        uses: graalvm/setup-graalvm@v1
+        uses: graalvm/setup-graalvm@eec48106e0bf45f2976c2ff0c3e22395cced8243  
# v1
         with:
           java-version: '25'
           distribution: 'graalvm'
@@ -174,7 +174,7 @@ jobs:
           submodules: recursive
 
       - name: Set up GraalVM JDK 25
-        uses: graalvm/setup-graalvm@v1
+        uses: graalvm/setup-graalvm@eec48106e0bf45f2976c2ff0c3e22395cced8243  
# v1
         with:
           java-version: '25'
           distribution: 'graalvm'
@@ -194,11 +194,11 @@ jobs:
 
       - name: Set up Docker Buildx
         if: github.event_name != 'pull_request'
-        uses: docker/setup-buildx-action@v3
+        uses: 
docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f  # v3
 
       - name: Log in to GHCR
         if: github.event_name != 'pull_request'
-        uses: docker/login-action@v3
+        uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9  # 
v3
         with:
           registry: ghcr.io
           username: ${{ github.actor }}
@@ -206,7 +206,7 @@ jobs:
 
       - name: Log in to Docker Hub (release only)
         if: github.event_name != 'pull_request' && 
needs.init-skywalking.outputs.is-release == 'true'
-        uses: docker/login-action@v3
+        uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9  # 
v3
         with:
           username: ${{ secrets.DOCKERHUB_USER }}
           password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -214,7 +214,7 @@ jobs:
       - name: Build and push by digest (GHCR)
         if: github.event_name != 'pull_request'
         id: build-ghcr
-        uses: docker/build-push-action@v6
+        uses: 
docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8  # v6
         with:
           context: .
           file: docker/Dockerfile.native
@@ -226,7 +226,7 @@ jobs:
       - name: Build and push by digest (Docker Hub, release only)
         if: github.event_name != 'pull_request' && 
needs.init-skywalking.outputs.is-release == 'true'
         id: build-dockerhub
-        uses: docker/build-push-action@v6
+        uses: 
docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8  # v6
         with:
           context: .
           file: docker/Dockerfile.native
@@ -450,10 +450,10 @@ jobs:
           merge-multiple: true
 
       - name: Set up Docker Buildx
-        uses: docker/setup-buildx-action@v3
+        uses: 
docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f  # v3
 
       - name: Log in to GHCR
-        uses: docker/login-action@v3
+        uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9  # 
v3
         with:
           registry: ghcr.io
           username: ${{ github.actor }}
@@ -461,7 +461,7 @@ jobs:
 
       - name: Log in to Docker Hub (release only)
         if: needs.init-skywalking.outputs.is-release == 'true'
-        uses: docker/login-action@v3
+        uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9  # 
v3
         with:
           username: ${{ secrets.DOCKERHUB_USER }}
           password: ${{ secrets.DOCKERHUB_TOKEN }}
diff --git a/docs/menu.yml b/docs/menu.yml
index fb73c28..7dd4ea8 100644
--- a/docs/menu.yml
+++ b/docs/menu.yml
@@ -32,6 +32,8 @@ catalog:
         path: "/docker-image"
       - name: "Configuration"
         path: "/configuration"
+  - name: "Version Mapping"
+    path: "/version-mapping"
   - name: "Release Guide"
     path: "/release-guide"
   - name: "Architecture"
diff --git a/docs/release-guide.md b/docs/release-guide.md
index 42f6c6a..6d78a88 100644
--- a/docs/release-guide.md
+++ b/docs/release-guide.md
@@ -40,6 +40,7 @@ All scripts are in the `release/` directory:
 | `full-release.sh` | Automated end-to-end pipeline (recommended) |
 | `pre-release.sh` | Bump version, tag, bump to next SNAPSHOT |
 | `release.sh` | Package, sign, SVN upload, vote email |
+| `post-vote.sh` | After vote passes: SVN move, website PR |
 
 ## Automated Release (Recommended)
 
@@ -150,6 +151,31 @@ Send the generated vote email to 
`[email protected]`.
 
 The vote remains open for at least 72 hours and requires PMC approval.
 
+## After the Vote Passes
+
+Once the vote passes (72+ hours, PMC approval), run:
+
+```bash
+release/post-vote.sh 0.1.0
+```
+
+The script first shows a full briefing of all planned changes and asks for 
confirmation before
+executing anything. It then performs:
+
+| Step | What | Notes |
+|------|------|-------|
+| SVN move | `svn mv` from dist/dev to dist/release | Creates 
`dist/release/graalvm-distro/{version}/` |
+| Old release cleanup | Optionally remove older versions from dist/release | 
Apache policy: only keep latest; older releases auto-archived at 
archive.apache.org |
+| releases.yml | Add new version with `closer.cgi` / `downloads.apache.org` 
URLs | Migrates previous version URLs to `archive.apache.org/dist/` |
+| docs.yml | Add new version entry, update `Latest` commitId | Keeps all 
previous version entries |
+| Event post | Create 
`content/events/release-apache-skywalking-graalvm-distro-{version}/index.md` | 
Content from `changes/changes.md` |
+| PR | Create a single PR on `apache/skywalking-website` with all above 
changes | Branch: `graalvm-distro-{version}-release` |
+
+After the script completes:
+
+1. Review and merge the website PR
+2. Send `[ANNOUNCE]` email to `[email protected]`
+
 ## Quick Reference
 
 ```bash
@@ -162,4 +188,7 @@ git push origin v0.1.0            #    push tag (triggers 
CI)
 git push origin main              #    push next SNAPSHOT
                                   # 2. wait for CI to go green
 release/release.sh 0.1.0          # 3. package, sign, SVN upload, vote email
+
+# After vote passes
+release/post-vote.sh 0.1.0        # 4. SVN move, website PR
 ```
diff --git a/docs/version-mapping.md b/docs/version-mapping.md
index 910d8f3..bf764e3 100644
--- a/docs/version-mapping.md
+++ b/docs/version-mapping.md
@@ -8,11 +8,11 @@ Otherwise, it is shown as `{commit-id}-SNAPSHOT` indicating a 
development build
 <!-- DOC-CHECK: version-mapping-table -->
 | Distro Version | Apache SkyWalking Version |
 |---|---|
-| 0.1.0-rc0 | `2709c94ab3cc`-SNAPSHOT |
-| 0.1.0-rc1 | `2709c94ab3cc`-SNAPSHOT |
-| 0.1.0 | `64a1795d8a58`-SNAPSHOT |
-| 0.1.1 | `64a1795d8a58`-SNAPSHOT |
-| 0.2.0 | `64a1795d8a58`-SNAPSHOT |
-| 0.2.1 | `64a1795d8a58`-SNAPSHOT |
 | 0.3.0-SNAPSHOT (dev) | `726ebcc321db`-SNAPSHOT |
+| 0.2.1 | `64a1795d8a58`-SNAPSHOT |
+| 0.2.0 | `64a1795d8a58`-SNAPSHOT |
+| 0.1.1 | `64a1795d8a58`-SNAPSHOT |
+| 0.1.0 | `64a1795d8a58`-SNAPSHOT |
+| 0.1.0-rc1 | `2709c94ab3cc`-SNAPSHOT |
+| 0.1.0-rc0 | `2709c94ab3cc`-SNAPSHOT |
 <!-- END DOC-CHECK -->
diff --git a/release/post-vote.sh b/release/post-vote.sh
new file mode 100755
index 0000000..2df4e6d
--- /dev/null
+++ b/release/post-vote.sh
@@ -0,0 +1,643 @@
+#!/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.
+
+# Post-vote release script. Run AFTER the vote passes.
+#
+# What this script does:
+#   1. Show a full briefing of planned changes and ask for confirmation
+#   2. SVN move: dist/dev → dist/release (with version directory)
+#   3. Optionally remove oldest release from dist/release
+#   4. Clone apache/skywalking-website
+#   5. Update data/releases.yml (add new version, migrate old version URLs to 
archive)
+#   6. Update data/docs.yml (add new version entry)
+#   7. Create release event post in content/events/
+#   8. Create a PR on apache/skywalking-website combining all changes
+
+set -euo pipefail
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
+DISTRO_REPO="apache/skywalking-graalvm-distro"
+WEBSITE_REPO="apache/skywalking-website"
+
+SVN_DEV_BASE="https://dist.apache.org/repos/dist/dev/skywalking/graalvm-distro";
+SVN_RELEASE_BASE="https://dist.apache.org/repos/dist/release/skywalking/graalvm-distro";
+
+# URL patterns:
+#   Current release (latest):  
https://www.apache.org/dyn/closer.cgi/skywalking/...  (tarballs)
+#                               https://downloads.apache.org/skywalking/...    
       (asc, sha512)
+#   Archived releases (old):   https://archive.apache.org/dist/skywalking/...  
       (all files)
+
+# ─── Usage ───────────────────────────────────────────────────────────────────
+usage() {
+    cat <<EOF
+Usage: $0 <version>
+
+Post-vote release tasks for Apache SkyWalking GraalVM Distro.
+
+Run this AFTER the vote passes on [email protected].
+
+What this script does:
+  1. Brief you on all planned changes and ask for confirmation
+  2. SVN move from dist/dev to dist/release/{version}/
+  3. Optionally remove oldest release from dist/release (Apache policy: keep 
only latest)
+  4. Update apache/skywalking-website in a single PR:
+     - data/releases.yml  (add new version with closer.cgi URLs,
+                            migrate previous version URLs to 
archive.apache.org)
+     - data/docs.yml      (add new version entry, update Latest commitId)
+     - content/events/    (create release announcement from changes/changes.md)
+
+Prerequisites:
+  - Vote has passed on [email protected]
+  - gh CLI authenticated with permission to create PRs on ${WEBSITE_REPO}
+  - svn installed
+  - Tag v<version> exists in ${DISTRO_REPO}
+EOF
+    exit 1
+}
+
+# ─── Helpers ─────────────────────────────────────────────────────────────────
+log()   { echo "===> $*"; }
+error() { echo "ERROR: $*" >&2; exit 1; }
+
+# ─── Validate arguments ─────────────────────────────────────────────────────
+[[ $# -eq 1 ]] || usage
+VERSION="$1"
+TAG="v${VERSION}"
+
+# ─── Pre-flight checks ──────────────────────────────────────────────────────
+log "Pre-flight checks..."
+
+for cmd in git gh svn sed date python3; do
+    command -v "${cmd}" >/dev/null 2>&1 || error "'${cmd}' is not installed"
+done
+
+# Verify tag exists
+git rev-parse "${TAG}" >/dev/null 2>&1 \
+    || error "Tag ${TAG} not found locally. Run: git fetch --tags"
+
+# Verify changes/changes.md has release notes
+CHANGES_FILE="${REPO_ROOT}/changes/changes.md"
+[[ -f "${CHANGES_FILE}" ]] || error "changes/changes.md not found"
+grep -q "^## ${VERSION}$" "${CHANGES_FILE}" \
+    || error "changes/changes.md does not contain a '## ${VERSION}' section"
+
+# GitHub CLI auth
+gh auth status --hostname github.com >/dev/null 2>&1 \
+    || error "'gh' is not authenticated. Run: gh auth login"
+
+# Get the SkyWalking submodule commit for version display
+SW_COMMIT=$(git -C "${REPO_ROOT}" ls-tree "${TAG}" skywalking | awk '{print 
$3}')
+SW_COMMIT_SHORT="${SW_COMMIT:0:7}"
+
+# Get the distro tag commit for docs.yml
+TAG_COMMIT=$(git rev-parse "${TAG}")
+
+# Determine the upstream SkyWalking version label used in website entries
+# Format: X.Y.Z (10.3.0-dev-<short-commit>)
+SW_VERSION_RAW=$(git show "${TAG}:skywalking/pom.xml" 2>/dev/null \
+    | sed -n '/<version>/{s/.*<version>\(.*\)<\/version>.*/\1/;p;q;}')
+if [[ -n "${SW_VERSION_RAW}" ]]; then
+    VERSION_LABEL="${VERSION} (${SW_VERSION_RAW}-${SW_COMMIT_SHORT})"
+else
+    VERSION_LABEL="${VERSION}"
+fi
+
+# Format release date: "Mar. 23rd, 2026"
+RELEASE_DATE=$(date -u +"%b. %d, %Y")
+DAY=$(date -u +"%d")
+DAY_NUM=$((10#${DAY}))
+case "${DAY_NUM}" in
+    1|21|31) SUFFIX="st" ;;
+    2|22)    SUFFIX="nd" ;;
+    3|23)    SUFFIX="rd" ;;
+    *)       SUFFIX="th" ;;
+esac
+RELEASE_DATE=$(echo "${RELEASE_DATE}" | sed "s/ ${DAY},/ 
${DAY_NUM}${SUFFIX},/")
+
+TODAY=$(date -u +"%Y-%m-%d")
+
+# ─── Briefing: show all planned changes ─────────────────────────────────────
+SVN_DEV_DIR="${SVN_DEV_BASE}/${VERSION}"
+SVN_RELEASE_DIR="${SVN_RELEASE_BASE}/${VERSION}"
+
+ARTIFACT_PREFIX="apache-skywalking-graalvm-distro-${VERSION}"
+CLOSER_BASE="https://www.apache.org/dyn/closer.cgi/skywalking/graalvm-distro/${VERSION}";
+DOWNLOADS_BASE="https://downloads.apache.org/skywalking/graalvm-distro/${VERSION}";
+ARCHIVE_NEW_BASE="https://archive.apache.org/dist/skywalking/graalvm-distro/${VERSION}";
+
+EVENT_DIR_NAME="release-apache-skywalking-graalvm-distro-${VERSION}"
+
+echo ""
+echo 
"═══════════════════════════════════════════════════════════════════════════"
+echo "  POST-VOTE RELEASE PLAN — SkyWalking GraalVM Distro ${VERSION}"
+echo 
"═══════════════════════════════════════════════════════════════════════════"
+echo ""
+echo "  Release version : ${VERSION}"
+echo "  Version label   : ${VERSION_LABEL}"
+echo "  Git tag         : ${TAG}"
+echo "  Tag commit      : ${TAG_COMMIT}"
+echo "  SW submodule    : ${SW_COMMIT_SHORT}"
+echo "  Release date    : ${RELEASE_DATE}"
+echo ""
+echo "─── 1. SVN: Move from dist/dev to dist/release 
──────────────────────────"
+echo ""
+echo "  FROM: ${SVN_DEV_DIR}"
+echo "  TO:   ${SVN_RELEASE_DIR}"
+echo ""
+echo "─── 2. Website: data/releases.yml 
───────────────────────────────────────"
+echo ""
+echo "  ADD new version (${VERSION_LABEL}) with download URLs:"
+echo "    Source tarball : ${CLOSER_BASE}/${ARTIFACT_PREFIX}-src.tar.gz"
+echo "    Linux AMD64   : ${CLOSER_BASE}/${ARTIFACT_PREFIX}-linux-amd64.tar.gz"
+echo "    Linux ARM64   : ${CLOSER_BASE}/${ARTIFACT_PREFIX}-linux-arm64.tar.gz"
+echo "    MacOS ARM     : 
${CLOSER_BASE}/${ARTIFACT_PREFIX}-darwin-arm64.tar.gz"
+echo "    (asc/sha512 via downloads.apache.org)"
+echo ""
+echo "  MIGRATE previous version URLs:"
+echo "    closer.cgi/skywalking/...      → 
archive.apache.org/dist/skywalking/..."
+echo "    downloads.apache.org/skywalking/... → 
archive.apache.org/dist/skywalking/..."
+echo ""
+echo "─── 3. Website: data/docs.yml 
───────────────────────────────────────────"
+echo ""
+echo "  UPDATE 'Latest' commitId → ${TAG_COMMIT}"
+echo "  ADD new version entry: ${VERSION_LABEL}"
+echo "    link: /docs/skywalking-graalvm-distro/v${VERSION}/readme/"
+echo ""
+echo "─── 4. Website: content/events/ 
─────────────────────────────────────────"
+echo ""
+echo "  CREATE ${EVENT_DIR_NAME}/index.md"
+echo "  Content from: changes/changes.md ## ${VERSION} section"
+echo ""
+echo "─── 5. Website PR 
───────────────────────────────────────────────────────"
+echo ""
+echo "  Repository : ${WEBSITE_REPO}"
+echo "  Branch     : graalvm-distro-${VERSION}-release"
+echo "  All website changes combined in a single PR."
+echo ""
+echo 
"═══════════════════════════════════════════════════════════════════════════"
+echo ""
+read -r -p "Proceed with all the above? [y/N] " confirm
+[[ "${confirm}" =~ ^[Yy]$ ]] || { echo "Aborted."; exit 0; }
+echo ""
+
+# ─── Step 1: SVN credentials ────────────────────────────────────────────────
+read -r -p "Apache SVN username (LDAP): " SVN_USER
+[[ -n "${SVN_USER}" ]] || error "SVN username is required"
+read -r -s -p "Apache SVN password: " SVN_PASS
+echo ""
+[[ -n "${SVN_PASS}" ]] || error "SVN password is required"
+
+# ─── Step 2: SVN move from dist/dev to dist/release ─────────────────────────
+log "SVN: Verifying source exists in dist/dev..."
+svn info "${SVN_DEV_DIR}" --username "${SVN_USER}" --password "${SVN_PASS}" 
--non-interactive >/dev/null 2>&1 \
+    || error "SVN source not found: ${SVN_DEV_DIR}"
+
+# Create parent directory in dist/release if needed
+if ! svn info "${SVN_RELEASE_BASE}" --username "${SVN_USER}" --password 
"${SVN_PASS}" --non-interactive >/dev/null 2>&1; then
+    log "Creating ${SVN_RELEASE_BASE}..."
+    svn mkdir "${SVN_RELEASE_BASE}" \
+        -m "Create graalvm-distro directory in dist/release" \
+        --username "${SVN_USER}" --password "${SVN_PASS}" --non-interactive
+fi
+
+log "SVN: Moving dist/dev/${VERSION} → dist/release/${VERSION}..."
+svn mv "${SVN_DEV_DIR}" "${SVN_RELEASE_DIR}" \
+    -m "Release Apache SkyWalking GraalVM Distro ${VERSION}" \
+    --username "${SVN_USER}" --password "${SVN_PASS}" --non-interactive
+
+log "SVN move complete: ${SVN_RELEASE_DIR}"
+
+# ─── Step 3: Ask whether to remove oldest release from dist/release ─────────
+# Apache policy: only the latest release should remain in dist/release.
+# Older releases are auto-archived to archive.apache.org.
+echo ""
+log "Checking for older releases in dist/release..."
+
+# List existing version directories in dist/release
+EXISTING_VERSIONS=$(svn list "${SVN_RELEASE_BASE}" \
+    --username "${SVN_USER}" --password "${SVN_PASS}" --non-interactive 
2>/dev/null \
+    | sed 's|/$||' | sort -V)
+
+# Filter out the version we just released
+OLD_VERSIONS=""
+for v in ${EXISTING_VERSIONS}; do
+    if [[ "${v}" != "${VERSION}" ]]; then
+        OLD_VERSIONS="${OLD_VERSIONS}${v} "
+    fi
+done
+OLD_VERSIONS=$(echo "${OLD_VERSIONS}" | xargs)  # trim
+
+REMOVED_VERSIONS=""
+if [[ -n "${OLD_VERSIONS}" ]]; then
+    echo ""
+    echo "  Found older version(s) in dist/release: ${OLD_VERSIONS}"
+    echo "  Apache policy: only keep the latest release in dist/release."
+    echo "  Older versions are automatically archived at archive.apache.org."
+    echo ""
+    echo "  If removed, the website download links and doc links for these"
+    echo "  versions will also be removed from releases.yml and docs.yml."
+    echo ""
+    read -r -p "  Remove older version(s) from dist/release? [y/N] " remove_old
+    if [[ "${remove_old}" =~ ^[Yy]$ ]]; then
+        for old_ver in ${OLD_VERSIONS}; do
+            log "SVN: Removing ${SVN_RELEASE_BASE}/${old_ver}..."
+            svn rm "${SVN_RELEASE_BASE}/${old_ver}" \
+                -m "Remove old GraalVM Distro ${old_ver} from dist/release 
(archived at archive.apache.org)" \
+                --username "${SVN_USER}" --password "${SVN_PASS}" 
--non-interactive
+            log "Removed: ${old_ver}"
+            REMOVED_VERSIONS="${REMOVED_VERSIONS}${old_ver} "
+        done
+        REMOVED_VERSIONS=$(echo "${REMOVED_VERSIONS}" | xargs)
+    else
+        log "Keeping older versions in dist/release."
+    fi
+else
+    log "No older versions found in dist/release."
+fi
+
+# ─── Step 4: Clone skywalking-website and create branch ─────────────────────
+WORK_DIR="${SCRIPT_DIR}/release-package/website-pr"
+rm -rf "${WORK_DIR}"
+mkdir -p "${WORK_DIR}"
+
+log "Cloning ${WEBSITE_REPO}..."
+gh repo clone "${WEBSITE_REPO}" "${WORK_DIR}/skywalking-website" -- --depth 1
+
+cd "${WORK_DIR}/skywalking-website"
+
+BRANCH_NAME="graalvm-distro-${VERSION}-release"
+git checkout -b "${BRANCH_NAME}"
+
+# ─── Step 5: Update data/releases.yml ────────────────────────────────────────
+log "Updating data/releases.yml..."
+
+RELEASES_FILE="data/releases.yml"
+
+# Python script to:
+#   1. Add new version entry with closer.cgi / downloads.apache.org URLs
+#   2. For kept old versions: migrate URLs to archive.apache.org
+#   3. For removed versions: delete their entries entirely
+python3 <<'PYEOF'
+import sys
+
+releases_file = sys.argv[1]
+version = sys.argv[2]
+version_label = sys.argv[3]
+release_date = sys.argv[4]
+removed_versions = set(sys.argv[5].split()) if len(sys.argv) > 5 and 
sys.argv[5] else set()
+
+with open(releases_file, "r") as f:
+    content = f.read()
+
+prefix = f"apache-skywalking-graalvm-distro-{version}"
+closer_base = 
f"https://www.apache.org/dyn/closer.cgi/skywalking/graalvm-distro/{version}";
+downloads_base = 
f"https://downloads.apache.org/skywalking/graalvm-distro/{version}";
+
+# New version source block
+new_source_entry = f"""        - version: {version_label}
+          date: {release_date}
+          downloadLink:
+            - name: src
+              link: {closer_base}/{prefix}-src.tar.gz
+            - name: asc
+              link: {downloads_base}/{prefix}-src.tar.gz.asc
+            - name: sha512
+              link: {downloads_base}/{prefix}-src.tar.gz.sha512"""
+
+# New version distribution block
+new_dist_entry = f"""        - version: {version_label}
+          date: {release_date}
+          downloadLink:
+            - name: Linux AMD64
+              link: {closer_base}/{prefix}-linux-amd64.tar.gz
+            - name: asc
+              link: {downloads_base}/{prefix}-linux-amd64.tar.gz.asc
+            - name: sha512
+              link: {downloads_base}/{prefix}-linux-amd64.tar.gz.sha512
+            - name: "|"
+            - name: Linux ARM64
+              link: {closer_base}/{prefix}-linux-arm64.tar.gz
+            - name: asc
+              link: {downloads_base}/{prefix}-linux-arm64.tar.gz.asc
+            - name: sha512
+              link: {downloads_base}/{prefix}-linux-arm64.tar.gz.sha512
+            - name: "|"
+            - name: MacOS ARM
+              link: {closer_base}/{prefix}-darwin-arm64.tar.gz
+            - name: asc
+              link: {downloads_base}/{prefix}-darwin-arm64.tar.gz.asc
+            - name: sha512
+              link: {downloads_base}/{prefix}-darwin-arm64.tar.gz.sha512"""
+
+graalvm_marker = "A re-distribution of the Apache SkyWalking OAP server"
+
+def should_remove_entry(version_line):
+    """Check if a '- version: ...' line belongs to a removed version."""
+    for rv in removed_versions:
+        # Match version lines like "- version: 0.2.1 (10.3.0-dev-64a1795)"
+        # The version number appears right after "version: "
+        if f"- version: {rv} " in version_line or f"- version: {rv}" == 
version_line.strip():
+            return True
+    return False
+
+def process_old_entries(lines, i, stop_condition):
+    """Process old version entries: remove entries for removed versions,
+    migrate URLs to archive.apache.org for kept versions."""
+    kept = []
+    while i < len(lines):
+        old_line = lines[i]
+        old_stripped = old_line.lstrip()
+        old_indent = len(old_line) - len(old_stripped)
+
+        if stop_condition(old_stripped, old_indent):
+            break
+
+        # Check if this is a version entry that should be removed
+        if old_stripped.startswith("- version:") and 
should_remove_entry(old_stripped):
+            # Skip this entire version entry (version, date, downloadLink, and 
all items)
+            i += 1
+            while i < len(lines):
+                next_stripped = lines[i].lstrip()
+                next_indent = len(lines[i]) - len(next_stripped)
+                # Stop at the next version entry or section boundary
+                if next_stripped.startswith("- version:") or 
stop_condition(next_stripped, next_indent):
+                    break
+                i += 1
+            continue
+
+        # Keep the entry but migrate URLs to archive.apache.org
+        migrated = old_line
+        migrated = 
migrated.replace("https://www.apache.org/dyn/closer.cgi/skywalking/";, 
"https://archive.apache.org/dist/skywalking/";)
+        migrated = 
migrated.replace("https://downloads.apache.org/skywalking/";, 
"https://archive.apache.org/dist/skywalking/";)
+        kept.append(migrated)
+        i += 1
+
+    return kept, i
+
+lines = content.split("\n")
+result = []
+i = 0
+in_graalvm = False
+inserted_source = False
+inserted_dist = False
+
+while i < len(lines):
+    line = lines[i]
+
+    if graalvm_marker in line:
+        in_graalvm = True
+        result.append(line)
+        i += 1
+        continue
+
+    if in_graalvm:
+        stripped = line.lstrip()
+        indent = len(line) - len(stripped)
+
+        # Found "source:" key — prepend new entry, process old entries
+        if not inserted_source and stripped == "source:" and indent == 6:
+            result.append(line)  # keep "      source:"
+            result.append(new_source_entry)
+            inserted_source = True
+            i += 1
+
+            def source_stop(s, ind):
+                if ind == 6 and s.startswith("distribution:"):
+                    return True
+                if ind <= 6 and s and s not in ("") \
+                   and not s.startswith("-") and not s.startswith("version:") \
+                   and not s.startswith("date:") and not 
s.startswith("downloadLink:") \
+                   and not s.startswith("name:") and not s.startswith("link:"):
+                    return True
+                return False
+
+            kept, i = process_old_entries(lines, i, source_stop)
+            result.extend(kept)
+            continue
+
+        # Found "distribution:" key — prepend new entry, process old entries
+        if not inserted_dist and stripped == "distribution:" and indent == 6:
+            result.append(line)  # keep "      distribution:"
+            result.append(new_dist_entry)
+            inserted_dist = True
+            i += 1
+
+            def dist_stop(s, ind):
+                return ind <= 4 and bool(s)
+
+            kept, i = process_old_entries(lines, i, dist_stop)
+            result.extend(kept)
+            in_graalvm = False
+            continue
+
+    result.append(line)
+    i += 1
+
+with open(releases_file, "w") as f:
+    f.write("\n".join(result))
+
+actions = [f"added {version_label}"]
+if removed_versions:
+    actions.append(f"removed {', '.join(sorted(removed_versions))}")
+actions.append("migrated kept old version URLs to archive.apache.org")
+print(f"releases.yml: {'; '.join(actions)}")
+PYEOF
+"${RELEASES_FILE}" "${VERSION}" "${VERSION_LABEL}" "${RELEASE_DATE}" 
"${REMOVED_VERSIONS}"
+
+# ─── Step 6: Update data/docs.yml ────────────────────────────────────────────
+log "Updating data/docs.yml..."
+
+DOCS_FILE="data/docs.yml"
+
+python3 <<'PYEOF'
+import sys
+
+docs_file = sys.argv[1]
+version = sys.argv[2]
+version_label = sys.argv[3]
+tag_commit = sys.argv[4]
+removed_versions = set(sys.argv[5].split()) if len(sys.argv) > 5 and 
sys.argv[5] else set()
+
+with open(docs_file, "r") as f:
+    content = f.read()
+
+def is_removed_version(version_line):
+    """Check if a '- version: ...' line belongs to a removed version."""
+    for rv in removed_versions:
+        if f"- version: v{rv} " in version_line or f"- version: v{rv}" == 
version_line.strip():
+            return True
+        if f"- version: {rv} " in version_line or f"- version: {rv}" == 
version_line.strip():
+            return True
+    return False
+
+lines = content.split("\n")
+result = []
+i = 0
+graalvm_marker = "A re-distribution of the Apache SkyWalking OAP server"
+in_graalvm = False
+in_docs = False
+found_latest = False
+inserted_new = False
+
+while i < len(lines):
+    line = lines[i]
+
+    if graalvm_marker in line:
+        in_graalvm = True
+        result.append(line)
+        i += 1
+        continue
+
+    if in_graalvm and "docs:" in line and not in_docs:
+        in_docs = True
+        result.append(line)
+        i += 1
+        continue
+
+    if in_graalvm and in_docs:
+        stripped = line.lstrip()
+
+        # Found "- version: Latest" — update its commitId
+        if stripped.startswith("- version: Latest"):
+            result.append(line)
+            i += 1
+            # Next line should be link
+            if i < len(lines) and "link:" in lines[i]:
+                result.append(lines[i])
+                i += 1
+            # Next line should be commitId — replace it
+            if i < len(lines) and "commitId:" in lines[i]:
+                indent = len(lines[i]) - len(lines[i].lstrip())
+                result.append(" " * indent + "commitId: " + tag_commit)
+                i += 1
+            found_latest = True
+            continue
+
+        # After Latest, before the first versioned entry, insert new version
+        if found_latest and not inserted_new and stripped.startswith("- 
version:"):
+            indent = len(line) - len(stripped)
+            result.append(" " * indent + f"- version: {version_label}")
+            result.append(" " * indent + f"  link: 
/docs/skywalking-graalvm-distro/v{version}/readme/")
+            result.append(" " * indent + f"  commitId: {tag_commit}")
+            inserted_new = True
+            # Fall through to check if the current entry should be removed
+
+        # Skip version entries for removed versions
+        if stripped.startswith("- version:") and is_removed_version(stripped):
+            i += 1
+            # Skip the link and commitId lines that follow
+            while i < len(lines):
+                next_stripped = lines[i].lstrip()
+                if next_stripped.startswith("- version:") or \
+                   (next_stripped and not next_stripped.startswith("link:") \
+                    and not next_stripped.startswith("commitId:")):
+                    break
+                i += 1
+            continue
+
+        # Detect end of docs section
+        if inserted_new and stripped and not stripped.startswith("-") \
+           and not stripped.startswith("version:") and not 
stripped.startswith("link:") \
+           and not stripped.startswith("commitId:"):
+            indent_level = len(line) - len(stripped)
+            if indent_level <= 4:
+                in_graalvm = False
+                in_docs = False
+
+    result.append(line)
+    i += 1
+
+with open(docs_file, "w") as f:
+    f.write("\n".join(result))
+
+actions = [f"added {version_label}", "updated Latest commitId"]
+if removed_versions:
+    actions.append(f"removed doc entries for {', 
'.join(sorted(removed_versions))}")
+print(f"docs.yml: {'; '.join(actions)}")
+PYEOF
+"${DOCS_FILE}" "${VERSION}" "${VERSION_LABEL}" "${TAG_COMMIT}" 
"${REMOVED_VERSIONS}"
+
+# ─── Step 7: Create release event post ──────────────────────────────────────
+log "Creating release event post..."
+
+EVENT_DIR="content/events/${EVENT_DIR_NAME}"
+mkdir -p "${EVENT_DIR}"
+
+# Extract release notes from changes/changes.md (the section for this version)
+RELEASE_NOTES=$(sed -n "/^## ${VERSION}$/,/^## /p" "${CHANGES_FILE}" | sed 
'1d;/^## /d')
+
+# Calculate end time (~2 months from now)
+if date -v+2m >/dev/null 2>&1; then
+    END_DATE=$(date -v+2m -u +"%Y-%m-%dT00:00:00Z")
+else
+    END_DATE=$(date -u -d "+2 months" +"%Y-%m-%dT00:00:00Z")
+fi
+
+cat > "${EVENT_DIR}/index.md" <<EVENTEOF
+---
+title: Release Apache SkyWalking GraalVM Distro version ${VERSION}
+date: ${TODAY}
+author: SkyWalking Team
+description: "Release Apache SkyWalking GraalVM Distro ${VERSION}"
+endTime: ${END_DATE}
+---
+
+SkyWalking GraalVM Distro ${VERSION} is released. Go to 
[downloads](https://skywalking.apache.org/downloads/#SkyWalkingGraalVMDistro) 
page to find release tars.
+
+${RELEASE_NOTES}
+EVENTEOF
+
+log "Event post created: ${EVENT_DIR}/index.md"
+
+# ─── Step 8: Commit and create PR ───────────────────────────────────────────
+log "Creating PR on ${WEBSITE_REPO}..."
+
+git add data/releases.yml data/docs.yml "${EVENT_DIR}/index.md"
+git commit -m "Add SkyWalking GraalVM Distro ${VERSION} release"
+
+git push -u origin "${BRANCH_NAME}"
+
+PR_URL=$(gh pr create \
+    --repo "${WEBSITE_REPO}" \
+    --title "Add SkyWalking GraalVM Distro ${VERSION} release" \
+    --body "$(cat <<EOF
+## Summary
+
+- Update \`data/releases.yml\`: add ${VERSION} download links (closer.cgi), 
migrate previous version URLs to archive.apache.org${REMOVED_VERSIONS:+, remove 
entries for ${REMOVED_VERSIONS}}
+- Update \`data/docs.yml\`: add ${VERSION} documentation version, update 
Latest commitId${REMOVED_VERSIONS:+, remove doc entries for ${REMOVED_VERSIONS}}
+- Add release event post for ${VERSION}
+
+Release notes: 
https://github.com/${DISTRO_REPO}/blob/v${VERSION}/changes/changes.md
+EOF
+)" \
+    --base master \
+    --head "${BRANCH_NAME}" \
+    2>&1)
+
+log "PR created: ${PR_URL}"
+
+# ─── Summary ─────────────────────────────────────────────────────────────────
+echo ""
+log "Post-vote release tasks complete!"
+echo ""
+echo "  SVN release : ${SVN_RELEASE_DIR}"
+echo "  Website PR  : ${PR_URL}"
+echo ""
+echo "Next steps:"
+echo "  1. Review and merge the website PR"
+echo "  2. Send [ANNOUNCE] email to [email protected]"


Reply via email to