Files
minstrel/.forgejo/workflows/release.yml
T
bvandeusen 4c4399c9bb feat(server,web): expose server version via /healthz + display in Settings
Came up debugging the in-app update flow — wasn't obvious which image
the container was actually running without exec'ing in. New flow:

### Server
- internal/server/version.go: new `var ServerVersion = "dev"`,
  overridden via -ldflags at build time.
- /healthz response gains a "version" key alongside the existing
  "status" + "min_client_version". Backward-compat: existing clients
  ignore unknown JSON fields. Endpoint stays unauthenticated.

### Build
- Dockerfile: new `ARG MINSTREL_VERSION=dev`, threaded into the
  go build -ldflags so the binary's ServerVersion is stamped at
  link time. Default "dev" preserves local `docker build` ergonomics.
- .forgejo/workflows/release.yml: tags step also emits a `version`
  output (the git tag for tag pushes, "main" for branch pushes);
  build step passes it as `--build-arg MINSTREL_VERSION=...`.

### Web
- web/src/lib/components/ServerVersion.svelte: small understated
  text ("Server v2026.05.10.2") that fetches /healthz on mount.
  Renders nothing on parse failure or pre-version images.
- Mounted at the bottom of Settings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 23:13:19 -04:00

102 lines
3.6 KiB
YAML

name: release
# Builds and pushes the minstrel container image to the Forgejo registry.
#
# push to main → :main
# push tag vX.Y.Z → :vX.Y.Z and :latest
# workflow_dispatch → manual trigger (same rules based on the ref)
on:
push:
branches: [main]
tags: ['v*']
# Tag pushes still build (tag releases are intentional, server + Flutter
# share the version). Branch pushes skip when the diff is Flutter-only —
# rebuilding the Go image for a Flutter-only merge wastes CI and churns
# the registry.
paths-ignore:
- 'flutter_client/**'
- 'docs/**'
- '**/*.md'
workflow_dispatch:
jobs:
release:
runs-on: go-ci
env:
IMAGE: git.fabledsword.com/bvandeusen/minstrel
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Detect buildable project
id: guard
shell: bash
run: |
if [ -f Dockerfile ] && [ -f go.mod ]; then
echo "ready=true" >> "$GITHUB_OUTPUT"
else
echo "ready=false" >> "$GITHUB_OUTPUT"
echo "::notice::No Dockerfile + go.mod yet — release build skipped"
fi
- name: Compute image tags
id: tags
if: steps.guard.outputs.ready == 'true'
shell: bash
run: |
if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then
VERSION="${GITHUB_REF#refs/tags/}"
echo "args=-t ${IMAGE}:${VERSION} -t ${IMAGE}:latest" >> "$GITHUB_OUTPUT"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "::notice::Release build: ${VERSION} + latest"
else
echo "args=-t ${IMAGE}:main" >> "$GITHUB_OUTPUT"
echo "version=main" >> "$GITHUB_OUTPUT"
echo "::notice::Main-branch build: :main"
fi
- name: Registry login
if: steps.guard.outputs.ready == 'true'
shell: bash
run: |
echo "${{ secrets.CI_TOKEN }}" \
| docker login git.fabledsword.com -u "${{ github.actor }}" --password-stdin
# In-app update flow (#397): on tag pushes only, fetch the APK
# that flutter.yml is attaching to this same release. flutter.yml
# runs in parallel; poll up to 15 min for the asset to appear.
# On main pushes (or if the APK never lands), client/ stays empty
# and the endpoints return 404 — graceful degradation.
- name: Fetch APK for bundled in-app update channel
if: steps.guard.outputs.ready == 'true' && startsWith(github.ref, 'refs/tags/v')
shell: bash
env:
CI_TOKEN: ${{ secrets.CI_TOKEN }}
run: |
TAG="${GITHUB_REF#refs/tags/}"
REPO="${GITHUB_REPOSITORY}"
APK_URL="https://git.fabledsword.com/${REPO}/releases/download/${TAG}/minstrel-${TAG}.apk"
echo "Polling ${APK_URL} (up to 15 min for flutter.yml to attach)..."
for i in $(seq 1 30); do
if curl -fsSL -H "Authorization: token ${CI_TOKEN}" \
-o client/minstrel.apk "$APK_URL"; then
echo "Got APK on attempt $i"
echo "${TAG}" > client/minstrel.apk.version
ls -lh client/
exit 0
fi
echo "APK not ready yet (attempt $i/30), sleeping 30s..."
sleep 30
done
echo "::warning::APK never appeared at ${APK_URL} after 15 min — image will ship without bundled update channel"
- name: Build and push
if: steps.guard.outputs.ready == 'true'
run: |
docker buildx build \
--build-arg MINSTREL_VERSION="${{ steps.tags.outputs.version }}" \
--push ${{ steps.tags.outputs.args }} .