Skip to content

Commit 1dd1cd8

Browse files
authored
Publish release images by dispatch, built from the tag (#823)
Publishing the 9.7.0 GitHub Release produced no workflow run at all - not a failed one, nothing - and the images were never pushed. GitHub runs a release event's workflow as it exists at the tag, not as it exists on the default branch. The v9.7.0 tag was cut on 12 Aug and the release trigger landed on main the next day, so GitHub read the tag's copy of publish-docker.yaml, found no release trigger, and correctly did nothing. That is not a one-off. The tag is cut at `prepare` and the Release is published at `vote-passed`, at least 72 hours later, so anything changed in this workflow inside that window silently does not apply to the release in flight. The window reopens every release; 9.7.0 was just the first time something landed in it. Drop the release trigger and dispatch instead. `github-release` creates the Release and then runs `gh workflow run publish-docker.yaml -f version=x.y.z`, so publishing stays automatic rather than becoming something to remember, and there is one path rather than two that could both fire. A dispatch always runs the workflow from the default branch, which makes what publishes a function of main rather than of when the tag happened to be cut. If the dispatch fails the Release is already out, so the script warns with the retry commands instead of aborting. Everything the run acts on still comes from the tag rather than from a branch or a timestamp. The tree is checked out at refs/tags/vx.y.z, so Dockerfile and Makefile - which decide what the image actually is - come from the released source instead of from whatever main looks like now; without that a dispatch would have built with main's copies. The agent package remains the sha512- and signature-verified tarball from dist/release, and the image tags come from the version. A leading v on the input is tolerated, and leaving it blank builds a development image exactly as a push to main does.
1 parent fc00d4f commit 1dd1cd8

3 files changed

Lines changed: 83 additions & 27 deletions

File tree

.github/workflows/publish-docker.yaml

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,33 @@ name: publish-docker
2424
# tagged x.y.z-<base>, pushed to Docker Hub as
2525
# apache/skywalking-java-agent.
2626
#
27-
# The release trigger is `released` rather than `published`, so publishing a
28-
# pre-release does not ship official images. Creating the GitHub Release is the
29-
# last step of `tools/releasing/release.sh vote-passed`.
27+
# Releases publish by dispatch, deliberately, rather than by a `release` trigger.
28+
# For a `release` event GitHub runs the workflow as it exists **at the tag**, and
29+
# the tag is cut at `prepare` while the GitHub Release is published at
30+
# `vote-passed`, at least 72 hours later. Anything changed here in between would
31+
# silently not apply to the release in flight - that window is how 9.7.0 shipped
32+
# with no workflow run at all. A dispatch always runs the workflow from the
33+
# default branch, so what is on main is what publishes.
34+
#
35+
# `release.sh github-release` creates the Release and then dispatches this
36+
# workflow, so this stays automatic; running it by hand from the Actions tab is
37+
# how you retry a release whose images failed to push.
3038
on:
3139
push:
3240
branches:
3341
- main
34-
release:
35-
types:
36-
- released
42+
workflow_dispatch:
43+
inputs:
44+
version:
45+
description: 'Release version to publish to Docker Hub, e.g. 9.7.0. Leave blank to build a development image from main.'
46+
required: false
47+
default: ''
3748

3849
env:
3950
SKIP_TEST: true
51+
# Non-empty exactly when this run publishes an official release. Everything
52+
# below keys off this rather than the event name.
53+
RELEASE_TAG: ${{ github.event.inputs.version }}
4054

4155
jobs:
4256
# One agent package feeds every image. The variants differ only in the JRE they
@@ -56,19 +70,19 @@ jobs:
5670

5771
# Development images are compiled from the branch.
5872
- name: Cache local Maven repository
59-
if: github.event_name != 'release'
73+
if: env.RELEASE_TAG == ''
6074
uses: actions/cache@v4
6175
with:
6276
path: ~/.m2/repository
6377
key: ${{ runner.os }}-maven-publish-docker-${{ hashFiles('**/pom.xml') }}
6478
restore-keys: ${{ runner.os }}-maven-publish-docker-
6579
- uses: actions/setup-java@v2
66-
if: github.event_name != 'release'
80+
if: env.RELEASE_TAG == ''
6781
with:
6882
distribution: temurin
6983
java-version: 17
7084
- name: Build Agent
71-
if: github.event_name != 'release'
85+
if: env.RELEASE_TAG == ''
7286
run: make build
7387

7488
# A release is never rebuilt. The published image has to carry the artifact
@@ -79,11 +93,10 @@ jobs:
7993
# from dist/dev to dist/release immediately before the GitHub Release that
8094
# triggers this workflow, so the file is in place by the time this runs.
8195
- name: Download the released agent package
82-
if: github.event_name == 'release'
96+
if: env.RELEASE_TAG != ''
8397
run: |
8498
set -euo pipefail
85-
TAG=${{ github.event.release.tag_name }}
86-
VERSION=${TAG#v}
99+
VERSION=${RELEASE_TAG#v}
87100
BASE="https://dist.apache.org/repos/dist/release/skywalking/java-agent/${VERSION}"
88101
TARBALL="apache-skywalking-java-agent-${VERSION}.tgz"
89102
@@ -120,18 +133,32 @@ jobs:
120133
# A release publishes the complete set the previous manual `make
121134
# docker.push.*` produced, alpine included. Per-commit development
122135
# images keep the existing JRE-only set.
123-
base: ${{ github.event_name == 'release' && fromJSON('["alpine","java8","java11","java17","java21","java25"]') || fromJSON('["java8","java11","java17","java21","java25"]') }}
136+
base: ${{ github.event.inputs.version && fromJSON('["alpine","java8","java11","java17","java21","java25"]') || fromJSON('["java8","java11","java17","java21","java25"]') }}
124137
steps:
125138
- uses: actions/checkout@v2
126139
with:
127140
submodules: true
141+
# The workflow file necessarily comes from the default branch on a
142+
# dispatch - that is the point, it is what makes the run deterministic. The
143+
# tree it builds must not. Dockerfile and Makefile decide what the image
144+
# actually is, so for a release take them from the tag, exactly as the
145+
# release:perform build and the source tarball did.
146+
- name: Check out the released tag
147+
if: env.RELEASE_TAG != ''
148+
run: |
149+
set -euo pipefail
150+
VERSION=${RELEASE_TAG#v}
151+
git fetch --depth 1 origin "refs/tags/v${VERSION}:refs/tags/v${VERSION}"
152+
git checkout "refs/tags/v${VERSION}"
153+
git submodule update --init --depth 1
154+
git --no-pager log -1 --format='building from %h %d'
128155
- uses: actions/download-artifact@v4
129156
with:
130157
name: skywalking-agent
131158
path: skywalking-agent
132159
- name: Set environment variables
133160
run: |
134-
if [[ "${{ github.event_name }}" == "release" ]]; then
161+
if [[ -n "${RELEASE_TAG}" ]]; then
135162
# Provisioned by ASF INFRA on request, as for apache/skywalking.
136163
# Without them docker/login-action fails with an opaque error, so say
137164
# what is actually missing.
@@ -149,8 +176,7 @@ jobs:
149176
echo "DOCKER_REGISTRY=docker.io" >> $GITHUB_ENV
150177
echo "DOCKER_USERNAME=${{ secrets.DOCKERHUB_USER }}" >> $GITHUB_ENV
151178
echo "DOCKER_PASSWORD=${{ secrets.DOCKERHUB_TOKEN }}" >> $GITHUB_ENV
152-
TAG=${{ github.event.release.tag_name }}
153-
echo "TAG=${TAG#v}" >> $GITHUB_ENV
179+
echo "TAG=${RELEASE_TAG#v}" >> $GITHUB_ENV
154180
else
155181
echo "HUB=ghcr.io/apache/skywalking-java" >> $GITHUB_ENV
156182
echo "DOCKER_REGISTRY=ghcr.io" >> $GITHUB_ENV

docs/en/contribution/release-java-agent.md

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,29 @@ After the vote passes, run `vote-passed` which executes:
134134
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`
135135

136136
### Docker images
137-
Docker images are published by GitHub Actions, not from your machine. Publishing the
138-
GitHub Release fires the `release: released` trigger in
139-
[`.github/workflows/publish-docker.yaml`](../../../.github/workflows/publish-docker.yaml),
140-
which builds every base variant and pushes
137+
Docker images are published by GitHub Actions, not from your machine. `github-release`
138+
publishes the GitHub Release and then dispatches
139+
[`.github/workflows/publish-docker.yaml`](../../../.github/workflows/publish-docker.yaml)
140+
with the release version. It builds every base variant and pushes
141141
`apache/skywalking-java-agent:x.y.z-{alpine,java8,java11,java17,java21,java25}` to Docker
142-
Hub for `linux/amd64` and `linux/arm64`. Watch that workflow; if it fails you can fall back
143-
to pushing from your machine with `./tools/releasing/release.sh docker x.y.z`, which needs
144-
you to be logged in to Docker Hub with push access to the `apache` organisation.
142+
Hub for `linux/amd64` and `linux/arm64`. Watch that workflow.
143+
144+
If it fails, run it again: **Actions → publish-docker → Run workflow**, entering the
145+
version (`9.7.0`). That is the same path `github-release` takes, so retrying is safe and
146+
idempotent.
147+
148+
> [!NOTE]
149+
> There is deliberately **no `release:` trigger**. GitHub runs a release event's workflow as
150+
> it exists *at the tag*, and the tag is cut at `prepare` while the Release is published at
151+
> `vote-passed`, at least 72 hours later — so any change to the workflow in between would
152+
> silently not apply to the release in flight. That window is why 9.7.0 published with no
153+
> workflow run at all. Dispatching instead means the workflow always comes from `main`,
154+
> while everything it acts on comes from the tag: the tree it builds is checked out at
155+
> `vx.y.z`, and the agent package is the verified tarball from `dist/release`.
156+
157+
As a last resort you can push from your machine with
158+
`./tools/releasing/release.sh docker x.y.z`, which needs you to be logged in to Docker Hub
159+
with push access to the `apache` organisation.
145160

146161
The image contains the exact tarball that was voted on. The workflow downloads
147162
`apache-skywalking-java-agent-x.y.z.tgz` from `dist/release`, checks it against the

tools/releasing/release.sh

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -689,11 +689,26 @@ cmd_github_release() {
689689
fi
690690

691691
gh release create "${tag}" --title "${version}" "${notes_args[@]}"
692-
693692
info "GitHub Release ${tag} published."
694-
info " publish-docker.yaml is now pushing to Docker Hub:"
695-
info " apache/skywalking-java-agent:${version}-{alpine,java8,java11,java17,java21,java25}"
696-
info " Watch: https://github.com/apache/skywalking-java/actions/workflows/publish-docker.yaml"
693+
694+
# Dispatch rather than let a `release` trigger fire. GitHub runs a release
695+
# event's workflow as it exists at the tag, and the tag is cut at `prepare`
696+
# while this runs at `vote-passed`, at least 72 hours later - anything
697+
# changed in publish-docker.yaml in between would silently not apply. A
698+
# dispatch always runs the workflow from the default branch, so the release
699+
# publishes with what is on main, and builds from the tag.
700+
info "Dispatching publish-docker for ${version}..."
701+
if gh workflow run publish-docker.yaml -f version="${version}"; then
702+
info " Pushing to Docker Hub:"
703+
info " apache/skywalking-java-agent:${version}-{alpine,java8,java11,java17,java21,java25}"
704+
info " Watch: https://github.com/apache/skywalking-java/actions/workflows/publish-docker.yaml"
705+
else
706+
warn " Could not dispatch publish-docker. The release itself is published;"
707+
warn " only the images are missing. Retry with:"
708+
warn " gh workflow run publish-docker.yaml -f version=${version}"
709+
warn " or from Actions -> publish-docker -> Run workflow, or as a last resort"
710+
warn " $0 docker ${version}"
711+
fi
697712
}
698713

699714
# ============================================================

0 commit comments

Comments
 (0)