ci(deploy-release): force-sync codeberg + verify tags before chart bump

Today v0.0.19 surfaced a real failure mode: varasys → codeberg push-
mirror is `sync_on_commit: true`, but a transient codeberg 504 mid-
push left 2 of 8 tags un-replicated. BMC chart's Dockerfile fetches
zddc-server-v<X.Y.Z> from codeberg (no egress to git.varasys.io),
so the bumped chart fired BMC pipelines that immediately failed at
`git fetch refs/tags/zddc-server-v0.0.19`. Mirror's next periodic
push (8h default) would self-heal — but by then dev was broken.

Make the stable-cut deterministic: before bumping the chart, force
the push-mirror via the Forgejo API and poll codeberg until all 8
lockstep tags are visible. Fail the job (and skip the chart bump)
if codeberg is genuinely unreachable after 5 min — operator triages
manually rather than triggering downstream builds against a stale
codeberg.

Uses ${{ github.token }} (Forgejo Actions auto-injected) for the
push_mirrors-sync API call. If that token turns out to lack admin
scope on this repo (Forgejo specifics around runner-token perms
vary), the failure will be a clear 401/403 on the curl — switch
to a dedicated CHART_FORGEJO_TOKEN-style secret then.

Local repro:
  FORGEJO_TOKEN=$FORGEJO_TOKEN curl -X POST \
    -H "Authorization: token $FORGEJO_TOKEN" \
    https://git.varasys.io/api/v1/repos/VARASYS/ZDDC/push_mirrors-sync

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
ZDDC 2026-05-20 11:10:55 -05:00
parent bd8301d0f2
commit 703449adc5

View file

@ -118,6 +118,52 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Force-sync codeberg push-mirror + verify all 8 tags landed
# The chart Dockerfile fetches zddc-server-v<X.Y.Z> from
# codeberg (BMC AKS has no egress to git.varasys.io). The
# varasys → codeberg push-mirror is sync_on_commit=true but
# occasionally hits a codeberg 504 mid-push, leaving the tag
# set partially replicated. When that happens, the bump in
# the next step triggers BMC pipelines that immediately fail
# at "git fetch refs/tags/zddc-server-v..." until the next
# mirror interval (8h) catches up.
#
# Force a synchronous sync, then poll codeberg until every
# tool's vX.Y.Z tag is visible. Fails the job (and prevents
# the chart bump) if codeberg is genuinely unreachable after
# 5 min — operator runs the sync API manually after.
env:
FORGEJO_TOKEN: ${{ github.token }}
run: |
set -eu
TAG_VER="${GITHUB_REF#refs/tags/zddc-server-v}"
echo "Triggering push-mirror sync for VARASYS/ZDDC..."
curl -fsS -X POST \
-H "Authorization: token $FORGEJO_TOKEN" \
"https://git.varasys.io/api/v1/repos/${GITHUB_REPOSITORY}/push_mirrors-sync"
echo "Sync triggered; polling codeberg for all 8 v${TAG_VER} tags..."
TOOLS="archive transmittal classifier landing form tables browse zddc-server"
for i in $(seq 1 60); do
MISSING=""
for T in $TOOLS; do
TAG="${T}-v${TAG_VER}"
if ! git ls-remote --tags https://codeberg.org/VARASYS/ZDDC.git \
"refs/tags/${TAG}" 2>/dev/null | grep -q "${TAG}$"; then
MISSING="${MISSING} ${TAG}"
fi
done
if [ -z "$MISSING" ]; then
echo "✓ all 8 tags present on codeberg"
exit 0
fi
echo " (poll $i/60) still missing:${MISSING}"
sleep 5
done
echo "::error::tags still missing from codeberg after 5 min:${MISSING}" >&2
curl -sS -H "Authorization: token $FORGEJO_TOKEN" \
"https://git.varasys.io/api/v1/repos/${GITHUB_REPOSITORY}/push_mirrors" \
| head -c 800 >&2
exit 1
- name: Bump chart for stable cut - name: Bump chart for stable cut
# All bump logic lives in .forgejo/scripts/notify-chart-bump.sh # All bump logic lives in .forgejo/scripts/notify-chart-bump.sh
# — same script the dev workflow uses. See its header for # — same script the dev workflow uses. See its header for