name: Docker # Build the container image and smoke-test it on every PR/push to main/dev. # Publishing is opt-in: set the repo variable PUSH_IMAGE=true and provide the # REGISTRY_* vars/secrets. Without them this only builds + smoke-tests (never # blocks a merge on registry access). on: pull_request: branches: [main, dev] push: branches: [main, dev] jobs: image: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Build image run: docker build -f docker/Dockerfile -t familiar:ci . - name: Smoke-test (/healthz responds, MCP requires a token) run: | set -e docker run -d --name familiar-ci \ -e FAMILIAR_TRANSPORT=http \ -e FAMILIAR_HTTP_HOST=0.0.0.0 \ -e FAMILIAR_HTTP_PORT=8000 \ -e FAMILIAR_HTTP_AUTH_TOKEN=ci-smoke-token \ -p 8000:8000 familiar:ci # Wait for the healthcheck endpoint. for i in $(seq 1 30); do if curl -fsS http://127.0.0.1:8000/healthz >/dev/null; then ok=1; break; fi sleep 1 done test "${ok:-0}" = "1" || { echo "healthz never came up"; docker logs familiar-ci; exit 1; } echo "healthz OK" # MCP endpoint must reject an unauthenticated call. code=$(curl -s -o /dev/null -w '%{http_code}' -X POST http://127.0.0.1:8000/mcp \ -H 'Content-Type: application/json' \ -H 'Accept: application/json, text/event-stream' \ -d '{"jsonrpc":"2.0","id":1,"method":"ping"}') test "$code" = "401" || { echo "expected 401 without token, got $code"; docker logs familiar-ci; exit 1; } echo "auth gate OK (401 without token)" - name: Cleanup if: always() run: docker rm -f familiar-ci || true - name: Log in to registry if: >- github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev') && vars.PUSH_IMAGE == 'true' run: | echo "${{ secrets.REGISTRY_TOKEN }}" | docker login "${{ vars.REGISTRY_HOST }}" \ -u "${{ secrets.REGISTRY_USER }}" --password-stdin - name: Tag + push image if: >- github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev') && vars.PUSH_IMAGE == 'true' run: | # main -> :latest, dev -> :dev, both also tagged with the commit SHA. MOVING=$([ "${{ github.ref_name }}" = "main" ] && echo latest || echo dev) SHA=$(echo "${{ github.sha }}" | cut -c1-12) for tag in "$MOVING" "$SHA"; do docker tag familiar:ci "${{ vars.REGISTRY_IMAGE }}:$tag" docker push "${{ vars.REGISTRY_IMAGE }}:$tag" done