name: ENGIN CI on: push: branches: - main - prod-hardening pull_request: branches: - main jobs: production-check: name: Build, test and smoke runs-on: engin-ci timeout-minutes: 20 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Clean previous CI resources run: | docker rm -f engin-ci-app 2>/dev/null || true docker image rm -f engin-console:ci 2>/dev/null || true - name: Build production image run: docker build --tag engin-console:ci . - name: Run Ruff run: | docker run --rm \ --entrypoint sh \ engin-console:ci \ -c "python -m pip install --quiet \ --disable-pip-version-check \ --root-user-action=ignore \ ruff==0.16.4 && ruff check --no-cache \ app.py engin tests final_pipeline.py ml_polish_benchmark.py" - name: Check installed dependencies run: | docker run --rm \ --entrypoint python \ engin-console:ci \ -m pip check - name: Run test suite run: | docker run --rm \ --entrypoint python \ engin-console:ci \ -m unittest discover -v - name: Validate Python syntax run: | docker run --rm \ --entrypoint python \ engin-console:ci \ -m compileall -q app.py engin tests final_pipeline.py - name: Start application run: | docker run -d \ --name engin-ci-app \ engin-console:ci - name: Verify Streamlit health run: | set -eu attempt=1 while [ "$attempt" -le 30 ]; do if docker exec engin-ci-app python -c \ "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8501/_stcore/health', timeout=3).read()"; then exit 0 fi sleep 2 attempt=$((attempt + 1)) done docker logs engin-ci-app exit 1 - name: Cleanup if: always() run: | docker logs engin-ci-app 2>/dev/null || true docker rm -f engin-ci-app 2>/dev/null || true docker image rm -f engin-console:ci 2>/dev/null || true