# ObsiGate CI/CD Pipeline # Runs on every push and pull request to main name: CI on: push: branches: [main] pull_request: branches: [main] jobs: # ── Lint ────────────────────────────────────────────────────────── lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install dependencies run: | pip install ruff mypy pip install -r backend/requirements.txt - name: Ruff (linter) run: ruff check backend/ - name: Mypy (type checker) run: mypy backend/ --ignore-missing-imports || echo "mypy found type errors (advisory — 28 pre-existing issues)" - name: Frontend validation run: node tests/frontend/validate-imports.mjs - name: Frontend unit tests run: node tests/frontend/unit.test.mjs # ── Tests ───────────────────────────────────────────────────────── test: needs: lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install dependencies run: | pip install pytest pytest-cov pytest-asyncio httpx pip install -r backend/requirements.txt - name: Run tests run: pytest tests/ --cov=backend --cov-report=xml --cov-report=term -q - name: Upload coverage artifact uses: actions/upload-artifact@v3 with: name: coverage-report path: coverage.xml retention-days: 30 # ── Security scan ───────────────────────────────────────────────── security: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install dependencies run: | pip install bandit pip-audit pip install -r backend/requirements.txt - name: Bandit (SAST) run: bandit -r backend/ --skip B101,B110,B310 || echo "bandit found issues (non-blocking)" - name: Pip-audit (dependency vulnerabilities) run: pip-audit || echo "pip-audit found vulnerabilities (non-blocking)" # ── Docker build ────────────────────────────────────────────────── build: needs: test runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Build Docker image run: docker build -t obsigate:ci . - name: Verify image run: docker images obsigate:ci # ── E2E Tests (Playwright) ───────────────────────────────────────── e2e: needs: build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup Node uses: actions/setup-node@v4 with: node-version: "20" - name: Install Playwright run: | npm ci npx playwright install --with-deps chromium - name: Start ObsiGate run: | docker run -d --name obsigate-e2e -p 2020:8080 \ -v $(pwd)/test_vault:/vaults/TestVault \ -v $(pwd)/test_dir:/vaults/TestDir \ -e VAULT_1_NAME=TestVault \ -e VAULT_1_PATH=/vaults/TestVault \ -e DIR_1_NAME=TestDir \ - name: Start ObsiGate run: | docker rm -f obsigate-e2e 2>/dev/null || true docker run -d --name obsigate-e2e -p 2029:8080 -v $(pwd)/test_vault:/vaults/TestVault -v $(pwd)/test_dir:/vaults/TestDir -e VAULT_1_NAME=TestVault -e VAULT_1_PATH=/vaults/TestVault -e DIR_1_NAME=TestDir -e DIR_1_PATH=/vaults/TestDir -e OBSIGATE_AUTH_ENABLED=false obsigate:ci # Wait for health check for i in $(seq 1 30); do curl -s http://localhost:2029/api/health && break sleep 1 done - name: Run E2E tests run: npx playwright test --project=chromium-desktop --reporter=list - name: Upload test results if: always() uses: actions/upload-artifact@v3 with: name: playwright-report path: playwright-report/ retention-days: 7 - name: Cleanup if: always() run: docker rm -f obsigate-e2e