Skip to content

Manage per-model recipe options without loading #879

Manage per-model recipe options without loading

Manage per-model recipe options without loading #879

# .github/workflows/container-build-test.yml
name: Container Build Tests
on:
pull_request:
paths:
- Dockerfile
- CMakeLists.txt
- CMakePresets.json
- cmake/**
- src/cpp/**
- src/web-app/**
- .github/workflows/build-and-push-container.yml
- .github/workflows/container-build-test.yml
workflow_dispatch:
inputs:
upload_arm64_artifact:
description: Upload the ARM64 image for external testing
type: boolean
required: false
default: false
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name == 'pull_request' && 'pr' || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
build-and-smoke-test:
name: Build and smoke test (${{ matrix.arch }})
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
platform: linux/amd64
runner: ubuntu-latest
- arch: arm64
platform: linux/arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
timeout-minutes: 90
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build container
uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile
platforms: ${{ matrix.platform }}
load: true
push: false
tags: lemonade-server:test-${{ matrix.arch }}
cache-from: type=gha,scope=container-${{ matrix.arch }}
cache-to: type=gha,mode=max,scope=container-${{ matrix.arch }}
- name: Verify image architecture
shell: bash
run: |
set -euo pipefail
actual_arch="$(
docker image inspect \
"lemonade-server:test-${{ matrix.arch }}" \
--format '{{.Architecture}}'
)"
if [[ "${actual_arch}" != "${{ matrix.arch }}" ]]; then
echo "Expected ${{ matrix.arch }}, got ${actual_arch}"
exit 1
fi
- name: Verify CLI starts
run: |
docker run --rm \
"lemonade-server:test-${{ matrix.arch }}" \
lemonade --help
- name: Verify runtime C toolchain
shell: bash
run: |
set -euo pipefail
docker run --rm \
"lemonade-server:test-${{ matrix.arch }}" \
bash -c 'set -euo pipefail
tmp="$(mktemp -d)"
printf "%s\n" "#include <stdlib.h>" "void launcher(void) {}" > "${tmp}/launcher.c"
gcc -O3 -shared -fPIC -o "${tmp}/launcher.so" "${tmp}/launcher.c"
test -f "${tmp}/launcher.so"
'
- name: Start server
run: |
docker run --detach \
--name lemonade-smoke \
--publish 127.0.0.1:13305:13305 \
"lemonade-server:test-${{ matrix.arch }}"
- name: Check server health
shell: bash
run: |
set -euo pipefail
for attempt in $(seq 1 60); do
if curl --fail --silent \
http://127.0.0.1:13305/live \
> /dev/null; then
exit 0
fi
sleep 2
done
echo "Server failed to become healthy"
docker logs lemonade-smoke
exit 1
- name: Show server logs
if: failure()
run: docker logs lemonade-smoke || true
- name: Stop server
if: always()
run: docker rm --force lemonade-smoke || true
- name: Export ARM64 image
if: >-
matrix.arch == 'arm64' &&
github.event_name == 'workflow_dispatch' &&
inputs.upload_arm64_artifact
shell: bash
run: |
set -euo pipefail
docker save "lemonade-server:test-arm64" \
| gzip -1 \
> lemonade-server-arm64.tar.gz
- name: Upload ARM64 test image
if: >-
matrix.arch == 'arm64' &&
github.event_name == 'workflow_dispatch' &&
inputs.upload_arm64_artifact
uses: actions/upload-artifact@v4
with:
name: lemonade-server-arm64-${{ github.sha }}
path: lemonade-server-arm64.tar.gz
if-no-files-found: error
retention-days: 7
compression-level: 0