feat(vibe-kanban-remote): build the self-hosted remote-server image
Some checks failed
images / hermes (push) Failing after 59s
images / vibe-kanban-remote (push) Has been cancelled

Builds crates/remote/Dockerfile from our mirror at git.lair.cafe rather than
from GitHub, and resolves the version from the mirror's tags rather than
GitHub's releases API. BloopAI has announced a sunset; the mirror exists so
this build outlives them, which is pointless if the build still asks
github.com what to build. Nothing in this image's path touches GitHub.

Gitea mirrors carry tags but not releases, so latest is resolved by filtering
to the strict release pattern v<semver>-<14-digit datestamp> and sorting on
the datestamp -- which also skips the malformed historical tags in the
upstream repo (vv.20250708094151, vv0.0.40-nbump.2....).

FEATURES is deliberately left unset: the Dockerfile strips the private
billing crate only when it is empty, which is the documented self-host path.
Setting it would send the build looking for BloopAI/vibe-kanban-private over
SSH, which we cannot reach.

Consumed by the vibe-kanban quadlets on bob (kanban.internal).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TsmUEtbyTkgQ18tCFYXo1h
This commit is contained in:
2026-07-20 18:18:43 +03:00
parent d53e06d784
commit dff283c468
4 changed files with 172 additions and 0 deletions

View File

@@ -80,3 +80,62 @@ jobs:
podman push "${IMAGE}:${VERSION}"
podman push "${IMAGE}:latest"
echo "published ${IMAGE}:${VERSION} (and :latest)"
vibe-kanban-remote:
runs-on:
- metal
- podman
steps:
- uses: actions/checkout@v4
# Resolved from OUR MIRROR, not GitHub: BloopAI has announced a sunset and
# the mirror exists so this build outlives them — which is pointless if the
# build asks github.com what to build. Gitea mirrors carry tags but not
# releases, so filter to the strict release pattern and sort on the trailing
# datestamp (also skips malformed historical tags like `vv.20250708094151`).
- name: resolve latest upstream release (from the mirror)
id: rel
run: |
tag=$(for p in 1 2 3 4 5; do
curl -fsS "https://git.lair.cafe/api/v1/repos/BloopAI/vibe-kanban/tags?limit=100&page=${p}" \
| jq -r '.[].name'
done \
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+-[0-9]{14}$' \
| sort -t- -k2 -n \
| tail -1)
if [ -z "$tag" ]; then
echo "ERROR: could not resolve a vibe-kanban tag from the mirror"; exit 1
fi
echo "mirror latest: $tag"
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "version=${tag#v}" >> "$GITHUB_OUTPUT"
- name: login to registry
run: podman login -u ${{ gitea.actor }} -p ${{ secrets.REGISTRY_TOKEN }} git.lair.cafe
- name: build & push (release-triggered, self-healing)
env:
TAG: ${{ steps.rel.outputs.tag }}
VERSION: ${{ steps.rel.outputs.version }}
FORCE: ${{ github.event.inputs.force }}
run: |
IMAGE=git.lair.cafe/lair/vibe-kanban-remote
if [ "$FORCE" != "true" ] && skopeo inspect "docker://${IMAGE}:${VERSION}" >/dev/null 2>&1; then
echo "${IMAGE}:${VERSION} already published — nothing to build"
exit 0
fi
# Upstream ships the Dockerfile; context is the repo root, so -f points
# into it. FEATURES is deliberately unset — the Dockerfile strips the
# private billing crate only when it is empty (the self-host path), and
# we have no access to BloopAI/vibe-kanban-private.
# VITE_RELAY_API_BASE_URL is baked into the SPA; empty = relay disabled.
echo "building ${IMAGE}:${VERSION} from the mirror at ${TAG}"
podman build --pull=newer \
-f crates/remote/Dockerfile \
--build-arg VITE_RELAY_API_BASE_URL= \
-t "${IMAGE}:${VERSION}" \
-t "${IMAGE}:latest" \
"https://git.lair.cafe/BloopAI/vibe-kanban.git#${TAG}"
podman push "${IMAGE}:${VERSION}"
podman push "${IMAGE}:latest"
echo "published ${IMAGE}:${VERSION} (and :latest)"