diff --git a/.github/workflows/publish-docker.yaml b/.github/workflows/publish-docker.yaml
index 13dd95e4ae..ba10b71356 100644
--- a/.github/workflows/publish-docker.yaml
+++ b/.github/workflows/publish-docker.yaml
@@ -16,37 +16,90 @@
name: publish-docker
+# Two kinds of image come out of this workflow:
+#
+# push to main -> per-commit development images, tagged with the commit SHA,
+# pushed to GitHub Container Registry.
+# release -> the official versioned images for a passed release vote,
+# tagged x.y.z-, pushed to Docker Hub as
+# apache/skywalking-java-agent.
+#
+# The release trigger is `released` rather than `published`, so publishing a
+# pre-release does not ship official images. Creating the GitHub Release is the
+# last step of `tools/releasing/release.sh vote-passed`.
on:
push:
branches:
- main
+ release:
+ types:
+ - released
env:
SKIP_TEST: true
- HUB: ghcr.io/apache/skywalking-java
jobs:
- build-tar:
+ # One agent package feeds every image. The variants differ only in the JRE they
+ # sit on: the Dockerfile takes BASE_IMAGE and ADDs the same DIST directory, and
+ # the agent itself is Java 8 bytecode that runs on all of them. So this is built
+ # (or downloaded) exactly once and handed to the matrix below as an artifact,
+ # rather than each variant fetching its own copy.
+ agent-package:
if: github.repository == 'apache/skywalking-java'
- name: Build Agent
+ name: Prepare Agent Package
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v2
with:
submodules: true
+
+ # Development images are compiled from the branch.
- name: Cache local Maven repository
+ if: github.event_name != 'release'
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-publish-docker-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-maven-publish-docker-
- uses: actions/setup-java@v2
+ if: github.event_name != 'release'
with:
distribution: temurin
java-version: 17
- name: Build Agent
+ if: github.event_name != 'release'
run: make build
+
+ # A release is never rebuilt. The published image has to carry the artifact
+ # the PMC voted on, so take it from the Apache distribution area and prove
+ # it is that one: the sha512 rules out a truncated download, and verifying
+ # the detached signature against the project KEYS file rules out anything
+ # the release manager did not sign. `release.sh promote` does the svn mv
+ # from dist/dev to dist/release immediately before the GitHub Release that
+ # triggers this workflow, so the file is in place by the time this runs.
+ - name: Download the released agent package
+ if: github.event_name == 'release'
+ run: |
+ set -euo pipefail
+ TAG=${{ github.event.release.tag_name }}
+ VERSION=${TAG#v}
+ BASE="https://dist.apache.org/repos/dist/release/skywalking/java-agent/${VERSION}"
+ TARBALL="apache-skywalking-java-agent-${VERSION}.tgz"
+
+ curl -fsSL --retry 5 --retry-delay 10 -O "${BASE}/${TARBALL}"
+ curl -fsSL --retry 5 --retry-delay 10 -O "${BASE}/${TARBALL}.asc"
+ curl -fsSL --retry 5 --retry-delay 10 -O "${BASE}/${TARBALL}.sha512"
+
+ sha512sum -c "${TARBALL}.sha512"
+
+ curl -fsSL --retry 5 --retry-delay 10 https://downloads.apache.org/skywalking/KEYS | gpg --import
+ gpg --verify "${TARBALL}.asc" "${TARBALL}"
+
+ tar -xzf "${TARBALL}"
+ # The Makefile passes this directory to the Dockerfile as ARG DIST.
+ test -d skywalking-agent
+
- uses: actions/upload-artifact@v4
name: Upload Agent
with:
@@ -55,7 +108,7 @@ jobs:
build-docker:
if: github.repository == 'apache/skywalking-java'
- needs: [ build-tar ]
+ needs: [ agent-package ]
name: Build and Push Docker
runs-on: ubuntu-latest
permissions:
@@ -64,9 +117,10 @@ jobs:
timeout-minutes: 60
strategy:
matrix:
- java-version: [ 8, 11, 17, 21, 25 ]
- env:
- TAG: ${{ github.sha }}
+ # A release publishes the complete set the previous manual `make
+ # docker.push.*` produced, alpine included. Per-commit development
+ # images keep the existing JRE-only set.
+ base: ${{ github.event_name == 'release' && fromJSON('["alpine","java8","java11","java17","java21","java25"]') || fromJSON('["java8","java11","java17","java21","java25"]') }}
steps:
- uses: actions/checkout@v2
with:
@@ -75,6 +129,35 @@ jobs:
with:
name: skywalking-agent
path: skywalking-agent
+ - name: Set environment variables
+ run: |
+ if [[ "${{ github.event_name }}" == "release" ]]; then
+ # Provisioned by ASF INFRA on request, as for apache/skywalking.
+ # Without them docker/login-action fails with an opaque error, so say
+ # what is actually missing.
+ if [[ -z "${{ secrets.DOCKERHUB_USER }}" || -z "${{ secrets.DOCKERHUB_TOKEN }}" ]]; then
+ echo "::error::DOCKERHUB_USER / DOCKERHUB_TOKEN are not set on this repository."
+ echo "::error::Ask ASF INFRA to add them (see docs/en/contribution/release-java-agent.md),"
+ echo "::error::or publish from a workstation with './tools/releasing/release.sh docker '."
+ exit 1
+ fi
+ # apache/skywalking-java-agent:x.y.z- on Docker Hub.
+ # NAME differs from the development images, which is why it is set
+ # here rather than left to the Makefile default.
+ echo "HUB=apache" >> $GITHUB_ENV
+ echo "NAME=skywalking-java-agent" >> $GITHUB_ENV
+ echo "DOCKER_REGISTRY=docker.io" >> $GITHUB_ENV
+ echo "DOCKER_USERNAME=${{ secrets.DOCKERHUB_USER }}" >> $GITHUB_ENV
+ echo "DOCKER_PASSWORD=${{ secrets.DOCKERHUB_TOKEN }}" >> $GITHUB_ENV
+ TAG=${{ github.event.release.tag_name }}
+ echo "TAG=${TAG#v}" >> $GITHUB_ENV
+ else
+ echo "HUB=ghcr.io/apache/skywalking-java" >> $GITHUB_ENV
+ echo "DOCKER_REGISTRY=ghcr.io" >> $GITHUB_ENV
+ echo "DOCKER_USERNAME=${{ github.actor }}" >> $GITHUB_ENV
+ echo "DOCKER_PASSWORD=${{ secrets.GITHUB_TOKEN }}" >> $GITHUB_ENV
+ echo "TAG=${{ github.sha }}" >> $GITHUB_ENV
+ fi
- name: Disable containerd image store
run: |
DAEMON_JSON="/etc/docker/daemon.json"
@@ -93,8 +176,14 @@ jobs:
- name: Log in to the Container registry
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
- registry: ${{ env.HUB }}
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
- - name: Build docker image
- run: make docker.push.java${{ matrix.java-version }} || make docker.push.java${{ matrix.java-version }}
+ registry: ${{ env.DOCKER_REGISTRY }}
+ username: ${{ env.DOCKER_USERNAME }}
+ password: ${{ env.DOCKER_PASSWORD }}
+ # The Makefile builds linux/amd64 and linux/arm64, which needs emulation
+ # and the docker-container buildx driver.
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
+ - name: Build and push docker image
+ run: make docker.push.${{ matrix.base }} || make docker.push.${{ matrix.base }}
diff --git a/docs/en/contribution/release-java-agent.md b/docs/en/contribution/release-java-agent.md
index 5b941a822c..3107827cff 100644
--- a/docs/en/contribution/release-java-agent.md
+++ b/docs/en/contribution/release-java-agent.md
@@ -76,6 +76,14 @@ Then run `gpgconf --kill gpg-agent` and `gpg --sign /dev/null` to cache it.
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
+Before the long build starts, **prepare** asks for the GitHub milestone ID of the next
+development version, which it writes into the reset `CHANGES.md`. Look up the
+`Java - ` milestone at https://github.com/apache/skywalking/milestones and
+enter its number. The ID is checked against that milestone's title, and you are warned if
+they disagree. Set `NEXT_MILESTONE=` to answer non-interactively; leave the prompt
+blank to keep the `milestone/xxx` placeholder and edit it by hand before merging the
+release PR.
+
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
@@ -92,8 +100,49 @@ are found in `https://dist.apache.org/repos/dist/dev/skywalking/java-agent/x.y.z
1. Check the Apache License Header. Run `docker run --rm -v $(pwd):/github/workspace apache/skywalking-eyes header check`. (No binaries in source codes)
## vote-passed
+Every step after `prepare` identifies the release by its **tag** (`vx.y.z`), never by the
+checked-out branch. By the time you run `vote-passed`, the release PR has normally been
+merged and `release/x.y.z` deleted, and `main` has already moved on to the next
+`-SNAPSHOT`; the tag is the only thing that still pins the release. The version defaults to
+the highest `vx.y.z` tag in the repository, and can be overridden with a positional
+argument (`./release.sh docker 9.7.0`) or `RELEASE_VERSION=9.7.0`.
+
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)
+2. **github-release** — publish the GitHub Release for the tag, using `changes/changes-x.y.z.md` as its notes
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`
+
+### Docker images
+Docker images are published by GitHub Actions, not from your machine. Publishing the
+GitHub Release fires the `release: released` trigger in
+[`.github/workflows/publish-docker.yaml`](../../../.github/workflows/publish-docker.yaml),
+which builds every base variant and pushes
+`apache/skywalking-java-agent:x.y.z-{alpine,java8,java11,java17,java21,java25}` to Docker
+Hub for `linux/amd64` and `linux/arm64`. Watch that workflow; if it fails you can fall back
+to pushing from your machine with `./tools/releasing/release.sh docker x.y.z`, which needs
+you to be logged in to Docker Hub with push access to the `apache` organisation.
+
+The image contains the exact tarball that was voted on. The workflow downloads
+`apache-skywalking-java-agent-x.y.z.tgz` from `dist/release`, checks it against the
+published `.sha512`, and verifies the `.asc` signature against the project
+[KEYS](https://downloads.apache.org/skywalking/KEYS) file before it goes into an image — it
+does not rebuild the agent from source.
+
+The same workflow keeps publishing per-commit development images to
+`ghcr.io/apache/skywalking-java` on every push to `main`; only the `release` event
+publishes official versioned images.
+
+#### Docker Hub credentials
+The release path needs the `DOCKERHUB_USER` and `DOCKERHUB_TOKEN` repository secrets. These
+are the names used across the other Apache SkyWalking repositories (`apache/skywalking`,
+`skywalking-python`, `skywalking-mcp`, ...). They are **not** self-service: `.asf.yaml`
+cannot set secrets. File an [ASF INFRA JIRA](https://issues.apache.org/jira/browse/INFRA)
+ticket asking for them to be added to `apache/skywalking-java`, referencing that
+`apache/skywalking` already has them; INFRA holds the Docker Hub account credentials. See
+[GitHub Actions and Secrets](https://infra.apache.org/github-actions-secrets.html).
+
+Until they exist, the release run fails early with an explicit error and you should publish
+with `./tools/releasing/release.sh docker x.y.z` instead. Because `github-release` is
+idempotent, you can also add the secrets later and just re-run the failed workflow from the
+Actions tab — there is no need to delete and recreate the GitHub Release.
diff --git a/tools/releasing/release.sh b/tools/releasing/release.sh
index 22c200dc46..7848138489 100755
--- a/tools/releasing/release.sh
+++ b/tools/releasing/release.sh
@@ -46,6 +46,51 @@ info() { echo -e "${GREEN}[INFO]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }
+# ============================================================
+# resolve_version — identify the release from its tag
+# ============================================================
+# Every step after `prepare` acts on the release tag, never on whatever branch
+# happens to be checked out. `release:perform` builds from the tag, the source
+# tar is cut from the tag, and the vote email quotes the tag's commit IDs.
+#
+# The version therefore has to be derived from the tag as well. `git describe`
+# cannot do this: release tags are created on release/x.y.z branches and never
+# become ancestors of main, so once the release PR is merged and the branch is
+# deleted, describe walks past them to an unrelated ancient tag (v3.2.6 here).
+# That would aim SVN moves and Docker pushes at the wrong version. Tags are
+# branch-independent and outlive the release branch, so select from the tag list.
+#
+# Order of precedence: explicit argument, then $RELEASE_VERSION, then the highest
+# vX.Y.Z tag in the repository.
+resolve_version() {
+ local explicit="${1:-}"
+ [ -z "$explicit" ] && explicit="${RELEASE_VERSION:-}"
+
+ local version
+ if [ -n "$explicit" ]; then
+ version="${explicit#v}"
+ else
+ local latest
+ latest=$(git tag -l 'v[0-9]*.[0-9]*.[0-9]*' --sort=-v:refname | head -1)
+ if [ -z "$latest" ]; then
+ error "No vX.Y.Z release tag found. Pass the version explicitly, e.g. '$0 9.7.0'."
+ fi
+ version="${latest#v}"
+ fi
+
+ case "$version" in
+ [0-9]*.[0-9]*.[0-9]*) ;;
+ *) error "Version must look like x.y.z, got: ${version}" ;;
+ esac
+
+ # Refuse to act on a release that was never tagged.
+ if ! git rev-parse -q --verify "refs/tags/v${version}" >/dev/null 2>&1; then
+ error "Tag v${version} does not exist locally. Run '$0 prepare ${version}' first, or fetch it with 'git fetch origin --tags'."
+ fi
+
+ echo "$version"
+}
+
# ============================================================
# preflight — check tools and environment
# ============================================================
@@ -160,6 +205,40 @@ cmd_prepare() {
echo " Tag: v${version}"
echo " Next dev version: ${next_version}-SNAPSHOT"
echo " Branch: ${branch_name}"
+ echo ""
+
+ # At the end of this step CHANGES.md is reset for the next development
+ # version, and its milestone link needs that version's GitHub milestone ID.
+ # Ask for it here, up front, so the release does not stop for input after
+ # the long release:prepare build. Set NEXT_MILESTONE= to skip the prompt.
+ local next_milestone="${NEXT_MILESTONE:-}"
+ if [ -z "$next_milestone" ]; then
+ echo " CHANGES.md will be reset for ${next_version}, and its milestone link needs an ID."
+ echo " Find 'Java - ${next_version}' at https://github.com/apache/skywalking/milestones"
+ read -rp " Milestone ID for ${next_version} (number, or blank to fill in manually later): " next_milestone
+ fi
+ if [ -n "$next_milestone" ]; then
+ case "$next_milestone" in
+ *[!0-9]*) error "Milestone ID must be a number, got: ${next_milestone}" ;;
+ esac
+ # gh api writes the error body to stdout on failure, so gate on its
+ # exit status rather than letting a 404 payload become the title.
+ local milestone_title
+ if ! milestone_title=$(gh api "repos/apache/skywalking/milestones/${next_milestone}" -q .title 2>/dev/null); then
+ milestone_title=""
+ fi
+ if [ -z "$milestone_title" ]; then
+ warn " Could not verify milestone ${next_milestone} on apache/skywalking; using it as given."
+ elif [ "$milestone_title" != "Java - ${next_version}" ]; then
+ warn " Milestone ${next_milestone} is '${milestone_title}', expected 'Java - ${next_version}'. Double-check it."
+ else
+ info " Next milestone: ${next_milestone} (${milestone_title})"
+ fi
+ else
+ next_milestone="xxx"
+ warn " No milestone ID given; CHANGES.md will keep 'milestone/xxx' - edit it before merging the release PR."
+ fi
+
echo ""
read -rp "Continue? [y/N] " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
@@ -208,7 +287,7 @@ ${next_version}
------------------
-All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/xxx?closed=1)
+All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/${next_milestone}?closed=1)
------------------
Find change logs of all versions [here](changes).
@@ -249,12 +328,11 @@ EOF
cmd_stage() {
cd "$PROJECT_ROOT"
- # Detect version from latest tag
local version
- version=$(git describe --tags --abbrev=0 | sed 's/^v//')
+ version=$(resolve_version "${1:-}")
local tag_name="v${version}"
- info "Staging release ${version}..."
+ info "Staging release ${version} (from tag ${tag_name})..."
# Maven release:perform
info "Running maven release:perform..."
@@ -320,7 +398,7 @@ cmd_upload() {
cd "$PROJECT_ROOT"
local version
- version=$(git describe --tags --abbrev=0 | sed 's/^v//')
+ version=$(resolve_version "${1:-}")
local svn_dev="https://dist.apache.org/repos/dist/dev/skywalking/java-agent"
info "Uploading release ${version} to Apache SVN (dist/dev)..."
@@ -366,13 +444,13 @@ cmd_upload() {
cmd_email() {
local type="${1:-}"
if [[ ! "$type" =~ ^(vote|announce)$ ]]; then
- error "Usage: $0 email [vote|announce]"
+ error "Usage: $0 email [version]"
fi
cd "$PROJECT_ROOT"
local version
- version=$(git describe --tags --abbrev=0 | sed 's/^v//')
+ version=$(resolve_version "${2:-}")
local tag="v${version}"
local commit_id
commit_id=$(git rev-list -n1 "$tag" 2>/dev/null || echo "")
@@ -495,9 +573,9 @@ cmd_docker() {
cd "$PROJECT_ROOT"
local version
- version=$(git describe --tags --abbrev=0 | sed 's/^v//')
+ version=$(resolve_version "${1:-}")
- info "Building and pushing Docker images for ${version}..."
+ info "Building and pushing Docker images for ${version} (from tag v${version})..."
local dist_tar="${SCRIPT_DIR}/${PRODUCT_NAME}-${version}/${PRODUCT_NAME}-${version}.tgz"
@@ -517,6 +595,49 @@ cmd_docker() {
info "Docker images pushed for ${version}."
}
+# ============================================================
+# github-release — publish the GitHub Release
+# ============================================================
+# This is what ships the official Docker images. Publishing a non-prerelease
+# fires the `release: released` trigger in .github/workflows/publish-docker.yaml,
+# which builds every base variant and pushes them to Docker Hub. Running
+# `$0 docker` by hand is only a fallback for when that workflow fails.
+cmd_github_release() {
+ cd "$PROJECT_ROOT"
+
+ local version
+ version=$(resolve_version "${1:-}")
+ local tag="v${version}"
+ local notes_file="changes/changes-${version}.md"
+
+ info "Publishing GitHub Release ${tag}..."
+
+ if ! git ls-remote --tags origin "refs/tags/${tag}" | grep -q .; then
+ error "Tag ${tag} is not on origin. Push it before publishing the release."
+ fi
+
+ if gh release view "${tag}" >/dev/null 2>&1; then
+ warn "GitHub Release ${tag} already exists; leaving it alone."
+ warn "If the images were not pushed, re-run the workflow or use '$0 docker ${version}'."
+ return 0
+ fi
+
+ local -a notes_args
+ if [ -f "$notes_file" ]; then
+ notes_args=(--notes-file "$notes_file")
+ else
+ warn " ${notes_file} not found; using auto-generated notes."
+ notes_args=(--generate-notes)
+ fi
+
+ gh release create "${tag}" --title "${version}" "${notes_args[@]}"
+
+ info "GitHub Release ${tag} published."
+ info " publish-docker.yaml is now pushing to Docker Hub:"
+ info " apache/skywalking-java-agent:${version}-{alpine,java8,java11,java17,java21,java25}"
+ info " Watch: https://github.com/apache/skywalking-java/actions/workflows/publish-docker.yaml"
+}
+
# ============================================================
# promote — move from dist/dev to dist/release
# ============================================================
@@ -524,7 +645,7 @@ cmd_promote() {
cd "$PROJECT_ROOT"
local version
- version=$(git describe --tags --abbrev=0 | sed 's/^v//')
+ version=$(resolve_version "${1:-}")
info "Promoting release ${version} from dist/dev to dist/release..."
@@ -537,10 +658,10 @@ cmd_promote() {
info "Release ${version} promoted."
info "Next steps:"
- info " 1. Release the Nexus staging repository"
+ info " 1. Release the Nexus staging repository at https://repository.apache.org"
info " 2. Update website download page"
- info " 3. Run: $0 email announce"
- info " 4. Run: $0 docker"
+ info " 3. Run: $0 github-release ${version} (pushes the Docker images via GitHub Actions)"
+ info " 4. Run: $0 email announce ${version}"
}
# ============================================================
@@ -578,11 +699,11 @@ cmd_prepare_vote() {
echo ""
cmd_prepare "$version" "$next_version"
echo ""
- cmd_stage
+ cmd_stage "$version"
echo ""
- cmd_upload
+ cmd_upload "$version"
echo ""
- cmd_email vote
+ cmd_email vote "$version"
}
# ============================================================
@@ -591,11 +712,38 @@ cmd_prepare_vote() {
cmd_vote_passed() {
local old_version="${1:-}"
- cmd_promote
+ cd "$PROJECT_ROOT"
+
+ # Resolved from the release tag, so this works after the release branch has
+ # been merged and deleted. Show it before touching SVN or Docker Hub, both of
+ # which are public and awkward to undo.
+ local version
+ version=$(resolve_version "")
+
+ info "Publishing release ${version}:"
+ echo " Release tag : v${version}"
+ echo " SVN promote : dist/dev/skywalking/java-agent/${version} -> dist/release/..."
+ echo " GitHub Release : v${version} (this is what triggers the Docker Hub push)"
+ echo " Docker Hub tags : apache/skywalking-java-agent:${version}-{alpine,java8,java11,java17,java21,java25}"
+ echo " pushed by .github/workflows/publish-docker.yaml, not from here"
+ if [ -n "$old_version" ]; then
+ echo " Remove from SVN : dist/release/skywalking/java-agent/${old_version}"
+ else
+ echo " Remove from SVN : (nothing - no old version given)"
+ fi
+ echo ""
+ read -rp "Continue? [y/N] " confirm
+ if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
+ info "Aborted."
+ exit 0
+ fi
echo ""
- cmd_docker
+
+ cmd_promote "$version"
+ echo ""
+ cmd_github_release "$version"
echo ""
- cmd_email announce
+ cmd_email announce "$version"
if [ -n "$old_version" ]; then
echo ""
@@ -618,8 +766,9 @@ main() {
prepare) cmd_prepare "$@" ;;
stage) cmd_stage "$@" ;;
upload) cmd_upload "$@" ;;
- email) cmd_email "$@" ;;
- docker) cmd_docker "$@" ;;
+ email) cmd_email "$@" ;;
+ github-release) cmd_github_release "$@" ;;
+ docker) cmd_docker "$@" ;;
promote) cmd_promote "$@" ;;
cleanup) cmd_cleanup "$@" ;;
prepare-vote) cmd_prepare_vote "$@" ;;
@@ -634,17 +783,24 @@ main() {
echo " (wait for 72h vote to pass)"
echo " $0 vote-passed [old_version] # after vote"
echo ""
+ echo "Every command after 'prepare' identifies the release by its tag (vX.Y.Z), not by the"
+ echo "checked-out branch, so they still work once release/x.y.z has been merged and deleted."
+ echo "The version defaults to the highest vX.Y.Z tag; override with an argument or RELEASE_VERSION."
+ 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 " stage [ver] Stage release (maven release:perform, build tars)"
+ echo " upload [ver] 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"
+ echo " email [ver] Generate email content"
+ echo " promote [ver] Move from dist/dev to dist/release in SVN"
+ echo " github-release [ver] Publish the GitHub Release; this is what pushes"
+ echo " the Docker images, via publish-docker.yaml"
+ echo " docker [ver] Push Docker images from this machine (fallback"
+ echo " for when the workflow fails)"
+ echo " vote-passed [old_ver] Run promote + github-release + announce [+ cleanup]"
+ echo " cleanup Remove old release from dist/release"
;;
esac
}