build(deps): bump actions/deploy-pages from 4 to 5 #850
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI - Tests + Coverage | |
| on: | |
| push: | |
| branches: ["main"] | |
| pull_request: | |
| branches: ["main"] | |
| concurrency: | |
| group: ci-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| # βββ Shared environment ββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| env: | |
| MEOW_TEST_MODE: "1" | |
| MEOW_PRODUCTION_MODE: "0" # Required alongside MEOW_TEST_MODE to allow export_key() in tests | |
| MEOW_CRYPTO_BACKEND: "rust" | |
| RUST_BACKEND_REQUIRED: "1" # Phase 5: Fail closed if Rust backend unavailable | |
| PIP_DISABLE_PIP_VERSION_CHECK: "1" | |
| PYTHONDONTWRITEBYTECODE: "1" | |
| jobs: | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # PREFLIGHT: Fast sanity checks β lock files, formatting, lint | |
| # Catches the most common failures in <60s before burning CI minutes | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| preflight: | |
| name: "Preflight: Lint + Lock Check" | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.3.0 | |
| with: | |
| python-version: "3.12" | |
| cache: "pip" | |
| # -- Lock file verification (catches hash mismatches early) -- | |
| - name: Verify lock files are installable | |
| run: | | |
| pip install --require-hashes -r requirements-pip.lock | |
| pip install --dry-run --require-hashes -r requirements.lock 2>&1 | tail -5 | |
| pip install --dry-run --require-hashes -r requirements-dev.lock 2>&1 | tail -5 | |
| pip install --dry-run --require-hashes -r requirements-ci.lock 2>&1 | tail -5 | |
| echo "β All lock files verified" | |
| # -- Install lint tools only -- | |
| - name: Install lint tools | |
| run: | | |
| pip install --require-hashes -r requirements-ci.lock | |
| # -- Fast checks that don't need Rust or system deps -- | |
| - name: black format check | |
| run: black --check --diff meow_decoder/ | |
| - name: flake8 lint | |
| run: flake8 meow_decoder/ | |
| - name: mypy type check | |
| run: mypy meow_decoder/ --ignore-missing-imports --no-error-summary | |
| - name: bandit security lint | |
| run: bandit -r meow_decoder/ -ll -q || true | |
| # -- Crypto migration gate (fast grep check) -- | |
| - name: Check core crypto files for forbidden imports | |
| run: | | |
| echo "π Checking core crypto files for forbidden Python crypto imports..." | |
| # Core files that MUST be migrated (fail if they import cryptography/hmac/hashlib) | |
| CORE_FILES="meow_decoder/crypto.py meow_decoder/crypto_enhanced.py meow_decoder/ratchet.py meow_decoder/pq_hybrid.py meow_decoder/forward_secrecy.py" | |
| FORBIDDEN_PATTERN="^[[:space:]]*(from|import)[[:space:]]+(cryptography|hmac|hashlib)" | |
| VIOLATIONS="" | |
| for f in $CORE_FILES; do | |
| if [ -f "$f" ]; then | |
| matches=$(grep -n -E "$FORBIDDEN_PATTERN" "$f" 2>/dev/null || true) | |
| if [ -n "$matches" ]; then | |
| VIOLATIONS="$VIOLATIONS\n$f:\n$matches" | |
| fi | |
| fi | |
| done | |
| if [ -n "$VIOLATIONS" ]; then | |
| echo "β Forbidden Python crypto imports found in core files:" | |
| echo -e "$VIOLATIONS" | |
| echo "" | |
| echo "Core crypto files must use the Rust backend (meow_crypto_rs)." | |
| exit 1 | |
| fi | |
| echo "β Core crypto files are clean" | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # GATE 1a/1b: Tests split into two parallel batches to avoid timeouts. | |
| # Batch 1 (aβm): adversarial β metadata_obfuscation | |
| # Batch 2 (mβz): mobile_bridge β zero_key_bytes + security/ | |
| # Both must pass. Coverage threshold enforced in batch-1 only. | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| test-batch-1: | |
| name: "Gate 1a: Tests Batch 1 (a-m)" | |
| needs: preflight | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.3.0 | |
| with: | |
| python-version: "3.12" | |
| cache: "pip" | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| libzbar0 libgl1 libglib2.0-0 \ | |
| build-essential pkg-config libssl-dev \ | |
| libpcsclite-dev libudev-dev | |
| - uses: dtolnay/rust-toolchain@d0592fe69e35bc8f12e3dbaf9ad2694d976cb8e3 # stable | |
| with: | |
| toolchain: stable | |
| - name: Install Python dependencies | |
| run: | | |
| pip install --require-hashes -r requirements-pip.lock | |
| pip install --require-hashes -r requirements.lock | |
| pip install --require-hashes -r requirements-dev.lock | |
| pip install --require-hashes -r requirements-ci.lock | |
| - name: Build and install Rust crypto backend | |
| # Local wheel install - can't hash-pin freshly-built artifacts | |
| run: | | |
| cd rust_crypto | |
| maturin build --release --out dist | |
| python -m pip install --force-reinstall --no-deps dist/*.whl | |
| cd .. | |
| - name: Verify Rust backend | |
| run: python -c "import meow_crypto_rs; print('Rust backend OK')" | |
| - name: Rust crypto_core tests | |
| run: | | |
| echo "π¦ Running Rust crypto_core tests..." | |
| cd crypto_core && cargo test --features "pure-crypto,pq-crypto" --release | |
| echo "β Rust crypto_core tests passed" | |
| - name: Run test suite batch 1 (a-m, no slow markers) | |
| run: | | |
| pytest -m "not slow" \ | |
| --override-ini="addopts=" \ | |
| --cov=meow_decoder \ | |
| --cov-config=.coveragerc \ | |
| --cov-report=term-missing \ | |
| --cov-fail-under=80 \ | |
| -q --no-header \ | |
| tests/test_adversarial.py \ | |
| tests/test_asymmetric_rekey.py \ | |
| tests/test_audit_fixes.py \ | |
| tests/test_bridge_protocol.py \ | |
| tests/test_cat_errors.py \ | |
| tests/test_cat_js_runner.py \ | |
| tests/test_cat_utils.py \ | |
| tests/test_config.py \ | |
| tests/test_constant_time.py \ | |
| tests/test_crypto.py \ | |
| tests/test_crypto_DEBUG.py \ | |
| tests/test_crypto_backend.py \ | |
| tests/test_deadmans_switch_cli.py \ | |
| tests/test_decode_gif.py \ | |
| tests/test_duress_mode.py \ | |
| tests/test_e2e_crypto_fountain.py \ | |
| tests/test_e2e_gif_ratchet.py \ | |
| tests/test_e2e_ratchet_pipeline.py \ | |
| tests/test_encode.py \ | |
| tests/test_encode_DEBUG.py \ | |
| tests/test_fail_closed_enforcement.py \ | |
| tests/test_formal_fuzz_gaps.py \ | |
| tests/test_fountain.py \ | |
| tests/test_fountain_montecarlo.py \ | |
| tests/test_frame_mac.py \ | |
| tests/test_fuzz_coverage_integration.py \ | |
| tests/test_fuzz_targets.py \ | |
| tests/test_gif_handler.py \ | |
| tests/test_golden_vectors.py \ | |
| tests/test_hardware_integration.py \ | |
| tests/test_high_security.py \ | |
| tests/test_invariants.py \ | |
| tests/test_logo_eyes.py \ | |
| tests/test_metadata_obfuscation.py | |
| test-batch-2: | |
| name: "Gate 1b: Tests Batch 2 (m-z)" | |
| needs: preflight | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.3.0 | |
| with: | |
| python-version: "3.12" | |
| cache: "pip" | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| libzbar0 libgl1 libglib2.0-0 \ | |
| build-essential pkg-config libssl-dev \ | |
| libpcsclite-dev libudev-dev | |
| - uses: dtolnay/rust-toolchain@d0592fe69e35bc8f12e3dbaf9ad2694d976cb8e3 # stable | |
| with: | |
| toolchain: stable | |
| - name: Install Python dependencies | |
| run: | | |
| pip install --require-hashes -r requirements-pip.lock | |
| pip install --require-hashes -r requirements.lock | |
| pip install --require-hashes -r requirements-dev.lock | |
| pip install --require-hashes -r requirements-ci.lock | |
| - name: Build and install Rust crypto backend | |
| # Local wheel install - can't hash-pin freshly-built artifacts | |
| run: | | |
| cd rust_crypto | |
| maturin build --release --out dist | |
| python -m pip install --force-reinstall --no-deps dist/*.whl | |
| cd .. | |
| - name: Verify Rust backend | |
| run: python -c "import meow_crypto_rs; print('Rust backend OK')" | |
| - name: Run test suite batch 2 (m-z, no slow markers) | |
| run: | | |
| pytest -m "not slow" \ | |
| --override-ini="addopts=" \ | |
| --cov=meow_decoder \ | |
| --cov-config=.coveragerc \ | |
| --cov-report=term-missing \ | |
| -q --no-header \ | |
| tests/test_mobile_bridge.py \ | |
| tests/test_no_experimental_imports_in_production.py \ | |
| tests/test_no_overclaims.py \ | |
| tests/test_no_python_key_bytes.py \ | |
| tests/test_phase5_modules.py \ | |
| tests/test_pq_crypto_real.py \ | |
| tests/test_pq_hybrid.py \ | |
| tests/test_pqxdh_upgrade.py \ | |
| tests/test_production_boundary.py \ | |
| tests/test_production_import_boundary.py \ | |
| tests/test_profile_required_and_checked.py \ | |
| tests/test_progress.py \ | |
| tests/test_property_based.py \ | |
| tests/test_property_ratchet_pq.py \ | |
| tests/test_property_shamir_dualstream.py \ | |
| tests/test_qr_code.py \ | |
| tests/test_ratchet.py \ | |
| tests/test_rust_crypto_backend.py \ | |
| tests/test_security.py \ | |
| tests/test_security_hardening.py \ | |
| tests/test_security_warnings.py \ | |
| tests/test_setup.py \ | |
| tests/test_sidechannel.py \ | |
| tests/test_signal_invariants.py \ | |
| tests/test_stego_advanced.py \ | |
| tests/test_stego_adversarial.py \ | |
| tests/test_stego_fuzz.py \ | |
| tests/test_stego_multilayer.py \ | |
| tests/test_stego_phase0.py \ | |
| tests/test_stego_phase1.py \ | |
| tests/test_tamper_report.py \ | |
| tests/test_timelock_duress.py \ | |
| tests/test_x25519_forward_secrecy.py \ | |
| tests/test_zero_key_bytes.py \ | |
| tests/security/ | |
| # Python coverage is local-only (terminal report above). | |
| # Codecov monitors Rust coverage via rust-test-coverage.yml. | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # GATE 2: Cat Mode Golden Video Test (only runs after preflight passes) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| cat-mode-golden-test: | |
| name: "Gate 2: Cat Mode Golden Video" | |
| needs: preflight | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| continue-on-error: true # Allow CI to proceed even if this gate fails | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.3.0 | |
| with: | |
| python-version: "3.12" | |
| cache: "pip" | |
| # Check for golden videos FIRST so we don't waste time installing | |
| # chromium + playwright when videos haven't been generated yet. | |
| - name: Check if golden videos exist | |
| id: check_golden | |
| run: | | |
| if [ -f "tests/golden/cat_mode_golden_empty_hash_100ms.webm" ]; then | |
| echo "exists=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "exists=false" >> $GITHUB_OUTPUT | |
| echo "β οΈ Golden videos not found β skipping Cat Mode Video tests." | |
| echo " Run 'npm run generate-golden-videos' to create test assets." | |
| fi | |
| - name: Setup Chrome | |
| if: steps.check_golden.outputs.exists == 'true' | |
| uses: browser-actions/setup-chrome@latest # v1.7.1+ | |
| with: | |
| chrome-version: stable | |
| - name: Install Python dependencies for test runner | |
| if: steps.check_golden.outputs.exists == 'true' | |
| run: | | |
| pip install selenium webdriver-manager | |
| # Set Chrome binary for webdriver-manager | |
| echo "CHROME_BIN=$(which google-chrome || which chrome)" >> $GITHUB_ENV | |
| - name: Verify golden video checksums | |
| if: steps.check_golden.outputs.exists == 'true' | |
| run: | | |
| cd tests/golden | |
| echo "β Golden videos present" | |
| - name: Run Cat Mode Golden Video Test | |
| if: steps.check_golden.outputs.exists == 'true' | |
| run: | | |
| cd tests | |
| python3 run_golden_test.py | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # GATE 3: Cat Mode Error Injection Testing (validates error handling) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| cat-mode-error-test: | |
| name: "Gate 3: Cat Mode Error Tests" | |
| needs: cat-mode-golden-test | |
| if: always() # Run even if Gate 2 fails | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| continue-on-error: true # Allow CI to proceed even if this gate fails | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v4.2.0 | |
| with: | |
| node-version: "20" | |
| cache: "npm" | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.3.0 | |
| with: | |
| python-version: "3.12" | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y ffmpeg | |
| sudo apt-get install -y chromium-browser || true | |
| - name: Install npm dependencies | |
| run: npm install | |
| - name: Check if error videos exist | |
| id: check_errors | |
| run: | | |
| if [ -d "tests/golden/errors" ] && [ -f "tests/golden/errors/manifest.json" ]; then | |
| echo "exists=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "exists=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Generate error videos (if missing) | |
| if: steps.check_errors.outputs.exists == 'false' | |
| run: | | |
| # Generate golden videos first (if they don't exist) | |
| if [ ! -f "tests/golden/cat_mode_golden_empty_hash_100ms.webm" ]; then | |
| echo "πΉ Generating golden videos first..." | |
| npm run generate-golden-videos | |
| fi | |
| echo "π§ͺ Generating error test videos..." | |
| npm run generate-error-tests | |
| - name: Verify error video checksums | |
| if: steps.check_errors.outputs.exists == 'true' | |
| run: | | |
| cd tests/golden/errors | |
| # Extract checksums from README and verify | |
| # (For now, just check files exist) | |
| if ls *.webm 1> /dev/null 2>&1; then | |
| echo "β Error videos found" | |
| ls -lh *.webm | |
| else | |
| echo "β οΈ No error videos found - regenerating" | |
| cd ../../.. | |
| npm run generate-error-tests | |
| fi | |
| - name: Run Error Injection Tests | |
| run: | | |
| cd tests | |
| python3 run_error_tests.py | |
| - name: Upload error diagnostics | |
| if: always() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.0 | |
| with: | |
| name: error-test-results | |
| path: tests/golden/errors/test_results.json | |
| retention-days: 30 | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # GATE 4: Cross-Browser Testing (validates multi-browser compatibility) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| cat-mode-cross-browser: | |
| name: "Gate 4: Cross-Browser Tests" | |
| needs: cat-mode-golden-test | |
| if: always() # Run even if Gate 2 fails | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| continue-on-error: true # Allow CI to proceed even if this gate fails | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v4.2.0 | |
| with: | |
| node-version: "20" | |
| cache: "npm" | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.3.0 | |
| with: | |
| python-version: "3.12" | |
| - name: Install npm dependencies | |
| run: npm install | |
| - name: Install Playwright browsers | |
| run: npx playwright install --with-deps chromium firefox webkit | |
| - name: Check if golden videos exist | |
| id: check_golden | |
| run: | | |
| if [ -f "tests/golden/cat_mode_golden_empty_hash_100ms.webm" ]; then | |
| echo "exists=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "exists=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Generate golden videos (if missing) | |
| if: steps.check_golden.outputs.exists == 'false' | |
| run: | | |
| sudo apt-get install -y ffmpeg | |
| npm run generate-golden-videos | |
| - name: Run cross-browser tests | |
| run: npm run test:browsers | |
| - name: Upload test artifacts | |
| if: always() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.0 | |
| with: | |
| name: playwright-report | |
| path: tests/playwright-report/ | |
| retention-days: 30 | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.0 | |
| with: | |
| name: playwright-results | |
| path: tests/playwright-results.json | |
| retention-days: 30 | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # GATE 5: Security coverage (only runs after preflight passes) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| security-coverage: | |
| name: "Gate 5: Security Coverage" | |
| needs: preflight | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.3.0 | |
| with: | |
| python-version: "3.12" | |
| cache: "pip" | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| libzbar0 libgl1 libglib2.0-0 \ | |
| build-essential pkg-config libssl-dev \ | |
| libpcsclite-dev libudev-dev | |
| - uses: dtolnay/rust-toolchain@d0592fe69e35bc8f12e3dbaf9ad2694d976cb8e3 # stable | |
| with: | |
| toolchain: stable | |
| - name: Install Python + Rust backend | |
| # Local wheel install - can't hash-pin freshly-built artifacts | |
| run: | | |
| pip install --require-hashes -r requirements-pip.lock | |
| pip install --require-hashes -r requirements.lock | |
| pip install --require-hashes -r requirements-dev.lock | |
| pip install --require-hashes -r requirements-ci.lock | |
| cd rust_crypto && maturin build --release --out dist && pip install --force-reinstall --no-deps dist/*.whl && cd .. | |
| - name: Security coverage gate | |
| run: | | |
| pytest tests/ -m "security or crypto or adversarial" \ | |
| --override-ini="addopts=" \ | |
| --cov --cov-config=.coveragerc-security \ | |
| --cov-fail-under=85 \ | |
| --cov-report=term-missing \ | |
| -q --no-header | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # GATE 6: Slow Tests (Monte Carlo stress tests for fountain codes) | |
| # Validates statistical guarantees of LT codes - runs 1000s of trials | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| slow-tests: | |
| name: "Gate 6: Slow Tests (Monte Carlo)" | |
| needs: preflight | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.3.0 | |
| with: | |
| python-version: "3.12" | |
| cache: "pip" | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| libzbar0 libgl1 libglib2.0-0 \ | |
| build-essential pkg-config libssl-dev \ | |
| libpcsclite-dev libudev-dev | |
| - uses: dtolnay/rust-toolchain@d0592fe69e35bc8f12e3dbaf9ad2694d976cb8e3 # stable | |
| with: | |
| toolchain: stable | |
| - name: Install Python dependencies | |
| run: | | |
| pip install --require-hashes -r requirements-pip.lock | |
| pip install --require-hashes -r requirements.lock | |
| pip install --require-hashes -r requirements-dev.lock | |
| pip install --require-hashes -r requirements-ci.lock | |
| - name: Build and install Rust crypto backend | |
| run: | | |
| cd rust_crypto | |
| maturin build --release --out dist | |
| python -m pip install --force-reinstall --no-deps dist/*.whl | |
| cd .. | |
| - name: Run slow tests (Monte Carlo fountain stress) | |
| run: | | |
| echo "π² Running Monte Carlo fountain code stress tests..." | |
| echo " - 1000 trials at 30% packet loss (β₯99.5% success)" | |
| echo " - 1000 trials at 50% packet loss (β₯85-99% success)" | |
| echo " - 500 trials at 70% loss (graceful degradation)" | |
| pytest -m slow tests/test_fountain_montecarlo.py \ | |
| --override-ini="addopts=" \ | |
| -v --tb=short | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Required status check β preflight + all gates must pass | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| all-gates: | |
| name: "All CI Gates" | |
| needs: | |
| [ | |
| preflight, | |
| test-batch-1, | |
| test-batch-2, | |
| cat-mode-golden-test, | |
| cat-mode-error-test, | |
| cat-mode-cross-browser, | |
| security-coverage, | |
| slow-tests, | |
| ] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| if: always() | |
| steps: | |
| - name: Check gate results | |
| run: | | |
| FAILED=0 | |
| if [[ "${{ needs.preflight.result }}" != "success" ]]; then | |
| echo "β Preflight (Lint + Lock Check) failed" | |
| FAILED=1 | |
| fi | |
| if [[ "${{ needs.test-batch-1.result }}" != "success" ]]; then | |
| echo "β Gate 1a (Tests Batch 1) failed" | |
| FAILED=1 | |
| fi | |
| if [[ "${{ needs.test-batch-2.result }}" != "success" ]]; then | |
| echo "β Gate 1b (Tests Batch 2) failed" | |
| FAILED=1 | |
| fi | |
| # Gates 2-4 are Cat Mode video tests - treat as warnings (continue-on-error) | |
| if [[ "${{ needs.cat-mode-golden-test.result }}" != "success" ]]; then | |
| echo "β οΈ Gate 2 (Cat Mode Golden Video) had issues (non-blocking)" | |
| fi | |
| if [[ "${{ needs.cat-mode-error-test.result }}" != "success" ]]; then | |
| echo "β οΈ Gate 3 (Cat Mode Error Tests) had issues (non-blocking)" | |
| fi | |
| if [[ "${{ needs.cat-mode-cross-browser.result }}" != "success" ]]; then | |
| echo "β οΈ Gate 4 (Cross-Browser Tests) had issues (non-blocking)" | |
| fi | |
| if [[ "${{ needs.security-coverage.result }}" != "success" ]]; then | |
| echo "β Gate 5 (Security Coverage) failed" | |
| FAILED=1 | |
| fi | |
| if [[ "${{ needs.slow-tests.result }}" != "success" ]]; then | |
| echo "β Gate 6 (Slow Tests - Monte Carlo) failed" | |
| FAILED=1 | |
| fi | |
| if [[ "$FAILED" == "1" ]]; then | |
| echo "β Some critical CI gates failed" | |
| exit 1 | |
| fi | |
| echo "β All critical CI gates passed" |