Compare commits
4 Commits
v1.1.0
...
2724c292a0
| Author | SHA1 | Date | |
|---|---|---|---|
| 2724c292a0 | |||
| 65b12f815b | |||
| eb78059bb5 | |||
| f8d80c07db |
@@ -28,6 +28,11 @@
|
|||||||
# write:package; THIS workflow additionally needs
|
# write:package; THIS workflow additionally needs
|
||||||
# `write:repository` so it can push the bump commit + tag
|
# `write:repository` so it can push the bump commit + tag
|
||||||
# and create the release. Grant that scope to the token.
|
# and create the release. Grant that scope to the token.
|
||||||
|
# The final step also dispatches RunicGateway/installer's
|
||||||
|
# bundle workflow, so the token ideally has write there too
|
||||||
|
# — but that is a nicety, not a requirement: without it the
|
||||||
|
# step warns and the installer's nightly cron picks the
|
||||||
|
# release up instead.
|
||||||
# Also: `main` must accept a direct push from that user (disable branch
|
# Also: `main` must accept a direct push from that user (disable branch
|
||||||
# protection for it, or add it as an exception) — the bump commit lands on main.
|
# protection for it, or add it as an exception) — the bump commit lands on main.
|
||||||
#
|
#
|
||||||
@@ -51,6 +56,13 @@ env:
|
|||||||
BIN: uo-link-sidecar
|
BIN: uo-link-sidecar
|
||||||
LINUX_TARGET: x86_64-unknown-linux-gnu
|
LINUX_TARGET: x86_64-unknown-linux-gnu
|
||||||
WINDOWS_TARGET: x86_64-pc-windows-gnu
|
WINDOWS_TARGET: x86_64-pc-windows-gnu
|
||||||
|
# Ampere/Graviton instances and Pi-class boxes are a realistic ServUO home,
|
||||||
|
# and the shard dials the sidecar out on loopback — so wherever the shard
|
||||||
|
# runs, this binary has to run too (installer PLAN.md §5.2).
|
||||||
|
ARM64_TARGET: aarch64-unknown-linux-gnu
|
||||||
|
# Notified after a release so the installer's compat matrix picks up this
|
||||||
|
# version immediately rather than at its next nightly run (PLAN.md §7.2).
|
||||||
|
INSTALLER_REPO: RunicGateway/installer
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
@@ -129,14 +141,26 @@ jobs:
|
|||||||
echo "==> release=${RELEASE} version=${VERSION} bump=${BUMP} last_tag=${LAST_TAG:-<none>}"
|
echo "==> release=${RELEASE} version=${VERSION} bump=${BUMP} last_tag=${LAST_TAG:-<none>}"
|
||||||
|
|
||||||
# ── RUST ADAPTER: toolchain + cross-compile deps ─────────────────────
|
# ── RUST ADAPTER: toolchain + cross-compile deps ─────────────────────
|
||||||
- name: Install Rust toolchain, Windows target, and MinGW linker
|
- name: Install Rust toolchain, cross targets, and their linkers
|
||||||
if: ${{ steps.plan.outputs.release == 'true' }}
|
if: ${{ steps.plan.outputs.release == 'true' }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
SUDO=""; [ "$(id -u)" -ne 0 ] && SUDO="sudo"
|
SUDO=""; [ "$(id -u)" -ne 0 ] && SUDO="sudo"
|
||||||
$SUDO apt-get update
|
$SUDO apt-get update
|
||||||
|
# The arm64 cross toolchain is not optional for this crate: sqlx's
|
||||||
|
# sqlite feature pulls libsqlite3-sys, which compiles bundled SQLite
|
||||||
|
# from C, so a Rust-only cross build fails at the first .c file.
|
||||||
|
#
|
||||||
|
# libc6-dev-arm64-cross is named explicitly because gcc-aarch64-linux-gnu
|
||||||
|
# only *recommends* it, and this install is --no-install-recommends: the
|
||||||
|
# compiler arrives without arm64 libc headers and SQLite's build dies on
|
||||||
|
# `bits/libc-header-start.h: No such file or directory`. Verified by
|
||||||
|
# reproducing both the failure and the fix in a rust:1-slim-bookworm
|
||||||
|
# container.
|
||||||
$SUDO apt-get install -y --no-install-recommends \
|
$SUDO apt-get install -y --no-install-recommends \
|
||||||
build-essential gcc-mingw-w64-x86-64 curl ca-certificates git jq
|
build-essential gcc-mingw-w64-x86-64 \
|
||||||
|
gcc-aarch64-linux-gnu libc6-dev-arm64-cross \
|
||||||
|
curl ca-certificates git jq
|
||||||
|
|
||||||
if ! command -v cargo >/dev/null 2>&1; then
|
if ! command -v cargo >/dev/null 2>&1; then
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
|
||||||
@@ -146,6 +170,7 @@ jobs:
|
|||||||
export PATH="${HOME}/.cargo/bin:${PATH}"
|
export PATH="${HOME}/.cargo/bin:${PATH}"
|
||||||
rustup component add rustfmt
|
rustup component add rustfmt
|
||||||
rustup target add "${WINDOWS_TARGET}"
|
rustup target add "${WINDOWS_TARGET}"
|
||||||
|
rustup target add "${ARM64_TARGET}"
|
||||||
|
|
||||||
- name: Set the crate version to match the release
|
- name: Set the crate version to match the release
|
||||||
if: ${{ steps.plan.outputs.release == 'true' }}
|
if: ${{ steps.plan.outputs.release == 'true' }}
|
||||||
@@ -187,14 +212,30 @@ jobs:
|
|||||||
AR_x86_64_pc_windows_gnu: x86_64-w64-mingw32-ar
|
AR_x86_64_pc_windows_gnu: x86_64-w64-mingw32-ar
|
||||||
run: cargo build --release --locked --target "${WINDOWS_TARGET}"
|
run: cargo build --release --locked --target "${WINDOWS_TARGET}"
|
||||||
|
|
||||||
|
# Same shape as the Windows step: a linker for Rust's output and a CC/AR
|
||||||
|
# pair for the cc-crate build of bundled SQLite.
|
||||||
|
- name: cargo build --release (Linux arm64, cross via aarch64-linux-gnu)
|
||||||
|
if: ${{ steps.plan.outputs.release == 'true' }}
|
||||||
|
working-directory: sidecar
|
||||||
|
env:
|
||||||
|
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
|
||||||
|
CC_aarch64_unknown_linux_gnu: aarch64-linux-gnu-gcc
|
||||||
|
AR_aarch64_unknown_linux_gnu: aarch64-linux-gnu-ar
|
||||||
|
run: cargo build --release --locked --target "${ARM64_TARGET}"
|
||||||
|
|
||||||
# ── RUST ADAPTER: package artifacts (+ checksums) ────────────────────
|
# ── RUST ADAPTER: package artifacts (+ checksums) ────────────────────
|
||||||
- name: Package artifacts and SHA256SUMS
|
- name: Package artifacts and SHA256SUMS
|
||||||
if: ${{ steps.plan.outputs.release == 'true' }}
|
if: ${{ steps.plan.outputs.release == 'true' }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
cp "${WORKDIR}/target/${LINUX_TARGET}/release/${BIN}" "dist/${BIN}-linux-x86_64"
|
cp "${WORKDIR}/target/${LINUX_TARGET}/release/${BIN}" "dist/${BIN}-linux-x86_64"
|
||||||
|
cp "${WORKDIR}/target/${ARM64_TARGET}/release/${BIN}" "dist/${BIN}-linux-aarch64"
|
||||||
cp "${WORKDIR}/target/${WINDOWS_TARGET}/release/${BIN}.exe" "dist/${BIN}-windows-x86_64.exe"
|
cp "${WORKDIR}/target/${WINDOWS_TARGET}/release/${BIN}.exe" "dist/${BIN}-windows-x86_64.exe"
|
||||||
( cd dist && sha256sum "${BIN}-linux-x86_64" "${BIN}-windows-x86_64.exe" > SHA256SUMS )
|
# Every artifact must appear here: the installer verifies its download
|
||||||
|
# against these sums, and `sha256sum -c` passes silently over a file
|
||||||
|
# this list does not mention.
|
||||||
|
( cd dist && sha256sum "${BIN}-linux-x86_64" "${BIN}-linux-aarch64" \
|
||||||
|
"${BIN}-windows-x86_64.exe" > SHA256SUMS )
|
||||||
ls -l dist && echo "----" && cat dist/SHA256SUMS
|
ls -l dist && echo "----" && cat dist/SHA256SUMS
|
||||||
|
|
||||||
# ── RELEASE ENGINE: commit the bump, tag, push ───────────────────────
|
# ── RELEASE ENGINE: commit the bump, tag, push ───────────────────────
|
||||||
@@ -250,9 +291,51 @@ jobs:
|
|||||||
| jq -r '.id')"
|
| jq -r '.id')"
|
||||||
echo "Created release ${TAG} (id=${REL_ID})"
|
echo "Created release ${TAG} (id=${REL_ID})"
|
||||||
|
|
||||||
for f in "${BIN}-linux-x86_64" "${BIN}-windows-x86_64.exe" SHA256SUMS; do
|
for f in "${BIN}-linux-x86_64" "${BIN}-linux-aarch64" "${BIN}-windows-x86_64.exe" SHA256SUMS; do
|
||||||
curl -sSf -X POST "${API}/releases/${REL_ID}/assets?name=${f}" \
|
curl -sSf -X POST "${API}/releases/${REL_ID}/assets?name=${f}" \
|
||||||
-H "Authorization: token ${CI_TOKEN}" \
|
-H "Authorization: token ${CI_TOKEN}" \
|
||||||
-F "attachment=@dist/${f}" >/dev/null
|
-F "attachment=@dist/${f}" >/dev/null
|
||||||
echo " uploaded ${f}"
|
echo " uploaded ${f}"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# ── Recompose the installer's bundle manifest ────────────────────────
|
||||||
|
# The installer does not resolve "latest" at run time — it installs the
|
||||||
|
# exact combination named by a published bundle (docs/installer/PLAN.md
|
||||||
|
# §7.1). So a sidecar release that nobody recomposes around is a release
|
||||||
|
# no operator will ever be offered. This step tells the installer repo to
|
||||||
|
# rebuild that manifest now, instead of leaving the new version invisible
|
||||||
|
# until its nightly cron.
|
||||||
|
#
|
||||||
|
# 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. The
|
||||||
|
# bundle job runs its own gates regardless of who started it.
|
||||||
|
#
|
||||||
|
# A failure here is a WARNING, never a failure of this job. The release is
|
||||||
|
# already published and correct by this point; failing the run would
|
||||||
|
# misreport that. The installer's nightly cron recomposes from whatever
|
||||||
|
# the latest releases actually are, so a dropped dispatch self-heals — it
|
||||||
|
# costs latency, not correctness.
|
||||||
|
#
|
||||||
|
# `repository_dispatch` is deliberately not used: support for it is
|
||||||
|
# uncertain on this Gitea version, while dispatching an existing
|
||||||
|
# workflow_dispatch workflow via the API works today.
|
||||||
|
- 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