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
69 changes: 56 additions & 13 deletions .github/workflows/release-drift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@
# job is the backstop for when somebody forgets, which is the right shape for a
# rule no tooling here enforces.
#
# ## It also checks which release GitHub calls "Latest"
#
# Because the remedy for the first check broke it. 0.13.0 was re-pushed on its
# own as advised, released the day AFTER 0.16.0, and GitHub — which picks the
# newest-published release, not the highest version, when nobody says otherwise —
# made 0.13.0 "Latest". `mise use github:chussenot/pact@latest` then installed
# 0.13.0 for seven weeks. Both lists agreed on every tag that mattered; the badge
# was the only thing wrong, and nothing compared it to anything.
#
# `release.yml` now passes `--latest` explicitly, but a re-pushed tag runs the
# workflow AS IT WAS AT THAT TAG, so recovering an old tag still runs the old
# pipeline. Hence the remedy below ends with putting the badge back.
#
# ## Why it only reports
#
# It opens no release. Republishing a tag is a decision with a blast radius —
Expand Down Expand Up @@ -91,19 +104,49 @@ jobs:
fi
done

if [ -z "$missing" ]; then
# The highest PUBLISHED version: what "Latest" must be, and so what
# `@latest` installs.
highest="$(grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' <<<"$releases" | tail -n1)"
failed=0

if [ -n "$missing" ]; then
failed=1
echo "::error::tags on master with no GitHub release:$missing"
echo
echo "Most likely cause: more than three tags were pushed in one push, so"
echo "GitHub created no tag push events and release.yml never ran. Push"
echo "version tags one at a time."
echo
echo "To release a missed tag, re-push it on its own:"
for tag in $missing; do
echo " git push origin :refs/tags/$tag && git push origin $tag"
done
echo
echo "Each re-push runs release.yml as it was AT THAT TAG, which may not"
echo "set --latest. When they have all finished, put the badge back:"
# The badge's target once the re-pushes land, which is a missing tag
# itself when the newest tag is the one that never released.
target="$(printf '%s\n' "$highest" $missing | sort -V | tail -n1)"
echo " gh release edit $target --latest"
echo
else
echo "every version tag on master has a release"
exit 0
fi

echo "::error::tags on master with no GitHub release:$missing"
echo
echo "Most likely cause: more than three tags were pushed in one push, so"
echo "GitHub created no tag push events and release.yml never ran. Push"
echo "version tags one at a time."
echo
echo "To release a missed tag, re-push it on its own:"
for tag in $missing; do
echo " git push origin :refs/tags/$tag && git push origin $tag"
done
exit 1
# Compared against releases, not tags: a tag still waiting on its
# release is the check above's problem, not this one's.
latest="$(gh release view --json tagName -q .tagName)"
if [ "$latest" != "$highest" ]; then
failed=1
echo "::error::GitHub's Latest release is $latest, but the highest published version is $highest"
echo
echo "Anything installing @latest is getting $latest. Most likely cause: an"
echo "older tag was released after $highest and GitHub gave it the badge."
echo
echo "To fix:"
echo " gh release edit $highest --latest"
else
echo "Latest is $latest, the highest published version"
fi

exit "$failed"
17 changes: 17 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -513,14 +513,31 @@ jobs:
# Neither a draft nor a prerelease: 0.x IS this project's release series,
# and a draft that needs a human to press a button is a release that
# sometimes does not happen.
#
# `--latest` is ALWAYS passed, true or false, never left to GitHub. Left
# unset, the newest-PUBLISHED release wins, not the highest version: 0.13.0
# was released late, the day after 0.16.0, took the "Latest" badge, and
# `mise use github:chussenot/pact@latest` installed 0.13.0 for seven weeks
# while every check stayed green. A late release of an old tag is exactly
# what `release-drift.yml` tells you to do, so this is the normal path.
- name: Create the release
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ needs.resolve.outputs.tag }}
run: |
set -euo pipefail
# Latest iff no PUBLISHED release outranks this tag. Released, not
# tagged: a higher tag whose release never happened must not leave the
# repository with no Latest at all.
highest="$(
{ gh release list --limit 200 --json tagName -q '.[].tagName'; echo "$TAG"; } \
| grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n1
)"
if [ "$highest" = "$TAG" ]; then latest=true; else latest=false; fi
echo "highest published version after this release: $highest (latest=$latest)"
gh release create "$TAG" \
--title "$TAG" \
--notes-file /tmp/notes.md \
--verify-tag \
--latest="$latest" \
dist/*.tar.gz dist/SHA256SUMS
2 changes: 0 additions & 2 deletions cog.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,3 @@ path = "CHANGELOG.md"
authors = []

[bump_profiles]

[packages]
Loading