Skip to content

Commit d03c00d

Browse files
wu-shengclaude
andcommitted
Publish release images by dispatch, and build them from the tag
Drop the `release:` trigger. GitHub runs a release event's workflow as it exists at the tag, and the tag is cut at `prepare` while the GitHub Release is published at `vote-passed`, at least 72 hours later. Anything changed in publish-docker.yaml inside that window silently does not apply to the release in flight - which is how 9.7.0 published with no workflow run at all, its tag predating the trigger by a day. The window reopens every release, so the next one only escapes by luck. `github-release` now dispatches the workflow itself after creating the Release, so this stays automatic rather than becoming something to remember. A dispatch always runs the workflow from the default branch, making what publishes a function of main rather than of when the tag happened to be cut. If the dispatch fails the release is still published, so it warns with the retry commands instead of aborting. Nothing else about the run depends on a branch or on timing. 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 rather than from whatever main looks like now. The agent package is still the verified tarball from dist/release, and the image tags come from the version. A leading v on the input is tolerated. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 360ec0e commit d03c00d

3 files changed

Lines changed: 61 additions & 30 deletions

File tree

.github/workflows/publish-docker.yaml

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,21 @@ 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.
3034
#
31-
# workflow_dispatch is the way to publish when the release trigger cannot fire.
32-
# For a `release` event GitHub runs the workflow as it exists **at the tag**, so a
33-
# tag cut before this trigger was added produces no run at all - which is what
34-
# happened to 9.7.0. A dispatch always runs the workflow from the default branch,
35-
# so it is also the way to retry a release whose images failed to push.
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.
3638
on:
3739
push:
3840
branches:
3941
- main
40-
release:
41-
types:
42-
- released
4342
workflow_dispatch:
4443
inputs:
4544
version:
@@ -49,9 +48,9 @@ on:
4948

5049
env:
5150
SKIP_TEST: true
52-
# Non-empty exactly when this run publishes an official release, from either
53-
# trigger. Everything below keys off this rather than the event name.
54-
RELEASE_TAG: ${{ github.event.release.tag_name || github.event.inputs.version }}
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 }}
5554

5655
jobs:
5756
# One agent package feeds every image. The variants differ only in the JRE they
@@ -134,11 +133,25 @@ jobs:
134133
# A release publishes the complete set the previous manual `make
135134
# docker.push.*` produced, alpine included. Per-commit development
136135
# images keep the existing JRE-only set.
137-
base: ${{ (github.event.release.tag_name || github.event.inputs.version) && 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"]') }}
138137
steps:
139138
- uses: actions/checkout@v2
140139
with:
141140
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'
142155
- uses: actions/download-artifact@v4
143156
with:
144157
name: skywalking-agent

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

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,22 +134,25 @@ 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 normally 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
142142
Hub for `linux/amd64` and `linux/arm64`. Watch that workflow.
143143

144-
If it does not start, or it fails, run it by hand: **Actions → publish-docker → Run
145-
workflow**, entering the version (`9.7.0`). A dispatch always runs the workflow from the
146-
default branch and does the same download-and-verify, so it is the normal way to retry.
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.
147147

148148
> [!NOTE]
149-
> For a `release` event GitHub runs the workflow **as it exists at the tag**, not as it
150-
> exists on `main`. A tag cut before a trigger was added to `publish-docker.yaml` therefore
151-
> produces no run at all — this is exactly what happened to 9.7.0, whose tag predates the
152-
> release trigger. Use the manual dispatch in that case.
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`.
153156
154157
As a last resort you can push from your machine with
155158
`./tools/releasing/release.sh docker x.y.z`, which needs you to be logged in to Docker Hub

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)