name: PR tests on: pull_request: types: [opened, synchronize, edited, reopened] jobs: build-and-smoke: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Install uv uses: astral-sh/setup-uv@v5 - name: Set up Python run: uv python install with: python-version-file: "pyproject.toml" - name: Install the project dependencies run: | uv sync --all-groups uv add pip uv export --format requirements.txt -o requirements.txt # uv run python -m pip install --upgrade pip # uv run python -m pip install -r requirements.txt - name: Build image run: | docker build -t semapform-api:test-pr . - name: Start container (background) run: | # do NOT bind the container port to the host to avoid port conflicts on the runner docker run -d --name semapform-test semapform-api:test-pr sleep infinity - name: Start server in container and smoke test HTTP (in-container) run: | # start the server inside the container docker exec -d semapform-test uv run uvicorn api_service:app --host 0.0.0.0 --port 8001 # send a POST request to /api/validate-signature with signature="ST 250 U42 (15)" docker exec semapform-test python - << 'PY' import time, urllib.request, sys url = 'http://127.0.0.1:8001/api/validate-signature?signature=ST%20250%20U42%20%2815%29' for _ in range(20): try: req = urllib.request.Request(url, method='POST') r = urllib.request.urlopen(req, timeout=3) print('status', r.status) print(r.read().decode()) if 200 <= r.status < 300: sys.exit(0) except Exception: time.sleep(1) print('failed') sys.exit(1) PY - name: Start server in container and smoke test HTTP (in-container) run: | # start the server inside the container docker exec -d semapform-test uv run uvicorn api_service:app --host 0.0.0.0 --port 8001 # perform an in-container HTTP check using Python stdlib (avoids requiring curl) docker exec semapform-test python - << 'PY' import time,urllib.request,sys for _ in range(20): try: urllib.request.urlopen('http://127.0.0.1:8001/health', timeout=2) print('ok') sys.exit(0) except Exception: time.sleep(1) print('failed') sys.exit(1) PY - name: Cleanup container if: always() run: | docker rm -f semapform-test || true