This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git
The following commit(s) were added to refs/heads/master by this push:
new 36bbb29250 Automate release process with unified release.sh (#13744)
36bbb29250 is described below
commit 36bbb292500c7217f12cc162f2963e1da87d4ca5
Author: 吴晟 Wu Sheng <[email protected]>
AuthorDate: Sun Mar 15 11:44:56 2026 +0800
Automate release process with unified release.sh (#13744)
Replaces the separate `create_release_tars.sh` and `start_next_version.sh`
scripts with a single interactive `release.sh` that automates the full release
workflow end-to-end:
1. GPG signer verification (`@apache.org` required)
2. Required tools check (`gpg`, `svn`, `shasum`, `git`, `yq`)
3. Version detection from `pom.xml`
4. Release/next version calculation (strip `-SNAPSHOT`, bump minor)
5. Single git clone → build source/binary tarballs → GPG sign → SHA512
6. Upload to SVN staging
7. Vote email generation (sha512 checksums + submodule commit IDs
auto-filled)
8. Next version PR preparation (version bump, changelog rotation, menu.yml
update)
Key improvements over the old scripts:
- **Single clone** instead of two separate clones
- **No manual version export** — auto-detected from `pom.xml`
- **Vote email fully populated** — submodule commit IDs resolved
automatically
- **SVN upload automated** — no manual folder creation/upload
- **Interactive confirmations** for GPG signer and version numbers
---
docs/en/guides/How-to-release.md | 94 ++-------
tools/releasing/.gitignore | 3 +
tools/releasing/create_release_tars.sh | 90 --------
tools/releasing/release.sh | 369 +++++++++++++++++++++++++++++++++
tools/releasing/start_next_version.sh | 80 -------
5 files changed, 388 insertions(+), 248 deletions(-)
diff --git a/docs/en/guides/How-to-release.md b/docs/en/guides/How-to-release.md
index 4bee867f0d..3f6edf15d0 100644
--- a/docs/en/guides/How-to-release.md
+++ b/docs/en/guides/How-to-release.md
@@ -8,92 +8,30 @@ Add your GPG public key into the [SkyWalking GPG
KEYS](https://dist.apache.org/r
- If you are a PMC member, use your Apache ID and password to log in this svn,
and update the file. **Don't override the existing file.**
- If you are a committer, please ask a PMC member to help you.
-## Create artifacts for the release
+## Run the release script
-- Create a new empty folder to do the release work.
-- Set the version numbers and run the release script file
[`tools/releasing/create_release_tars.sh`](https://github.com/apache/skywalking/blob/master/tools/releasing/create_release_tars.sh)
+The release script
[`tools/releasing/release.sh`](https://github.com/apache/skywalking/blob/master/tools/releasing/release.sh)
automates the following steps:
-```bash
-export RELEASE_VERSION=x.y.z # (example: RELEASE_VERSION=10.1.0)
-export NEXT_RELEASE_VERSION=x.y.z # (example: NEXT_RELEASE_VERSION=10.2.0)
-curl -Ls
https://raw.githubusercontent.com/apache/skywalking/refs/heads/master/tools/releasing/create_release_tars.sh
| bash -
-```
-
-After all the steps are completed, you will have the following files in the
folder:
-
-```text
-apache-skywalking-apm-${RELEASE_VERSION}-bin.tar.gz
-apache-skywalking-apm-${RELEASE_VERSION}-bin.tar.gz.asc
-apache-skywalking-apm-${RELEASE_VERSION}-bin.tar.gz.sha512
-apache-skywalking-apm-${RELEASE_VERSION}-src.tar.gz
-apache-skywalking-apm-${RELEASE_VERSION}-src.tar.gz.asc
-apache-skywalking-apm-${RELEASE_VERSION}-src.tar.gz.sha512
-```
-
-## Start the next iteration
-
-Once the binary and source packages are created, you can start updating the
version to the next number and open a pull request.
+1. Verify GPG signer (`@apache.org` email required)
+2. Check required tools (`gpg`, `svn`, `shasum`, `git`, `yq`)
+3. Detect current version from `pom.xml`
+4. Calculate release version (strip `-SNAPSHOT`) and next version (bump minor)
+5. Clone the repository, build source and binary tarballs, GPG sign, SHA512
checksum
+6. Upload artifacts to SVN staging
(`https://dist.apache.org/repos/dist/dev/skywalking/{version}`)
+7. Generate the vote email (with sha512 checksums and submodule commit IDs
filled in)
+8. Prepare next version PR (bump version, rotate changelog, update `menu.yml`,
push branch)
```bash
-curl -Ls
https://raw.githubusercontent.com/apache/skywalking/refs/heads/master/tools/releasing/start_next_version.sh
| bash -
+cd tools/releasing
+bash release.sh
```
-## Upload to Apache svn
-1. Use your Apache ID to log in to
`https://dist.apache.org/repos/dist/dev/skywalking/`.
-1. Create a folder and name it by the release version and round, such as:
`x.y.z`
-1. Upload the source code package to the folder with files ending with `.asc`
and `.sha512`.
- * Package name: `apache-skywalking-x.y.z-src.tar.gz`
- * See Section "Build and sign the source code package" for more details
-1. Upload the distribution package to the folder with files ending with `.asc`
and `.sha512`.
- * Package name: `apache-skywalking-bin-x.y.z.tar.gz`.
- * Create a `.sha512` package: `shasum -a 512 file > file.sha512`
-
-## Call a vote in dev
-Call a vote in `[email protected]`
-
-```
-Mail title: [VOTE] Release Apache SkyWalking version x.y.z
-
-Mail content:
-Hi All,
-This is a call for vote to release Apache SkyWalking version x.y.z.
-
-Release notes:
-
- *
https://github.com/apache/skywalking/blob/master/docs/en/changes/changes-x.y.z.md
-
-Release Candidate:
-
- * https://dist.apache.org/repos/dist/dev/skywalking/xxxx
- * sha512 checksums
- - sha512xxxxyyyzzz apache-skywalking-apm-x.x.x-src.tgz
- - sha512xxxxyyyzzz apache-skywalking-apm-bin-x.x.x.tar.gz
-
-Release Tag :
-
- * (Git Tag) vx.y.z
-
-Release CommitID :
+The script is interactive — it confirms the GPG signer and version numbers
before proceeding.
- * https://github.com/apache/skywalking/tree/(Git Commit ID)
- * Git submodule
- * skywalking-ui: https://github.com/apache/skywalking-booster-ui/tree/(Git
Commit ID)
- * apm-protocol/apm-network/src/main/proto:
https://github.com/apache/skywalking-data-collect-protocol/tree/(Git Commit ID)
- *
oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
https://github.com/apache/skywalking-query-protocol/tree/(Git Commit ID)
+After the script completes, copy the generated vote email and send it to
`[email protected]`.
-Keys to verify the Release Candidate :
-
- * https://dist.apache.org/repos/dist/release/skywalking/KEYS
-
-Guide to build the release from source :
-
- *
https://github.com/apache/skywalking/blob/vx.y.z/docs/en/guides/How-to-build.md
-
-Voting will start now (xxxx date) and will remain open for at least 72 hours,
Request all PMC members to give their vote.
-[ ] +1 Release this package.
-[ ] +0 No opinion.
-[ ] -1 Do not release this package because....
-```
+## Call a vote in dev
+The release script generates the vote email automatically. Send it to
`[email protected]`.
## Vote Check
All PMC members and committers should check these before casting +1 votes.
diff --git a/tools/releasing/.gitignore b/tools/releasing/.gitignore
new file mode 100644
index 0000000000..8e479cb34f
--- /dev/null
+++ b/tools/releasing/.gitignore
@@ -0,0 +1,3 @@
+skywalking/
+svn-staging/
+apache-skywalking-apm-*
diff --git a/tools/releasing/create_release_tars.sh
b/tools/releasing/create_release_tars.sh
deleted file mode 100755
index fb55ea9795..0000000000
--- a/tools/releasing/create_release_tars.sh
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/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.
-#
-
-# This script relies on few environment variables to determine source code
package
-# behavior, those variables are:
-# RELEASE_VERSION -- The version of this source package.
-# NEXT_RELEASE_VERSION -- The version of the next release.
-# For example: RELEASE_VERSION=10.0.0, NEXT_RELEASE_VERSION=10.0.1
-
-set -e -o pipefail
-
-if [ "$RELEASE_VERSION" == "" ] || [ "$NEXT_RELEASE_VERSION" == "" ]; then
- echo "RELEASE_VERSION or NEXT_RELEASE_VERSION environment variable not
found."
- echo "Please set the RELEASE_VERSION and NEXT_RELEASE_VERSION."
- echo "For example: export RELEASE_VERSION=10.0.0"
- echo " : export NEXT_RELEASE_VERSION=10.0.1"
- exit 1
-fi
-
-PRODUCT_NAME="apache-skywalking-apm"
-TAG=v${RELEASE_VERSION}
-SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
-MVN=${MVN:-./mvnw}
-
-if [ -d "skywalking" ]; then
- rm -rf skywalking
-fi
-
-echo "Cloning the repository..."
-git clone --recurse-submodules -j4 --depth 1
https://github.com/apache/skywalking.git && cd skywalking
-
-echo "Checking out the release branch ${RELEASE_VERSION}-release..."
-git checkout -b ${RELEASE_VERSION}-release
-
-log_file=$(mktemp)
-echo "Setting the release version ${RELEASE_VERSION} in pom.xml, log file:
${log_file}"
-${MVN} versions:set-property -DgenerateBackupPoms=false -Dproperty=revision
-DnewVersion=${RELEASE_VERSION} > ${log_file} 2>&1
-
-echo "Committing the pom.xml changes..."
-git add pom.xml
-git commit -m "Prepare for release ${RELEASE_VERSION}"
-
-echo "Creating the release tag ${TAG}..."
-git tag ${TAG}
-
-echo "Pushing the release tag ${TAG} to the remote repository..."
-git push --set-upstream origin ${TAG}
-
-log_file=$(mktemp)
-echo "Generating a static version.properties, log file: ${log_file}"
-${MVN} -q -pl oap-server/server-starter -am initialize \
-
-DgenerateGitPropertiesFilename="$(pwd)/oap-server/server-starter/src/main/resources/version.properties"
> ${log_file} 2>&1
-
-echo "Creating the release source artifacts..."
-tar czf "${SCRIPT_DIR}"/${PRODUCT_NAME}-${RELEASE_VERSION}-src.tar.gz \
- --exclude .git \
- --exclude .DS_Store \
- --exclude .github \
- --exclude .gitignore \
- --exclude .gitmodules \
- --exclude .mvn/wrapper/maven-wrapper.jar \
- .
-
-log_file=$(mktemp)
-echo "Building the release binary artifacts, log file: ${log_file}"
-${MVN} install package -DskipTests > ${log_file} 2>&1
-mv "${SCRIPT_DIR}"/skywalking/dist/${PRODUCT_NAME}-bin.tar.gz
./${PRODUCT_NAME}-${RELEASE_VERSION}-bin.tar.gz
-
-cd "${SCRIPT_DIR}"
-gpg --armor --detach-sig ${PRODUCT_NAME}-${RELEASE_VERSION}-src.tar.gz
-gpg --armor --detach-sig ${PRODUCT_NAME}-${RELEASE_VERSION}-bin.tar.gz
-
-shasum -a 512 ${PRODUCT_NAME}-${RELEASE_VERSION}-src.tar.gz >
${PRODUCT_NAME}-${RELEASE_VERSION}-src.tar.gz.sha512
-shasum -a 512 ${PRODUCT_NAME}-${RELEASE_VERSION}-bin.tar.gz >
${PRODUCT_NAME}-${RELEASE_VERSION}-bin.tar.gz.sha512
diff --git a/tools/releasing/release.sh b/tools/releasing/release.sh
new file mode 100755
index 0000000000..e1568d1976
--- /dev/null
+++ b/tools/releasing/release.sh
@@ -0,0 +1,369 @@
+#!/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.
+#
+
+# Apache SkyWalking release automation script.
+# Usage: bash release.sh
+
+set -e -o pipefail
+
+SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
+PROJECT_DIR=$(cd "${SCRIPT_DIR}/../.." && pwd)
+PRODUCT_NAME="apache-skywalking-apm"
+SVN_DEV_URL="https://dist.apache.org/repos/dist/dev/skywalking"
+CLONE_DIR="${SCRIPT_DIR}/skywalking"
+MVN=./mvnw
+
+# ========================== Shared functions ==========================
+
+clone_repo() {
+ cd "${SCRIPT_DIR}"
+ if [ -d "${CLONE_DIR}" ]; then
+ rm -rf "${CLONE_DIR}"
+ fi
+ echo "Cloning the repository..."
+ git clone --recurse-submodules -j4 --depth 1
https://github.com/apache/skywalking.git
+}
+
+build_release_artifacts() {
+ local TAG=v${RELEASE_VERSION}
+
+ cd "${CLONE_DIR}"
+
+ echo "Checking out the release branch ${RELEASE_VERSION}-release..."
+ git checkout -b ${RELEASE_VERSION}-release
+
+ log_file=$(mktemp)
+ echo "Setting the release version ${RELEASE_VERSION} in pom.xml, log file:
${log_file}"
+ ${MVN} versions:set-property -DgenerateBackupPoms=false
-Dproperty=revision -DnewVersion=${RELEASE_VERSION} > ${log_file} 2>&1
+
+ echo "Committing the pom.xml changes..."
+ git add pom.xml
+ git commit -m "Prepare for release ${RELEASE_VERSION}"
+
+ echo "Creating the release tag ${TAG}..."
+ git tag ${TAG}
+
+ echo "Pushing the release tag ${TAG} to the remote repository..."
+ git push --set-upstream origin ${TAG}
+
+ log_file=$(mktemp)
+ echo "Generating a static version.properties, log file: ${log_file}"
+ ${MVN} -q -pl oap-server/server-starter -am initialize \
+
-DgenerateGitPropertiesFilename="$(pwd)/oap-server/server-starter/src/main/resources/version.properties"
> ${log_file} 2>&1
+
+ echo "Creating the release source artifacts..."
+ tar czf "${SCRIPT_DIR}"/${PRODUCT_NAME}-${RELEASE_VERSION}-src.tar.gz \
+ --exclude .git \
+ --exclude .DS_Store \
+ --exclude .github \
+ --exclude .gitignore \
+ --exclude .gitmodules \
+ --exclude .mvn/wrapper/maven-wrapper.jar \
+ .
+
+ log_file=$(mktemp)
+ echo "Building the release binary artifacts, log file: ${log_file}"
+ ${MVN} install package -DskipTests > ${log_file} 2>&1
+ mv dist/${PRODUCT_NAME}-bin.tar.gz
"${SCRIPT_DIR}"/${PRODUCT_NAME}-${RELEASE_VERSION}-bin.tar.gz
+
+ cd "${SCRIPT_DIR}"
+
+ gpg --armor --detach-sig ${PRODUCT_NAME}-${RELEASE_VERSION}-src.tar.gz
+ gpg --armor --detach-sig ${PRODUCT_NAME}-${RELEASE_VERSION}-bin.tar.gz
+
+ shasum -a 512 ${PRODUCT_NAME}-${RELEASE_VERSION}-src.tar.gz >
${PRODUCT_NAME}-${RELEASE_VERSION}-src.tar.gz.sha512
+ shasum -a 512 ${PRODUCT_NAME}-${RELEASE_VERSION}-bin.tar.gz >
${PRODUCT_NAME}-${RELEASE_VERSION}-bin.tar.gz.sha512
+
+ echo "Release artifacts built successfully."
+}
+
+prepare_next_version() {
+ cd "${CLONE_DIR}"
+
+ echo "Setting the next release version ${NEXT_RELEASE_VERSION}-SNAPSHOT in
pom.xml..."
+ ${MVN} versions:set-property -DgenerateBackupPoms=false
-Dproperty=revision -DnewVersion=${NEXT_RELEASE_VERSION}-SNAPSHOT
+
+ echo "Committing the pom.xml changes..."
+ git add pom.xml
+ git commit -m "Update the next release version to
${NEXT_RELEASE_VERSION}-SNAPSHOT"
+
+ echo "Moving the changelog file..."
+ mv docs/en/changes/changes.md docs/en/changes/changes-${RELEASE_VERSION}.md
+
+ echo "Updating the changelog file..."
+ cat docs/en/changes/changes.tpl | sed
"s/NEXT_RELEASE_VERSION/${NEXT_RELEASE_VERSION}/g" > docs/en/changes/changes.md
+
+ echo "Committing the changelog files..."
+ git add docs
+ git commit -m "Update the changelog files"
+
+ echo "Updating the menu.yml file..."
+ local new_menu_file=$(mktemp)
+ local major_version=$(echo ${RELEASE_VERSION} | cut -d. -f1)
+ yq '(.catalog[] | select(.name=="Changelog") | .catalog[] |
select(.name=="'"${major_version}.x Releases"'") | .catalog) |= [{ "name":
"'"${RELEASE_VERSION}"'", "path": "/en/changes/changes-'${RELEASE_VERSION}'" }]
+ .' docs/menu.yml > ${new_menu_file}
+ mv ${new_menu_file} docs/menu.yml
+ git add docs
+ git commit -m "Update the menu.yml file"
+
+ echo "Pushing the changes to the remote repository..."
+ git push --set-upstream origin ${RELEASE_VERSION}-release
+
+ echo "Opening the PR..."
+ open
https://github.com/apache/skywalking/pull/new/${RELEASE_VERSION}-release
+}
+
+upload_to_svn() {
+ local SRC_TAR="${SCRIPT_DIR}/${PRODUCT_NAME}-${RELEASE_VERSION}-src.tar.gz"
+ local BIN_TAR="${SCRIPT_DIR}/${PRODUCT_NAME}-${RELEASE_VERSION}-bin.tar.gz"
+ local SVN_DIR="${SCRIPT_DIR}/svn-staging"
+ local SVN_VERSION_DIR="${SVN_DIR}/${RELEASE_VERSION}"
+
+ if [ -d "${SVN_DIR}" ]; then
+ rm -rf "${SVN_DIR}"
+ fi
+
+ echo "Checking out SVN dev directory..."
+ svn co --depth immediates "${SVN_DEV_URL}" "${SVN_DIR}"
+
+ if [ -d "${SVN_VERSION_DIR}" ]; then
+ echo "Version folder ${RELEASE_VERSION} already exists in SVN,
updating artifacts..."
+ svn update "${SVN_VERSION_DIR}"
+ else
+ mkdir -p "${SVN_VERSION_DIR}"
+ cd "${SVN_DIR}"
+ svn add "${RELEASE_VERSION}"
+ fi
+
+ cp "${SRC_TAR}" "${SRC_TAR}.asc" "${SRC_TAR}.sha512" "${SVN_VERSION_DIR}/"
+ cp "${BIN_TAR}" "${BIN_TAR}.asc" "${BIN_TAR}.sha512" "${SVN_VERSION_DIR}/"
+
+ cd "${SVN_DIR}"
+ svn add --force "${RELEASE_VERSION}"
+ svn commit -m "Upload Apache SkyWalking ${RELEASE_VERSION} release
candidate"
+
+ echo "Artifacts uploaded to: ${SVN_DEV_URL}/${RELEASE_VERSION}"
+
+ rm -rf "${SVN_DIR}"
+}
+
+generate_vote_email() {
+ local TAG=v${RELEASE_VERSION}
+ local SRC_TAR="${SCRIPT_DIR}/${PRODUCT_NAME}-${RELEASE_VERSION}-src.tar.gz"
+ local BIN_TAR="${SCRIPT_DIR}/${PRODUCT_NAME}-${RELEASE_VERSION}-bin.tar.gz"
+ local SRC_SHA512=$(cat "${SRC_TAR}.sha512")
+ local BIN_SHA512=$(cat "${BIN_TAR}.sha512")
+ local VOTE_DATE=$(date +"%B %d, %Y")
+
+ # Extract submodule commit IDs from the cloned release repo
+ local UI_COMMIT=$(git -C "${CLONE_DIR}" submodule status -- skywalking-ui
| awk '{print $1}' | tr -d '+-')
+ local PROTOCOL_COMMIT=$(git -C "${CLONE_DIR}" submodule status --
apm-protocol/apm-network/src/main/proto | awk '{print $1}' | tr -d '+-')
+ local QUERY_COMMIT=$(git -C "${CLONE_DIR}" submodule status --
oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
| awk '{print $1}' | tr -d '+-')
+
+ cat <<EOF
+
+========================================================================
+Vote Email - Copy and send to [email protected]
+========================================================================
+
+Mail title: [VOTE] Release Apache SkyWalking version ${RELEASE_VERSION}
+
+Mail content:
+Hi All,
+This is a call for vote to release Apache SkyWalking version
${RELEASE_VERSION}.
+
+Release notes:
+
+ *
https://github.com/apache/skywalking/blob/master/docs/en/changes/changes-${RELEASE_VERSION}.md
+
+Release Candidate:
+
+ * ${SVN_DEV_URL}/${RELEASE_VERSION}
+ * sha512 checksums
+ - ${SRC_SHA512}
+ - ${BIN_SHA512}
+
+Release Tag :
+
+ * (Git Tag) ${TAG}
+
+Release CommitID :
+
+ * https://github.com/apache/skywalking/tree/${TAG}
+ * Git submodule
+ * skywalking-ui:
https://github.com/apache/skywalking-booster-ui/tree/${UI_COMMIT}
+ * apm-protocol/apm-network/src/main/proto:
https://github.com/apache/skywalking-data-collect-protocol/tree/${PROTOCOL_COMMIT}
+ *
oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
https://github.com/apache/skywalking-query-protocol/tree/${QUERY_COMMIT}
+
+Keys to verify the Release Candidate :
+
+ * https://dist.apache.org/repos/dist/release/skywalking/KEYS
+
+Guide to build the release from source :
+
+ *
https://github.com/apache/skywalking/blob/${TAG}/docs/en/guides/How-to-build.md
+
+Voting will start now (${VOTE_DATE}) and will remain open for at least 72
hours, Request all PMC members to give their vote.
+[ ] +1 Release this package.
+[ ] +0 No opinion.
+[ ] -1 Do not release this package because....
+
+========================================================================
+
+EOF
+}
+
+# ========================== Main flow ==========================
+
+# Step 1: Check GPG signer
+echo "=== Step 1: Checking GPG signer ==="
+
+GPG_KEY_ID=$(git config user.signingkey 2>/dev/null || true)
+if [ -z "$GPG_KEY_ID" ]; then
+ echo "No git signing key configured. Trying default GPG key..."
+ GPG_KEY_ID=$(gpg --list-secret-keys --keyid-format LONG 2>/dev/null | grep
-A1 '^sec' | tail -1 | awk '{print $1}' || true)
+fi
+
+if [ -z "$GPG_KEY_ID" ]; then
+ echo "ERROR: No GPG secret key found. Please configure a GPG key first."
+ exit 1
+fi
+
+GPG_UIDS=$(gpg --list-secret-keys --keyid-format LONG 2>/dev/null | grep 'uid'
| sed 's/.*] //')
+GPG_EMAIL=$(echo "$GPG_UIDS" | grep -oE
'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' | head -1)
+
+if [[ "$GPG_EMAIL" != *"@apache.org" ]]; then
+ echo "WARNING: GPG key email '${GPG_EMAIL}' is not an @apache.org address."
+ echo "Apache releases must be signed with an @apache.org GPG key."
+ exit 1
+fi
+
+echo "GPG Signer: ${GPG_UIDS}"
+echo "GPG Email: ${GPG_EMAIL}"
+read -p "Is this the correct GPG signer? [y/N] " confirm
+if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
+ echo "Aborted."
+ exit 1
+fi
+
+# Step 2: Check required tools
+echo ""
+echo "=== Step 2: Checking required tools ==="
+
+MISSING_TOOLS=()
+for tool in gpg svn shasum git yq; do
+ if ! command -v "$tool" &>/dev/null; then
+ MISSING_TOOLS+=("$tool")
+ fi
+done
+
+if [ ${#MISSING_TOOLS[@]} -gt 0 ]; then
+ echo "ERROR: Missing required tools: ${MISSING_TOOLS[*]}"
+ exit 1
+fi
+
+echo "All required tools are available."
+
+# Step 3: Detect current version
+echo ""
+echo "=== Step 3: Detecting current version ==="
+
+CURRENT_VERSION=$(grep '<revision>' "${PROJECT_DIR}/pom.xml" | head -1 | sed
's/.*<revision>\(.*\)<\/revision>.*/\1/')
+
+if [ -z "$CURRENT_VERSION" ]; then
+ echo "ERROR: Could not detect version from pom.xml."
+ exit 1
+fi
+
+echo "Current version: ${CURRENT_VERSION}"
+
+# Step 4: Calculate versions
+echo ""
+echo "=== Step 4: Calculating versions ==="
+
+RELEASE_VERSION="${CURRENT_VERSION%-SNAPSHOT}"
+
+if [ "$RELEASE_VERSION" == "$CURRENT_VERSION" ]; then
+ echo "WARNING: Current version '${CURRENT_VERSION}' does not end with
-SNAPSHOT."
+ read -p "Continue with release version '${RELEASE_VERSION}'? [y/N] "
confirm
+ if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
+ echo "Aborted."
+ exit 1
+ fi
+fi
+
+MAJOR=$(echo "$RELEASE_VERSION" | cut -d. -f1)
+MINOR=$(echo "$RELEASE_VERSION" | cut -d. -f2)
+NEXT_MINOR=$((MINOR + 1))
+NEXT_RELEASE_VERSION="${MAJOR}.${NEXT_MINOR}.0"
+
+echo "Release version: ${RELEASE_VERSION}"
+echo "Next dev version: ${NEXT_RELEASE_VERSION}-SNAPSHOT"
+read -p "Are these versions correct? [y/N] " confirm
+if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
+ read -p "Enter release version: " RELEASE_VERSION
+ read -p "Enter next release version (without -SNAPSHOT): "
NEXT_RELEASE_VERSION
+fi
+
+# Step 5: Clone and build
+echo ""
+echo "=== Step 5: Cloning repository and building release artifacts ==="
+clone_repo
+build_release_artifacts
+
+# Verify artifacts
+SRC_TAR="${SCRIPT_DIR}/${PRODUCT_NAME}-${RELEASE_VERSION}-src.tar.gz"
+BIN_TAR="${SCRIPT_DIR}/${PRODUCT_NAME}-${RELEASE_VERSION}-bin.tar.gz"
+
+for f in "${SRC_TAR}" "${SRC_TAR}.asc" "${SRC_TAR}.sha512" \
+ "${BIN_TAR}" "${BIN_TAR}.asc" "${BIN_TAR}.sha512"; do
+ if [ ! -f "$f" ]; then
+ echo "ERROR: Expected artifact not found: $f"
+ exit 1
+ fi
+done
+
+echo "All artifacts verified:"
+ls -lh "${SCRIPT_DIR}"/${PRODUCT_NAME}-${RELEASE_VERSION}-*
+
+# Step 6: Upload to SVN
+echo ""
+echo "=== Step 6: Uploading to SVN staging ==="
+upload_to_svn
+
+# Step 7: Generate vote email
+echo ""
+echo "=== Step 7: Generating vote email ==="
+generate_vote_email
+
+# Step 8: Next version
+echo ""
+echo "=== Step 8: Starting next version iteration ==="
+prepare_next_version
+
+echo ""
+echo
"========================================================================="
+echo "Release process complete!"
+echo " Release version: ${RELEASE_VERSION}"
+echo " Next dev version: ${NEXT_RELEASE_VERSION}-SNAPSHOT"
+echo " SVN staging: ${SVN_DEV_URL}/${RELEASE_VERSION}"
+echo ""
+echo "Next steps:"
+echo " 1. Send the vote email to [email protected]"
+echo " 2. Merge the next-version PR once the vote passes"
+echo
"========================================================================="
diff --git a/tools/releasing/start_next_version.sh
b/tools/releasing/start_next_version.sh
deleted file mode 100644
index 457bc69a7c..0000000000
--- a/tools/releasing/start_next_version.sh
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/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.
-#
-
-# This script relies on few environment variables to determine source code
package
-# behavior, those variables are:
-# RELEASE_VERSION -- The version of this source package.
-# NEXT_RELEASE_VERSION -- The version of the next release.
-# For example: RELEASE_VERSION=10.0.0, NEXT_RELEASE_VERSION=10.0.1
-
-set -e -o pipefail
-
-if [ "$RELEASE_VERSION" == "" ] || [ "$NEXT_RELEASE_VERSION" == "" ]; then
- echo "RELEASE_VERSION or NEXT_RELEASE_VERSION environment variable not
found."
- echo "Please set the RELEASE_VERSION and NEXT_RELEASE_VERSION."
- echo "For example: export RELEASE_VERSION=10.0.0"
- echo " : export NEXT_RELEASE_VERSION=10.0.1"
- exit 1
-fi
-
-if ! command -v yq &> /dev/null; then
- echo "yq is not installed. Please install yq first."
- exit 1
-fi
-
-if [ -d "skywalking" ]; then
- rm -rf skywalking
-fi
-
-echo "Cloning the repository..."
-git clone --recurse-submodules -j4 --depth 1
https://github.com/apache/skywalking.git && cd skywalking
-
-echo "Checking out the release branch ${RELEASE_VERSION}-release..."
-git checkout -b ${RELEASE_VERSION}-release
-
-echo "Setting the next release version ${NEXT_RELEASE_VERSION} in pom.xml..."
-./mvnw versions:set-property -DgenerateBackupPoms=false -Dproperty=revision
-DnewVersion=${NEXT_RELEASE_VERSION}-SNAPSHOT
-
-echo "Committing the pom.xml changes..."
-git add pom.xml
-git commit -m "Update the next release version to
${NEXT_RELEASE_VERSION}-SNAPSHOT"
-
-echo "Moving the changelog file..."
-mv docs/en/changes/changes.md docs/en/changes/changes-$RELEASE_VERSION.md
-
-echo "Updating the changelog file..."
-cat docs/en/changes/changes.tpl | sed
"s/NEXT_RELEASE_VERSION/${NEXT_RELEASE_VERSION}/g" > docs/en/changes/changes.md
-
-echo "Committing the changelog files..."
-git add docs
-git commit -m "Update the changelog files"
-
-echo "Updating the menu.yml file..."
-new_menu_file=$(mktemp)
-major_version=$(echo ${RELEASE_VERSION} | cut -d. -f1)
-yq '(.catalog[] | select(.name=="Changelog") | .catalog[] |
select(.name=="'"${major_version}.x Releases"'") | .catalog) |= [{ "name":
"'"${RELEASE_VERSION}"'", "path": "/en/changes/changes-'${RELEASE_VERSION}'" }]
+ .' docs/menu.yml > ${new_menu_file}
-mv ${new_menu_file} docs/menu.yml
-git add docs
-git commit -m "Update the menu.yml file"
-
-echo "Pushing the changes to the remote repository..."
-git push --set-upstream origin ${RELEASE_VERSION}-release
-
-echo "Opening the PR..."
-open https://github.com/apache/skywalking/pull/new/${RELEASE_VERSION}-release