Files
llmrouter/.gitea/workflows/ci.yml
T
elton 53dbcf65bb
llmrouter CI / bun test + build (push) Successful in 3s
llmrouter CI / Build and publish image (push) Failing after 17s
Gitea-Actions-CI nach live-Muster
bun test + Build je Push/PR; Push nach main published
git.42i.org/spine/llmrouter:latest (+sha-Tag) und verifiziert den Pull per
/health im Container. Muster: dev-image.yml aus 42i/live (buildx, eigener
Builder, --privileged, DOCKER_API_VERSION 1.43, Verify-Pull).
2026-09-08 09:48:13 +02:00

131 lines
3.9 KiB
YAML

name: llmrouter CI
# Test- und Image-Bau nach dem Muster der live-Workflows (42i/live
# .gitea/workflows/dev-image.yml): Positive paths-Listen statt paths-ignore
# (live#2266), concurrency-Block für Gitea 1.26 (live#1350), buildx mit
# eigenem Builder hinter --privileged und DOCKER_API_VERSION 1.43,
# Registry-Login über die Repo-Secrets user/password, Verify-Pull als
# Abschluss (42i/intern#1101).
on:
push:
branches: [main]
paths:
- "src/**"
- "test/**"
- "config.json"
- "key-acls.json"
- "package.json"
- "docker/**"
- "docker-compose.yml"
- ".gitea/workflows/ci.yml"
pull_request:
paths:
- "src/**"
- "test/**"
- "config.json"
- "key-acls.json"
- "package.json"
- "docker/**"
- "docker-compose.yml"
- ".gitea/workflows/ci.yml"
workflow_dispatch: {}
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
name: bun test + build
runs-on: docker
container:
image: git.42i.org/42i/dev:latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install
run: bun install
- name: Test
run: bun test
- name: Build (statisches Linux-Binary)
run: bun run build
image:
# Pure CD wie in live: jeder Push nach main baut und published;
# Pull Requests testen nur.
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: test
name: Build and publish image
runs-on: docker
container:
image: git.42i.org/42i/dev:latest
# docker buildx build braucht Zugriff auf den Docker-Host.
options: --privileged
env:
GITEA_SERVER_URL: https://git.42i.org
CI_REGISTRY_USER: ${{ secrets.user }}
CI_REGISTRY_PASSWORD: ${{ secrets.password }}
DOCKER_API_VERSION: "1.43"
BUILDER: llmrouter-ci
IMAGE: git.42i.org/spine/llmrouter:latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Docker login
run: |
echo "${CI_REGISTRY_PASSWORD}" | docker login "${GITEA_SERVER_URL}" -u "${CI_REGISTRY_USER}" --password-stdin
- name: Prepare builder
run: |
docker buildx inspect "${BUILDER}" >/dev/null 2>&1 || \
docker buildx create --name "${BUILDER}" --driver docker-container --use
docker buildx use "${BUILDER}"
docker buildx inspect "${BUILDER}" --bootstrap
- name: Build and push
run: |
# Nur linux/amd64: einziger Konsument ist der LXC auf x86.
SHA_TAG="git.42i.org/spine/llmrouter:sha-${GITHUB_SHA:0:7}"
docker buildx build \
--builder "${BUILDER}" \
--platform linux/amd64 \
-f docker/Dockerfile \
-t "${IMAGE}" \
-t "${SHA_TAG}" \
--push \
.
- name: Prune builder cache
if: always()
run: |
docker buildx prune --builder "${BUILDER}" -af || true
# Dem Push-Erfolg allein vertrauen wir nicht (42i/intern#1101) — frisch
# pullen, starten und /health im Container selbst prüfen (ohne
# Host-Ports, keine Secrets nötig: der Router lauscht auch ohne).
- name: Verify pull and health
run: |
set -u
docker pull "${IMAGE}"
CID=$(docker run -d --rm "${IMAGE}")
OK=0
for i in $(seq 1 15); do
if docker exec "$CID" bun -e 'const r = await fetch("http://127.0.0.1:4010/health"); process.exit(r.ok ? 0 : 1)'; then
OK=1
break
fi
sleep 2
done
if [ "$OK" -ne 1 ]; then
echo "health check failed" >&2
docker logs "$CID" 2>&1 || true
docker rm -f "$CID" 2>/dev/null || true
exit 1
fi
echo "llmrouter image verified: /health ok"
docker stop -t 2 "$CID"