diff --git a/CHANGES.md b/CHANGES.md index 237ce9ff0c..ef6a81a3e4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,7 +21,9 @@ Release Notes. * Enhance test/plugin/run.sh to support extra Maven properties per version in support-version.list (format: version,key=value). * Add MariaDB 3.x plugin (all classes renamed in 3.x). * Extend Jedis 4.x plugin to support Jedis 5.x (fix witness method for 5.x compatibility). -* Add Elasticsearch Java client (co.elastic.clients:elasticsearch-java) plugin for 7.x-9.x. +* Add Elasticsearch Java client (co.elastic.clients:elasticsearch-java) plugin for 7.16.x-9.x. +* Only publish `apm-application-toolkit` modules to Maven Central. Agent and plugins are distributed via download package and Docker images. +* Add unified release script (`tools/releasing/release.sh`) with two-step flow: `prepare-vote` and `vote-passed`. All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/249?closed=1) diff --git a/apm-application-toolkit/pom.xml b/apm-application-toolkit/pom.xml index cc173543d0..b018a7ef16 100644 --- a/apm-application-toolkit/pom.xml +++ b/apm-application-toolkit/pom.xml @@ -26,6 +26,11 @@ apm-application-toolkit pom + + + false + + apm-toolkit-log4j-1.x apm-toolkit-log4j-2.x diff --git a/docs/en/contribution/release-java-agent.md b/docs/en/contribution/release-java-agent.md index 567cf81615..5b941a822c 100644 --- a/docs/en/contribution/release-java-agent.md +++ b/docs/en/contribution/release-java-agent.md @@ -36,151 +36,47 @@ If you are a committer, use your Apache ID and password to log in this svn, and 1. Upload your GPG public key to the public GPG site, such as [MIT's site](http://pgp.mit.edu:11371/). This site should be in the Apache maven staging repository checklist. -## Test your settings -This step is only for testing purpose. If your env is correctly set, you don't need to check every time. -``` -./mvnw clean install(this will build artifacts, sources and sign) -``` - -## Prepare for the release -``` -./mvnw release:clean -./mvnw release:prepare -DautoVersionSubmodules=true -Pall -``` - -- Set version number as x.y.z, and tag as **v**x.y.z (The version tag must start with **v**. You will find out why this is necessary in the next step.) - -_You could do a GPG signature before preparing for the release. If you need to input the password to sign, and the maven doesn't provide you with the opportunity to do so, this may lead to failure of the release. To resolve this, you may run `gpg --sign xxx` in any file. This will allow it to remember the password for long enough to prepare for the release._ - -## Stage the release -``` -./mvnw release:perform -DskipTests -Pall -``` +## Release using the release script -- The release will be automatically inserted into a temporary staging repository. +The release script `tools/releasing/release.sh` automates the full release workflow. The release is a **two-step process** with a vote in between. -## Build and sign the source code and binary package +### Quick start ```shell -export RELEASE_VERSION=x.y.z (example: RELEASE_VERSION=5.0.0-alpha) -cd tools/releasing -bash create_release.sh -``` - -This script takes care of the following things: -1. Use `v` + `RELEASE_VERSION` as tag to clone the codes. -2. Complete `git submodule init/update`. -3. Exclude all unnecessary files in the target source tar, such as `.git`, `.github`, and `.gitmodules`. See the script for more details. -4. Execute `gpg` and `shasum 512` for source code tar. -5. Use maven package to build the agent tar. -6. Execute `gpg` and `shasum 512` for binary tar. - -`apache-skywalking-java-agent-x.y.z-src.tgz` and files ending with `.asc` and `.sha512` may be found in the `tools/releasing` folder. -`apache-skywalking-java-agent-x.y.z.tgz` and files ending with `.asc` and `.sha512` may be found in the `tools/releasing/apache-skywalking-java-agent-x.y.z` folder. - - -## Upload to Apache svn -1. Use your Apache ID to log in to `https://dist.apache.org/repos/dist/dev/skywalking/java-agent/`. -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`. -1. Upload the distribution package to the folder with files ending with `.asc` and `.sha512`. +# Step 1: Build, stage, upload, and generate vote email +./tools/releasing/release.sh prepare-vote x.y.z -## Make the internal announcements -Send an announcement mail in dev mail list. +# (send vote email to dev@skywalking.apache.org, wait 72h for vote to pass) +# Step 2: Promote, push Docker images, generate announce email, and clean up +./tools/releasing/release.sh vote-passed [old_version_to_remove] ``` -Mail title: [ANNOUNCE] SkyWalking Java Agent x.y.z test build available - -Mail content: -The test build of Java Agent x.y.z is available. - -We welcome any comments you may have, and will take all feedback into -account if a quality vote is called for this build. - -Release notes: - - * https://github.com/apache/skywalking-java/blob/master/changes/changes-x.y.z.md -Release Candidate: +Run `./tools/releasing/release.sh` without arguments to see all available commands, including individual steps if you need to run them separately. - * https://dist.apache.org/repos/dist/dev/skywalking/java-agent/xxxx - * sha512 checksums +### Pre-flight checks +Before starting, the script verifies: +- Required tools are installed (git, gpg, svn, shasum, mvn, java, tar, gh) +- GPG signing works **without password prompt** (critical for maven release) +- Maven settings contain Apache server credentials +- Git working tree is clean -Maven 2 staging repository: - - * https://repository.apache.org/content/repositories/xxxx/org/apache/skywalking-java/ - -Release Tag : - - * (Git Tag) x.y.z - -Release CommitID : - - * https://github.com/apache/skywalking-java/tree/(Git Commit ID) - * Git submodule - * apm-protocol/apm-network/src/main/proto: https://github.com/apache/skywalking-data-collect-protocol/tree/(Git Commit ID) - -Keys to verify the Release Candidate : - - * https://dist.apache.org/repos/dist/release/skywalking/KEYS - -Guide to build the release from source : - - > ./mvnw clean package - -A vote regarding the quality of this test build will be initiated -within the next couple of days. +If GPG signing fails, configure gpg-agent to cache the passphrase: ``` - -## Wait for at least 48 hours for test responses -Any PMC member, committer or contributor can test the release features and provide feedback. -Based on that, the PMC will decide whether to start the voting process. - -## Call a vote in dev -Call a vote in `dev@skywalking.apache.org` - +# ~/.gnupg/gpg-agent.conf +default-cache-ttl 86400 +max-cache-ttl 86400 ``` -Mail title: [VOTE] Release Apache SkyWalking Java Agent version x.y.z - -Mail content: -Hi All, -This is a call for vote to release Apache SkyWalking Java Agent version x.y.z. - -Release notes: - - * https://github.com/apache/skywalking-java/blob/master/changes/changes-x.y.z.md - -Release Candidate: - - * https://dist.apache.org/repos/dist/dev/skywalking/java-agent/xxxx - * sha512 checksums - -Maven 2 staging repository: +Then run `gpgconf --kill gpg-agent` and `gpg --sign /dev/null` to cache it. - * https://repository.apache.org/content/repositories/xxxx/org/apache/skywalking/ +### prepare-vote +`prepare-vote` runs the following steps in sequence: +1. **preflight** — verify tools and environment +2. **prepare** — create `release/x.y.z` branch, run `mvn release:prepare` (creates tag `vx.y.z` with full CHANGES.md), then archive changelog and reset for next version, push branch and tag, create PR +3. **stage** — run `mvn release:perform`, build source and binary tars with GPG signatures and sha512 checksums +4. **upload** — upload to Apache SVN `dist/dev` (prompts for SVN credentials) +5. **email vote** — print vote email template with pre-filled version, commit ID, submodule commit, and checksums -Release Tag : - - * (Git Tag) x.y.z - -Release CommitID : - - * https://github.com/apache/skywalking-java/tree/(Git Commit ID) - * Git submodule - * apm-protocol/apm-network/src/main/proto: https://github.com/apache/skywalking-data-collect-protocol/tree/(Git Commit ID) - -Keys to verify the Release Candidate : - - * https://dist.apache.org/repos/dist/release/skywalking/KEYS - -Guide to build the release from source : - - > ./mvnw clean package - -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.... -``` +Copy the generated email and send it to `dev@skywalking.apache.org`. Voting remains open for at least 72 hours. At least 3 (+1 binding) PMC votes with more +1 than -1 are required. ## Vote Check All PMC members and committers should check these before casting +1 votes. @@ -195,91 +91,9 @@ are found in `https://dist.apache.org/repos/dist/dev/skywalking/java-agent/x.y.z 1. Build a distribution package from the source code package (`apache-skywalking-java-agent-x.y.z-src.tar.gz`). 1. Check the Apache License Header. Run `docker run --rm -v $(pwd):/github/workspace apache/skywalking-eyes header check`. (No binaries in source codes) - -The voting process is as follows: -1. All PMC member votes are +1 binding, and all other votes are +1 but non-binding. -1. If you obtain at least 3 (+1 binding) votes with more +1 than -1 votes within 72 hours, the release will be approved. - - -## Publish the release -1. Move source codes tar and distribution packages to `https://dist.apache.org/repos/dist/release/skywalking/java-agent/`. -``` -> export SVN_EDITOR=vim -> svn mv https://dist.apache.org/repos/dist/dev/skywalking/java-agent/x.y.z https://dist.apache.org/repos/dist/release/skywalking/java-agent -.... -enter your apache password -.... - -``` -2. Release in the nexus staging repo. -3. Public download source and distribution tar/zip are located in `http://www.apache.org/dyn/closer.cgi/skywalking/java-agent/x.y.z/xxx`. -The Apache mirror path is the only release information that we publish. -4. Public asc and sha512 are located in `https://www.apache.org/dist/skywalking/java-agent/x.y.z/xxx`. -5. Public KEYS point to `https://www.apache.org/dist/skywalking/KEYS`. -6. Update the website download page. http://skywalking.apache.org/downloads/ . Add a new download source, distribution, sha512, asc, and document -links. The links can be found following rules (3) to (6) above. -7. Add a release event on the website homepage and event page. Announce the public release with changelog or key features. -8. Send ANNOUNCE email to `dev@skywalking.apache.org`, `announce@apache.org`. The sender should use the Apache email account. -``` -Mail title: [ANNOUNCE] Apache SkyWalking Java Agent x.y.z released - -Mail content: -Hi all, - -Apache SkyWalking Team is glad to announce the first release of Apache SkyWalking Java Agent x.y.z. - -SkyWalking: APM (application performance monitor) tool for distributed systems, -especially designed for microservices, cloud native and container-based (Docker, Kubernetes, Mesos) architectures. - -The Java Agent for Apache SkyWalking, which provides the native tracing/metrics/logging abilities for Java projects. - -This release contains a number of new features, bug fixes and improvements compared to -version a.b.c(last release). The notable changes since x.y.z include: - -(Highlight key changes) -1. ... -2. ... -3. ... - -Please refer to the change log for the complete list of changes: -https://github.com/apache/skywalking-java/blob/master/changes/changes-x.y.z.md - -Apache SkyWalking website: -http://skywalking.apache.org/ - -Downloads: -http://skywalking.apache.org/downloads/ - -Twitter: -https://twitter.com/AsfSkyWalking - -SkyWalking Resources: -- GitHub: https://github.com/apache/skywalking-java -- Issue: https://github.com/apache/skywalking/issues -- Mailing list: dev@skywalkiing.apache.org - - -- Apache SkyWalking Team -``` - -## Release Docker images - -```shell -export SW_VERSION=x.y.z -git clone --depth 1 --branch v$SW_VERSION https://github.com/apache/skywalking-java.git -cd skywalking-java - -curl -O https://dist.apache.org/repos/dist/release/skywalking/java-agent/$SW_VERSION/apache-skywalking-java-agent-$SW_VERSION.tgz -tar -xzvf apache-skywalking-java-agent-$SW_VERSION.tgz - -export NAME=skywalking-java-agent -export HUB=apache -export TAG=$SW_VERSION - -make docker.push.alpine docker.push.java8 docker.push.java11 docker.push.java17 docker.push.java21 docker.push.java25 -``` - -## Clean up the old releases -Once the latest release has been published, you should clean up the old releases from the mirror system. -1. Update the download links (source, dist, asc, and sha512) on the website to the archive repo (https://archive.apache.org/dist/skywalking). -2. Remove previous releases from https://dist.apache.org/repos/dist/release/skywalking/java-agent. +## vote-passed +After the vote passes, run `vote-passed` which executes: +1. **promote** — move packages from `dist/dev` to `dist/release` in Apache SVN (prompts for SVN credentials), then release the Nexus staging repository at https://repository.apache.org and update the website download page +2. **docker** — build and push all Docker image variants (alpine, java8, java11, java17, java21, java25) +3. **email announce** — print announcement email template. Copy and send to `dev@skywalking.apache.org` and `announce@apache.org` +4. **cleanup** (optional) — if old version is provided, remove it from `dist/release`. Update download page links to point to `https://archive.apache.org/dist/skywalking` diff --git a/pom.xml b/pom.xml index b675688a4a..1f3297d2d1 100755 --- a/pom.xml +++ b/pom.xml @@ -131,6 +131,8 @@ 1.33 1.5 true + + true 0.46.0 diff --git a/tools/releasing/create_release.sh b/tools/releasing/create_release.sh deleted file mode 100755 index 98cedccc01..0000000000 --- a/tools/releasing/create_release.sh +++ /dev/null @@ -1,84 +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. -# For example: RELEASE_VERSION=5.0.0-alpha - - -RELEASE_VERSION=${RELEASE_VERSION} -TAG_NAME=v${RELEASE_VERSION} -PRODUCT_NAME="apache-skywalking-java-agent" - -echo "Release version "${RELEASE_VERSION} -echo "Source tag "${TAG_NAME} - -if [ "$RELEASE_VERSION" == "" ]; then - echo "RELEASE_VERSION environment variable not found, Please setting the RELEASE_VERSION." - echo "For example: export RELEASE_VERSION=5.0.0-alpha" - exit 1 -fi - -echo "Creating source package" - -PRODUCT_NAME=${PRODUCT_NAME}-${RELEASE_VERSION} - -rm -rf ${PRODUCT_NAME} -mkdir ${PRODUCT_NAME} - -git clone https://github.com/apache/skywalking-java.git ./${PRODUCT_NAME} -cd ${PRODUCT_NAME} - -TAG_EXIST=`git tag -l ${TAG_NAME} | wc -l` - -if [ ${TAG_EXIST} -ne 1 ]; then - echo "Could not find the tag named" ${TAG_NAME} - exit 1 -fi - -git checkout ${TAG_NAME} - -# Init submodules -git submodule init -git submodule update - -# Generate a static skywalking-agent-version.properties and override the template when releasing source tar -# because after that there is no Git information anymore. -./mvnw -q -pl apm-sniffer/apm-agent-core initialize \ - -DgenerateGitPropertiesFilename="$(pwd)/apm-sniffer/apm-agent-core/src/main/resources/skywalking-agent-version.properties" - -cd .. -# Build source code tar -tar czf ${PRODUCT_NAME}-src.tgz \ - --exclude .git \ - --exclude .DS_Store \ - --exclude .github \ - --exclude .gitignore \ - --exclude .gitmodules \ - ${PRODUCT_NAME} - -gpg --armor --detach-sig ${PRODUCT_NAME}-src.tgz - -shasum -a 512 ${PRODUCT_NAME}-src.tgz > ${PRODUCT_NAME}-src.tgz.sha512 - -# Build binary tar -cd ${PRODUCT_NAME} -export TAG=${RELEASE_VERSION} -make dist diff --git a/tools/releasing/release.sh b/tools/releasing/release.sh new file mode 100755 index 0000000000..8338e60486 --- /dev/null +++ b/tools/releasing/release.sh @@ -0,0 +1,648 @@ +#!/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 Java Agent Release Script +# +# Usage: +# ./release.sh preflight Check tools and environment +# ./release.sh prepare Prepare release (branch, maven release:prepare, tag) +# ./release.sh stage Stage release (maven release:perform, build tars) +# ./release.sh upload Upload to Apache SVN dist/dev +# ./release.sh prepare-vote Run prepare + stage + upload, then generate vote email +# ./release.sh email [vote|announce] Generate email content +# ./release.sh promote Move from dist/dev to dist/release in SVN +# ./release.sh docker Build and push Docker images +# ./release.sh vote-passed Run promote + docker, then generate announce email +# ./release.sh cleanup Remove old release from dist/release + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" +PRODUCT_NAME="apache-skywalking-java-agent" + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +info() { echo -e "${GREEN}[INFO]${NC} $*"; } +warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } +error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; } + +# ============================================================ +# preflight — check tools and environment +# ============================================================ +cmd_preflight() { + info "Running pre-flight checks..." + + local failed=0 + + # Required tools + for tool in git gpg svn shasum mvn java tar gh; do + if command -v "$tool" &>/dev/null; then + info " $tool: $(command -v $tool)" + else + error " $tool: NOT FOUND" + failed=1 + fi + done + + # Java version + local java_version + java_version=$(java -version 2>&1 | head -1) + info " Java: $java_version" + + # GPG key + local gpg_keys + gpg_keys=$(gpg --list-secret-keys --keyid-format SHORT 2>/dev/null | grep -c "sec" || true) + if [ "$gpg_keys" -eq 0 ]; then + error " GPG: No secret keys found. Import your GPG key first." + failed=1 + else + info " GPG: $gpg_keys secret key(s) found" + fi + + # GPG signing without password prompt + info " Testing GPG signing (should not ask for password)..." + local test_file + test_file=$(mktemp) + echo "test" > "$test_file" + if gpg --batch --yes --armor --detach-sig "$test_file" 2>/dev/null; then + info " GPG signing: OK (no password prompt)" + rm -f "$test_file" "${test_file}.asc" + else + rm -f "$test_file" "${test_file}.asc" + echo "" + echo " GPG signing FAILED. The agent must be configured to cache the passphrase." + echo "" + echo " Options to fix:" + echo " 1. Configure gpg-agent with a longer cache TTL in ~/.gnupg/gpg-agent.conf:" + echo " default-cache-ttl 86400" + echo " max-cache-ttl 86400" + echo " Then: gpgconf --kill gpg-agent" + echo "" + echo " 2. Or run 'gpg --sign /dev/null' manually first to cache the passphrase." + echo "" + failed=1 + fi + + # Maven settings (Apache credentials) + local settings_file="${HOME}/.m2/settings.xml" + if [ -f "$settings_file" ]; then + if grep -q "apache.releases.https" "$settings_file"; then + info " Maven settings: apache.releases.https server found" + else + warn " Maven settings: apache.releases.https server NOT found in $settings_file" + failed=1 + fi + else + warn " Maven settings: $settings_file not found" + failed=1 + fi + + # Git status + cd "$PROJECT_ROOT" + if [ -n "$(git status --porcelain)" ]; then + warn " Git: working tree is dirty" + else + info " Git: working tree is clean" + fi + + local branch + branch=$(git rev-parse --abbrev-ref HEAD) + info " Git branch: $branch" + + if [ "$failed" -ne 0 ]; then + echo "" + error "Pre-flight checks failed. Fix the issues above before releasing." + fi + + echo "" + info "All pre-flight checks passed." +} + +# ============================================================ +# prepare — prepare the release (CHANGES.md, maven) +# ============================================================ +cmd_prepare() { + local version="${1:-}" + local next_version="${2:-}" + if [ -z "$version" ]; then + error "Usage: $0 prepare [next_version] (e.g., 9.7.0 9.8.0)" + fi + + cd "$PROJECT_ROOT" + + if [ -z "$next_version" ]; then + next_version=$(echo "$version" | awk -F. '{printf "%s.%s.%s", $1, $2+1, 0}') + fi + local branch_name="release/${version}" + + info "Preparing release ${version}..." + echo " Release version: ${version}" + echo " Tag: v${version}" + echo " Next dev version: ${next_version}-SNAPSHOT" + echo " Branch: ${branch_name}" + echo "" + read -rp "Continue? [y/N] " confirm + if [[ ! "$confirm" =~ ^[Yy]$ ]]; then + info "Aborted." + exit 0 + fi + + # Step 1: Create release branch from main + info "Creating branch ${branch_name}..." + git checkout -b "${branch_name}" + + # Step 2: Maven release:prepare + # This creates two commits: + # 1. [maven-release-plugin] prepare release vx.y.z (pom versions set to x.y.z) + # 2. [maven-release-plugin] prepare for next development iteration (pom versions set to next-SNAPSHOT) + # And a tag vx.y.z pointing to commit 1. + # CHANGES.md is kept as-is so the tag includes the full changelog. + info "Running maven release:prepare..." + ./mvnw release:clean + ./mvnw release:prepare -DautoVersionSubmodules=true -Pall \ + -DreleaseVersion="${version}" \ + -DdevelopmentVersion="${next_version}-SNAPSHOT" \ + -Dtag="v${version}" \ + -DpushChanges=false + + # Step 3: After the tag is created, move CHANGES.md for next dev cycle + info "Moving changelog to changes/changes-${version}.md..." + local changes_file="changes/changes-${version}.md" + + # Extract current version section from CHANGES.md + sed -n "/^${version}$/,/^------------------$/p" CHANGES.md | head -n -1 > "$changes_file" + grep "All issues and pull requests" CHANGES.md >> "$changes_file" || true + info "Created $changes_file" + + # Reset CHANGES.md for next development version + cat > CHANGES.md << EOF +Changes by Version +================== +Release Notes. + +${next_version} +------------------ + + +All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/xxx?closed=1) + +------------------ +Find change logs of all versions [here](changes). +EOF + + git add CHANGES.md "$changes_file" + git commit -m "Move ${version} changelog and reset for ${next_version} development" + + # Step 4: Push branch and tag + info "Pushing branch and tag..." + git push -u origin "${branch_name}" + git push origin "v${version}" + + # Step 5: Create PR + info "Creating pull request..." + if command -v gh &>/dev/null; then + gh pr create --base main --head "${branch_name}" \ + --title "Release ${version}" \ + --body "Release Apache SkyWalking Java Agent ${version}. + +- Maven release:prepare completed (tag \`v${version}\` created) +- CHANGES.md archived to \`changes/changes-${version}.md\` +- Next development version: ${next_version}-SNAPSHOT" + info "PR created." + else + warn "GitHub CLI (gh) not found. Create PR manually for branch ${branch_name}." + fi + + info "Release ${version} prepared." + info " Tag v${version} is ready." + info " PR created for branch ${branch_name} → main." + info "Next step: $0 stage" +} + +# ============================================================ +# stage — stage the release (maven, build source & binary tars) +# ============================================================ +cmd_stage() { + cd "$PROJECT_ROOT" + + # Detect version from latest tag + local version + version=$(git describe --tags --abbrev=0 | sed 's/^v//') + local tag_name="v${version}" + + info "Staging release ${version}..." + + # Maven release:perform + info "Running maven release:perform..." + ./mvnw release:perform -DskipTests -Pall + + # Build source and binary packages (inlined from create_release.sh) + info "Building source and binary packages..." + + cd "${SCRIPT_DIR}" + local product_dir="${PRODUCT_NAME}-${version}" + + rm -rf "${product_dir}" + mkdir "${product_dir}" + + git clone https://github.com/apache/skywalking-java.git "./${product_dir}" + cd "${product_dir}" + + TAG_EXIST=$(git tag -l "${tag_name}" | wc -l) + if [ "${TAG_EXIST}" -ne 1 ]; then + error "Could not find the tag named ${tag_name}" + fi + + git checkout "${tag_name}" + git submodule init + git submodule update + + # Generate static version properties (no Git info in source tar) + ./mvnw -q -pl apm-sniffer/apm-agent-core initialize \ + -DgenerateGitPropertiesFilename="$(pwd)/apm-sniffer/apm-agent-core/src/main/resources/skywalking-agent-version.properties" + + cd "${SCRIPT_DIR}" + + # Source tar + info "Creating source tar..." + tar czf "${product_dir}-src.tgz" \ + --exclude .git \ + --exclude .DS_Store \ + --exclude .github \ + --exclude .gitignore \ + --exclude .gitmodules \ + "${product_dir}" + + gpg --armor --detach-sig "${product_dir}-src.tgz" + shasum -a 512 "${product_dir}-src.tgz" > "${product_dir}-src.tgz.sha512" + + # Binary tar + info "Creating binary tar..." + cd "${product_dir}" + export TAG="${version}" + make dist + + echo "" + info "Release ${version} staged." + info "Source tar: ${SCRIPT_DIR}/${product_dir}-src.tgz" + info "Binary tar: ${SCRIPT_DIR}/${product_dir}/${PRODUCT_NAME}-${version}.tgz" + info "Next step: $0 upload" +} + +# ============================================================ +# upload — upload to Apache SVN dist/dev +# ============================================================ +cmd_upload() { + cd "$PROJECT_ROOT" + + local version + version=$(git describe --tags --abbrev=0 | sed 's/^v//') + local svn_dev="https://dist.apache.org/repos/dist/dev/skywalking/java-agent" + + info "Uploading release ${version} to Apache SVN (dist/dev)..." + + local staging_dir="${SCRIPT_DIR}/${PRODUCT_NAME}-${version}" + + # Verify files exist + local src_tar="${SCRIPT_DIR}/${PRODUCT_NAME}-${version}-src.tgz" + local bin_tar="${staging_dir}/${PRODUCT_NAME}-${version}.tgz" + + for f in "$src_tar" "${src_tar}.asc" "${src_tar}.sha512" \ + "$bin_tar" "${bin_tar}.asc" "${bin_tar}.sha512"; do + if [ ! -f "$f" ]; then + error "Missing file: $f. Run '$0 stage' first." + fi + done + + # Create SVN directory and upload + read -rp "SVN username (Apache ID): " svn_user + + local tmp_svn + tmp_svn=$(mktemp -d) + info "Checking out SVN dist/dev..." + svn checkout --depth empty "$svn_dev" "$tmp_svn" --username "$svn_user" + + mkdir -p "${tmp_svn}/${version}" + + cp "$src_tar" "${src_tar}.asc" "${src_tar}.sha512" "${tmp_svn}/${version}/" + cp "$bin_tar" "${bin_tar}.asc" "${bin_tar}.sha512" "${tmp_svn}/${version}/" + + cd "$tmp_svn" + svn add "${version}" + svn commit -m "Stage Apache SkyWalking Java Agent ${version}" --username "$svn_user" + + rm -rf "$tmp_svn" + info "Uploaded to ${svn_dev}/${version}" + info "Next step: $0 email vote" +} + +# ============================================================ +# email — generate email templates +# ============================================================ +cmd_email() { + local type="${1:-}" + if [[ ! "$type" =~ ^(vote|announce)$ ]]; then + error "Usage: $0 email [vote|announce]" + fi + + cd "$PROJECT_ROOT" + + local version + version=$(git describe --tags --abbrev=0 | sed 's/^v//') + local tag="v${version}" + local commit_id + commit_id=$(git rev-list -n1 "$tag" 2>/dev/null || echo "") + local submodule_commit + submodule_commit=$(git ls-tree "$tag" apm-protocol/apm-network/src/main/proto 2>/dev/null | awk '{print $3}' || echo "") + + # Get sha512 checksums + local src_sha512="" + local bin_sha512="" + local src_sha_file="${SCRIPT_DIR}/${PRODUCT_NAME}-${version}-src.tgz.sha512" + local bin_sha_file="${SCRIPT_DIR}/${PRODUCT_NAME}-${version}/${PRODUCT_NAME}-${version}.tgz.sha512" + [ -f "$src_sha_file" ] && src_sha512=$(cat "$src_sha_file") + [ -f "$bin_sha_file" ] && bin_sha512=$(cat "$bin_sha_file") + + echo "" + echo "============================================================" + + case "$type" in + vote) + cat << EOF +Mail to: dev@skywalking.apache.org +Subject: [VOTE] Release Apache SkyWalking Java Agent version ${version} + +Hi All, +This is a call for vote to release Apache SkyWalking Java Agent version ${version}. + +Release notes: + + * https://github.com/apache/skywalking-java/blob/master/changes/changes-${version}.md + +Release Candidate: + + * https://dist.apache.org/repos/dist/dev/skywalking/java-agent/${version} + * sha512 checksums + - ${src_sha512} + - ${bin_sha512} + +Maven 2 staging repository: + + * https://repository.apache.org/content/repositories//org/apache/skywalking/ + +Release Tag : + + * (Git Tag) v${version} + +Release CommitID : + + * https://github.com/apache/skywalking-java/tree/${commit_id} + * Git submodule + * apm-protocol/apm-network/src/main/proto: https://github.com/apache/skywalking-data-collect-protocol/tree/${submodule_commit} + +Keys to verify the Release Candidate : + + * https://dist.apache.org/repos/dist/release/skywalking/KEYS + +Guide to build the release from source : + + > ./mvnw clean package + +Voting will start now ($(date '+%B %d, %Y')) 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 + ;; + announce) + cat << EOF +Mail to: dev@skywalking.apache.org, announce@apache.org +Subject: [ANNOUNCE] Apache SkyWalking Java Agent ${version} released + +Hi all, + +Apache SkyWalking Team is glad to announce the release of Apache SkyWalking Java Agent ${version}. + +SkyWalking: APM (application performance monitor) tool for distributed systems, +especially designed for microservices, cloud native and container-based (Docker, Kubernetes, Mesos) architectures. + +The Java Agent for Apache SkyWalking, which provides the native tracing/metrics/logging abilities for Java projects. + +This release contains a number of new features, bug fixes and improvements compared to +the previous version. The notable changes include: + +(Highlight key changes from changes-${version}.md) +1. ... +2. ... +3. ... + +Please refer to the change log for the complete list of changes: +https://github.com/apache/skywalking-java/blob/master/changes/changes-${version}.md + +Apache SkyWalking website: +http://skywalking.apache.org/ + +Downloads: +http://skywalking.apache.org/downloads/ + +Twitter: +https://twitter.com/AsfSkyWalking + +SkyWalking Resources: +- GitHub: https://github.com/apache/skywalking-java +- Issue: https://github.com/apache/skywalking/issues +- Mailing list: dev@skywalking.apache.org + + +- Apache SkyWalking Team +EOF + ;; + esac + + echo "============================================================" + echo "" + warn "Replace with the actual Nexus staging repository ID." +} + +# ============================================================ +# docker — build and push Docker images +# ============================================================ +cmd_docker() { + cd "$PROJECT_ROOT" + + local version + version=$(git describe --tags --abbrev=0 | sed 's/^v//') + + info "Building and pushing Docker images for ${version}..." + + local dist_tar="${SCRIPT_DIR}/${PRODUCT_NAME}-${version}/${PRODUCT_NAME}-${version}.tgz" + + if [ ! -f "$dist_tar" ]; then + error "Binary tar not found: $dist_tar. Run '$0 stage' first." + fi + + # Extract agent package + tar -xzf "$dist_tar" -C "$PROJECT_ROOT" + + export NAME=skywalking-java-agent + export HUB=apache + export TAG="$version" + + make docker.push.alpine docker.push.java8 docker.push.java11 docker.push.java17 docker.push.java21 docker.push.java25 + + info "Docker images pushed for ${version}." +} + +# ============================================================ +# promote — move from dist/dev to dist/release +# ============================================================ +cmd_promote() { + cd "$PROJECT_ROOT" + + local version + version=$(git describe --tags --abbrev=0 | sed 's/^v//') + + info "Promoting release ${version} from dist/dev to dist/release..." + + read -rp "SVN username (Apache ID): " svn_user + + svn mv "https://dist.apache.org/repos/dist/dev/skywalking/java-agent/${version}" \ + "https://dist.apache.org/repos/dist/release/skywalking/java-agent/${version}" \ + -m "Release Apache SkyWalking Java Agent ${version}" \ + --username "$svn_user" + + info "Release ${version} promoted." + info "Next steps:" + info " 1. Release the Nexus staging repository" + info " 2. Update website download page" + info " 3. Run: $0 email announce" + info " 4. Run: $0 docker" +} + +# ============================================================ +# cleanup — remove old release from dist/release +# ============================================================ +cmd_cleanup() { + local old_version="${1:-}" + if [ -z "$old_version" ]; then + error "Usage: $0 cleanup (e.g., 9.5.0)" + fi + + info "Removing old release ${old_version} from dist/release..." + + read -rp "SVN username (Apache ID): " svn_user + + svn rm "https://dist.apache.org/repos/dist/release/skywalking/java-agent/${old_version}" \ + -m "Remove old Apache SkyWalking Java Agent ${old_version} release" \ + --username "$svn_user" + + info "Removed ${old_version} from dist/release." + warn "Remember to update download page links to point to archive.apache.org." +} + +# ============================================================ +# prepare-vote — run all steps before the vote +# ============================================================ +cmd_prepare_vote() { + local version="${1:-}" + local next_version="${2:-}" + if [ -z "$version" ]; then + error "Usage: $0 prepare-vote [next_version] (e.g., 9.7.0 9.8.0)" + fi + + cmd_preflight + echo "" + cmd_prepare "$version" "$next_version" + echo "" + cmd_stage + echo "" + cmd_upload + echo "" + cmd_email vote +} + +# ============================================================ +# vote-passed — run all steps after the vote passes +# ============================================================ +cmd_vote_passed() { + local old_version="${1:-}" + + cmd_promote + echo "" + cmd_docker + echo "" + cmd_email announce + + if [ -n "$old_version" ]; then + echo "" + cmd_cleanup "$old_version" + else + echo "" + warn "To clean up an old release, run: $0 cleanup " + fi +} + +# ============================================================ +# Main dispatcher +# ============================================================ +main() { + local cmd="${1:-}" + shift || true + + case "$cmd" in + preflight) cmd_preflight "$@" ;; + prepare) cmd_prepare "$@" ;; + stage) cmd_stage "$@" ;; + upload) cmd_upload "$@" ;; + email) cmd_email "$@" ;; + docker) cmd_docker "$@" ;; + promote) cmd_promote "$@" ;; + cleanup) cmd_cleanup "$@" ;; + prepare-vote) cmd_prepare_vote "$@" ;; + vote-passed) cmd_vote_passed "$@" ;; + *) + echo "Apache SkyWalking Java Agent Release Tool" + echo "" + echo "Usage: $0 [args]" + echo "" + echo "Quick start (two-step release):" + echo " $0 prepare-vote 9.7.0 [9.8.0] # before vote (next version auto-calculated if omitted)" + echo " (wait for 72h vote to pass)" + echo " $0 vote-passed [old_version] # after vote" + echo "" + echo "Individual commands:" + echo " preflight Check tools and environment" + echo " prepare [next_ver] Prepare release (branch, tag, PR)" + echo " stage Stage release (maven release:perform, build tars)" + echo " upload Upload to Apache SVN dist/dev" + echo " prepare-vote [next_ver] Run preflight + prepare + stage + upload + vote email" + echo " email [vote|announce] Generate email content" + echo " promote Move from dist/dev to dist/release in SVN" + echo " docker Build and push Docker images" + echo " vote-passed [old_ver] Run promote + docker + announce email [+ cleanup]" + echo " cleanup Remove old release from dist/release" + ;; + esac +} + +main "$@"