ci(release): recompose the installer bundle after publishing
Phase 0 item 3 of docs/installer/PLAN.md wired up from this side. The installer does not resolve "latest" at run time — it installs the exact combination named by a published bundle manifest (PLAN.md §7.1), so until now a new overlay release was invisible to operators until the installer repo's nightly cron noticed it. Adds a final step that POSTs to RunicGateway/installer's bundle workflow-dispatch endpoint. That job re-reads this tarball's manifest.json and checks its declared `protocol` against the sidecar's PROTOCOL_VERSION before publishing anything (gate 1) — the check this repo cannot perform for itself, since the C# plugin announces no version on the wire. It replaces the TODO the header has carried since #7, which was deliberately left unimplemented while there was nothing to dispatch. Dispatch, don't wait (PLAN.md §7.3): Gitea's dispatch endpoint returns no run handle, so there is nothing to poll — a waiting step would have to guess which run is its own while holding a runner idle. The bundle job runs its own gates regardless of who started it. A dispatch failure is a warning, never a failure of this job. By the time this step runs the release is published and correct, so failing the run would misreport that; the installer's nightly cron recomposes from whatever the latest releases actually are, making a dropped dispatch cost latency rather than correctness. That also means REGISTRY_TOKEN having write on the installer repo is a nicety, not a new hard requirement — noted in the header. Verified the workflow still parses and that the new step is last, gated on release=='true', and contains no path that can exit non-zero. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -51,18 +51,22 @@
|
||||
#
|
||||
# Prerequisites (Settings → Actions → Secrets on RunicGateway/servuo-plugins):
|
||||
# REGISTRY_TOKEN — Gitea access token with `write:repository`, to push the
|
||||
# tag and create the release.
|
||||
# tag and create the release. The final step also dispatches
|
||||
# RunicGateway/installer's bundle workflow, so the token
|
||||
# ideally has write there too — a nicety, not a requirement:
|
||||
# without it the step warns and that repo's nightly cron
|
||||
# picks the release up instead.
|
||||
# REGISTRY_USER — the Gitea username that token belongs to.
|
||||
#
|
||||
# These are checked by an explicit preflight step rather than left to fail
|
||||
# wherever they happen to be used first — see the comment on that step for why
|
||||
# an absent token does NOT simply fail the tag push.
|
||||
#
|
||||
# TODO (Phase 0 item 3): once the installer repo's bundle workflow exists, append
|
||||
# a final step here that POSTs to its workflow-dispatch endpoint, so a new
|
||||
# overlay release recomposes the bundle immediately instead of waiting for the
|
||||
# nightly cron (PLAN.md §7.2). Deliberately absent until there is something to
|
||||
# dispatch — a step that 404s every release is worse than no step.
|
||||
# The final step POSTs to the installer repo's bundle workflow, so a new overlay
|
||||
# release recomposes the compat matrix immediately instead of waiting for that
|
||||
# repo's nightly cron (PLAN.md §7.2). It was deliberately absent until Phase 0
|
||||
# item 3 landed something to dispatch — a step that 404s on every release is
|
||||
# worse than no step.
|
||||
|
||||
name: Release overlay
|
||||
|
||||
@@ -84,6 +88,9 @@ env:
|
||||
# house style set by link (pre-1.0; the release version is independent of the
|
||||
# protocol version, which lives in overlay.toml).
|
||||
SEED_VERSION: "0.1.0"
|
||||
# Notified after a release so the installer's compat matrix picks up this
|
||||
# overlay immediately rather than at its next nightly run (PLAN.md §7.2).
|
||||
INSTALLER_REPO: RunicGateway/installer
|
||||
|
||||
jobs:
|
||||
release:
|
||||
@@ -425,3 +432,45 @@ jobs:
|
||||
-F "attachment=@dist/${f}" >/dev/null
|
||||
echo " uploaded ${f}"
|
||||
done
|
||||
|
||||
# ── Recompose the installer's bundle manifest ────────────────────────
|
||||
# The installer does not resolve "latest" at run time — it deploys the
|
||||
# exact overlay named by a published bundle (docs/installer/PLAN.md §7.1).
|
||||
# An overlay release that nobody recomposes around is therefore a release
|
||||
# no operator will ever be offered. This tells the installer repo to
|
||||
# rebuild that manifest now rather than leaving the new version invisible
|
||||
# until its nightly cron.
|
||||
#
|
||||
# That job re-reads this tarball's manifest.json and checks its declared
|
||||
# `protocol` against the sidecar's PROTOCOL_VERSION before publishing
|
||||
# anything (PLAN.md §7.1, gate 1) — which is the check this repo cannot
|
||||
# perform for itself, since the C# plugin announces no version on the wire.
|
||||
#
|
||||
# DISPATCH, DON'T WAIT (PLAN.md §7.3). Gitea's workflow-dispatch endpoint
|
||||
# returns no run handle, so there is nothing to poll: a waiting step would
|
||||
# have to guess which run is its own and hold a runner idle to do it.
|
||||
#
|
||||
# A failure here is a WARNING, never a failure of this job. The release is
|
||||
# already published and correct by this point, and failing the run would
|
||||
# misreport that. The installer's nightly cron recomposes from whatever the
|
||||
# latest releases actually are, so a dropped dispatch costs latency, not
|
||||
# correctness.
|
||||
- name: Ask the installer repo to recompose its bundle
|
||||
if: ${{ steps.plan.outputs.release == 'true' }}
|
||||
env:
|
||||
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
CI_TOKEN="$(printf '%s' "${REGISTRY_TOKEN}" | tr -d '\r\n')"
|
||||
HTTP="$(curl -s -o /dev/null -w '%{http_code}' -X POST \
|
||||
-H "Authorization: token ${CI_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"ref":"main"}' \
|
||||
"https://${GITEA_HOST}/api/v1/repos/${INSTALLER_REPO}/actions/workflows/bundle.yml/dispatches" || echo 000)"
|
||||
case "$HTTP" in
|
||||
20*) echo "Dispatched ${INSTALLER_REPO} bundle.yml (HTTP ${HTTP}) — not waiting for it." ;;
|
||||
403|404)
|
||||
echo "::warning::Could not dispatch ${INSTALLER_REPO} bundle.yml (HTTP ${HTTP}). REGISTRY_TOKEN likely lacks write:repository on that repo. Release ${{ steps.plan.outputs.tag }} is published and fine; its bundle will be composed by the installer's nightly cron instead." ;;
|
||||
*)
|
||||
echo "::warning::Dispatching ${INSTALLER_REPO} bundle.yml returned HTTP ${HTTP}. Release ${{ steps.plan.outputs.tag }} is published and fine; the nightly cron will recompose the bundle." ;;
|
||||
esac
|
||||
|
||||
Reference in New Issue
Block a user