Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/shared-files.sha256
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,5 @@ fcb6cd0e2a71205b918f545f2680d378c790b774b9852129c5f9c7f3f8eb9860 .github/workfl
09230b04c5f14bdda50a0c862152ff197a656cbc3fd0d110899c5f8150f8aa9a .github/workflows/publish.yml#check-snapshot
51e987d59efd9887b43e345edc0e0f3db21686879e3ca6ea9f0fdbc493d37121 .github/workflows/publish.yml#check-tag
a8637f88765da759a6eaba243d0d0d695053174df581ccbbcc5e5f3a475fc9e9 .github/workflows/publish.yml#verify-signing-key-gradle
f20f0a991ce68fa1dcc8ef4daffc5e5dea2093d9b578aa41d17f18a56555d79f .github/workflows/publish.yml#github-snapshot
83a1288c55d35e4d3972e013009577fb594a9a5fb8b9b7c96a7f6a19db20d8d1 .github/workflows/publish.yml#github-snapshot
ce90d90fcb1f2de35075b91c74411e9eb7d3b43e7965fd592744e914fd04c5db .github/workflows/publish.yml#github-release
39 changes: 37 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -528,23 +528,58 @@ jobs:
# upload on purpose: a failed upload must not leave the release emptier than it was. And only
# here: a versioned v* release is history, github-release never deletes anything. Every
# deletion is printed by name, so the job log is the audit trail.
#
# Asset by asset, never the release. The first form of this job (2026-05-07) deleted the whole
# `snapshot` release with its tag and recreated it; on 2026-05-10 the runs of several main
# pushes minutes apart deleted it under each other, and every job of each burst but the last
# failed in that step with its artifacts present. The job then went with the Central
# migration and came back as `view || create` + `upload --clobber` without any cleanup, which
# is how the backlog grew (workspace/policies/fat-jar-release-assets.md has the runs). Hence
# three guards: an empty upload is refused (every asset would count as stale; the download
# and upload steps above fail first, the guard keeps it so), an asset that is already gone
# counts as removed (two overlapping dispatches may both pick it), and a failed deletion is
# reported and the rest still tried -- the assets of this upload are on the release either
# way, so this is "attach first, then red" like the signature check.
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
keep="$(ls -1 snapshot-assets | sort)"
current="$(gh release view snapshot --repo ${{ github.repository }} --json assets --jq '.assets[].name' | sort)"
if [ -z "$keep" ]; then
echo "::error::refusing to prune: this run uploaded nothing, so every asset of the release would count as stale"
exit 1
fi
list_assets() {
gh release view snapshot --repo ${{ github.repository }} --json assets --jq '.assets[].name' | sort
}
current="$(list_assets)"
stale="$(comm -13 <(printf '%s\n' "$keep") <(printf '%s\n' "$current"))"
if [ -z "$stale" ]; then
echo "nothing to remove: the release holds exactly the $(printf '%s\n' "$keep" | wc -l) asset(s) of this upload"
exit 0
fi
echo "removing $(printf '%s\n' "$stale" | wc -l) asset(s) that are not part of this upload:"
failed=0
while IFS= read -r name; do
[ -n "$name" ] || continue
echo " deleting $name"
gh release delete-asset snapshot "$name" --repo ${{ github.repository }} --yes
if gh release delete-asset snapshot "$name" --repo ${{ github.repository }} --yes; then
continue
fi
if ! remaining="$(list_assets)"; then
echo "::error::could not delete $name, and could not re-read the release to tell whether it is gone"
failed=$((failed + 1))
elif printf '%s\n' "$remaining" | grep -qxF -- "$name"; then
echo "::error::could not delete $name"
failed=$((failed + 1))
else
echo " $name was already gone"
fi
done <<< "$stale"
if [ "$failed" -ne 0 ]; then
echo "::error::$failed asset(s) could not be removed; the $(printf '%s\n' "$keep" | wc -l) asset(s) of this upload are on the release"
exit 1
fi
echo "kept the $(printf '%s\n' "$keep" | wc -l) asset(s) of this upload"
- name: Fail if anything was attached unsigned
# After the upload on purpose: the assets must exist even when the signature does not.
Expand Down
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
signature check existed) and three SpotBugs plugin jars (`fb-contrib-7.6.4.jar`, `fb-contrib-7.7.4.jar`,
`findsecbugs-plugin-1.14.0.jar`) an old collect step uploaded from `target/spotbugs/` in 2026-05, 5 of its
11 assets. `github-snapshot` now deletes every asset
the run did not upload, after the upload and each printed by name; versioned releases are never
pruned, and the next snapshot run clears the backlog by itself. The collect steps copy
the run did not upload, after the upload and each printed by name; it refuses an empty upload,
treats an asset that is already gone as removed and fails only after trying every deletion (asset
by asset on purpose: the job's first form deleted and recreated the release, and failed in every
burst of main pushes in May 2026); versioned releases are never pruned, and the next snapshot run
clears the backlog by itself. The collect steps copy
`<artifactId>-<version>.pom` + `.pom.asc` as well (Central had them, the release did not), and
the signature check counts every attachable type (`*.jar`, `*.aar`, `*.pom`) instead of jars
alone. Shared job text with the two sibling repositories (`shared-files.sha256`), the convention
Expand Down
6 changes: 4 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,10 @@ exists here. The attach jobs are shared text with the two sibling Maven-only rep
signature check counts every attachable type (`*.jar`, `*.aar`, `*.pom`), and `github-snapshot` ends
by deleting every asset of the `snapshot` pre-release that the run did not upload, each printed by
name -- `gh release upload --clobber` never removed anything, so the release accumulated every past
version. Versioned releases are never pruned. See the policy's "Attach first, then go red" and "The
`snapshot` pre-release holds exactly the current upload".
version. The prune refuses an empty upload, treats an asset that is already gone as removed and
fails only after trying every deletion; versioned releases are never pruned. See the policy's
"Attach first, then go red" and "The `snapshot` pre-release holds exactly the current upload", which
also records the delete-and-recreate form of this job (May 2026) and why it is gone.

## Shared files and the release gate (`shared-files` job)

Expand Down
Loading