Skip to content

fix: resolve conformance contract gaps — version, health, headers, tracing #271

fix: resolve conformance contract gaps — version, health, headers, tracing

fix: resolve conformance contract gaps — version, health, headers, tracing #271

Workflow file for this run

name: CI
on:
pull_request:
paths-ignore:
- '**/*.md'
- 'docs/**'
- 'archive/**'
push:
branches: [main]
paths-ignore:
- '**/*.md'
- 'docs/**'
- 'archive/**'
permissions:
contents: read
defaults:
run:
shell: bash -euo pipefail {0}
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
pre-flight:
name: Pre-flight (Lint & Unit)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Verify capability matrix references
run: python3 scripts/ci/verify-capability-matrix.py
- name: Build lint runner
run: docker compose -f compose/docker-compose.yml build lint-runner
- name: Containerized Linting
run: docker compose -f compose/docker-compose.yml --profile lint run --rm lint-runner scripts/ci/lint.sh
- name: Containerized Unit Tests
run: docker compose -f compose/docker-compose.yml --profile test --profile interactive run --rm test-runner scripts/ci/test.sh
- name: Deterministic E2E subset
run: |
docker compose -f compose/docker-compose.yml --profile interactive --profile test run --rm test-runner \
pytest -q /work/tests/e2e/test_dashboard_e2e.py /work/tests/e2e/test_ux_keyboard_accessibility.py
conformance:
name: Conformance (Contracts)
needs: pre-flight
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
path: winebot
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
repository: mark-e-deyoung/winebot-contracts
path: contracts
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install conformance test deps
run: |
pip install -r contracts/tests/conformance/requirements.txt
- name: Build image
run: |
cd winebot
docker compose -f compose/docker-compose.yml build winebot
- name: Start WineBot service
id: start-winebot
run: |
cd winebot
docker compose -f compose/docker-compose.yml --profile headless up -d winebot
# Get container IP for API access (headless profile doesn't expose ports)
CONTAINER_NAME=$(docker compose -f compose/docker-compose.yml ps -q winebot)
CONTAINER_IP=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$CONTAINER_NAME")
echo "container-ip=$CONTAINER_IP" >> "$GITHUB_OUTPUT"
- name: Wait for WineBot to be healthy
run: |
cd winebot
scripts/ci/wait-for-container-health.sh compose/docker-compose.yml headless winebot 60 2
- name: Read API token from container
id: api-token
run: |
cd winebot
TOKEN=$(docker compose -f compose/docker-compose.yml exec -T winebot cat /tmp/winebot_api_token 2>/dev/null || true)
if [ -z "$TOKEN" ]; then
TOKEN=$(docker compose -f compose/docker-compose.yml exec -T winebot cat /winebot-shared/winebot_api_token 2>/dev/null || true)
fi
echo "token=$TOKEN" >> "$GITHUB_OUTPUT"
echo "API token read: ${TOKEN:0:8}..." >> "$GITHUB_STEP_SUMMARY"
- name: Run conformance tests
env:
API_URL: http://${{ steps.start-winebot.outputs.container-ip }}:8000
API_TOKEN: ${{ steps.api-token.outputs.token }}
run: |
python -m pytest contracts/tests/conformance/ \
--api-url "$API_URL" \
--api-token "$API_TOKEN" \
--results-file conformance-results.json \
-v --tb=short
- name: Upload conformance results
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
with:
name: conformance-results
path: conformance-results.json
- name: Stop services
if: always()
run: |
cd winebot
docker compose -f compose/docker-compose.yml --profile headless down --remove-orphans
integration:
name: Integration (Smoke Test)
needs: pre-flight
uses: ./.github/workflows/reusable-build-smoke-gate.yml
with:
image_target: intent-slim
build_intent: slim
image_tag: winebot:slim
smoke_phases: health
run_rel_forbidden: true
generate_trust_pack: true
trust_pack_dir: artifacts/trust-pack
trust_pack_artifact_name: trust-pack-ci