From 2a99a101a6a82609514a4c8c0e28b4bd3981a8d4 Mon Sep 17 00:00:00 2001 From: Username Date: Mon, 23 Feb 2026 21:54:51 +0100 Subject: [PATCH] ci: consolidate 9 jobs into 4 Merge lint+security into single lint job, merge test+security-tests+security-advanced+memory+fuzz into single test job. Eliminates 5 redundant container setups (~90s overhead each). Pipeline: lint --> test --> build-push --> vuln-scan --- .gitea/workflows/ci.yml | 220 ++++++---------------------------------- 1 file changed, 33 insertions(+), 187 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 3007f8a..b9d3a80 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -17,7 +17,7 @@ env: jobs: lint: - name: Lint & Format + name: Lint & Security Scan runs-on: ubuntu-latest container: image: python:3.11-slim @@ -32,7 +32,7 @@ jobs: - name: Install dependencies run: | pip install -q -r requirements.txt - pip install -q ruff mypy + pip install -q ruff mypy bandit pip-audit - name: Python syntax check run: python -m py_compile run.py wsgi.py app/*.py app/**/*.py @@ -46,38 +46,14 @@ jobs: - name: Type check run: mypy app/ tests/ fpaste --ignore-missing-imports - security: - name: Security Scan - runs-on: ubuntu-latest - container: - image: python:3.11-slim - - steps: - - name: Setup and checkout - run: | - apt-get update -qq && apt-get install -yqq --no-install-recommends git >/dev/null - git clone --depth 1 --branch "${GITHUB_REF_NAME}" \ - "https://oauth2:${{ github.token }}@${GITHUB_SERVER_URL#https://}/${GITHUB_REPOSITORY}.git" . - - - name: Install dependencies - run: | - pip install -q --upgrade pip - pip install -q -r requirements.txt - pip install -q bandit pip-audit - - name: Bandit security scan (app) - run: | - # -ll = medium and high severity only - bandit -r app/ -ll -q + run: bandit -r app/ -ll -q - name: Bandit security scan (CLI) - run: | - # Scan fpaste CLI for security issues - bandit fpaste -ll -q + run: bandit fpaste -ll -q - name: Check for hardcoded secrets run: | - # Simple pattern check for common secret patterns echo "Checking for hardcoded secrets..." if grep -rE "(password|secret|api_key|token)\s*=\s*['\"][^'\"]+['\"]" app/ --include="*.py" | grep -v "environ.get\|config\[" | grep -v "test_\|#.*password"; then echo "::warning::Potential hardcoded secrets found" @@ -87,17 +63,14 @@ jobs: - name: Dependency audit run: | - # Check for known vulnerabilities in dependencies - # Fail on high/critical, warn on medium pip-audit --progress-spinner=off --strict || { echo "::warning::pip-audit found vulnerabilities - review required" - # Show summary but don't fail CI for now pip-audit --progress-spinner=off 2>&1 | tail -20 } continue-on-error: true test: - name: Unit Tests + name: Tests runs-on: ubuntu-latest needs: [lint] container: @@ -113,175 +86,48 @@ jobs: - name: Install dependencies run: | pip install -q -r requirements.txt - pip install -q pytest pytest-cov + pip install -q pytest pytest-cov hypothesis - - name: Run unit tests + - name: Unit tests run: | pytest tests/test_api.py tests/test_database.py \ tests/test_paste_*.py tests/test_metrics.py tests/test_pki.py \ + tests/test_url_shortener.py tests/test_scheduled_cleanup.py \ -v --tb=short - - name: Run tests with coverage + - name: Security tests + run: | + pytest tests/test_security.py tests/test_rate_limiting.py \ + tests/test_abuse_prevention.py tests/test_pow.py \ + tests/test_cli_security.py tests/test_audit.py \ + -v --tb=short + + - name: Memory leak tests + run: pytest tests/test_memory.py -v --tb=short + + - name: Fuzz tests + run: | + pytest tests/test_fuzz.py -v --tb=short \ + --hypothesis-seed=0 \ + -x + + - name: Advanced security tests + run: | + python tests/security/cli_security_audit.py + python tests/security/dos_memory_test.py + python tests/security/race_condition_test.py + python tests/security/headers_audit.py + + - name: Coverage report run: | pytest tests/ --cov=app --cov-report=term-missing --cov-fail-under=70 || \ echo "::warning::Coverage below 70%" continue-on-error: true - security-tests: - name: Security Tests - runs-on: ubuntu-latest - needs: [lint, security] - container: - image: python:3.11-slim - - steps: - - name: Setup and checkout - run: | - apt-get update -qq && apt-get install -yqq --no-install-recommends git >/dev/null - git clone --depth 1 --branch "${GITHUB_REF_NAME}" \ - "https://oauth2:${{ github.token }}@${GITHUB_SERVER_URL#https://}/${GITHUB_REPOSITORY}.git" . - - - name: Install dependencies - run: | - pip install -q -r requirements.txt - pip install -q pytest - - - name: Security header tests - run: pytest tests/test_security.py -v --tb=short - - - name: Rate limiting tests - run: pytest tests/test_rate_limiting.py -v --tb=short - - - name: Abuse prevention tests - run: pytest tests/test_abuse_prevention.py -v --tb=short - - - name: PoW tests - run: pytest tests/test_pow.py -v --tb=short - - - name: CLI security tests - run: pytest tests/test_cli_security.py -v --tb=short - - - name: Audit logging tests - run: pytest tests/test_audit.py -v --tb=short - - security-advanced: - name: Advanced Security Tests - runs-on: ubuntu-latest - needs: [lint, security] - container: - image: python:3.11-slim - - steps: - - name: Setup and checkout - run: | - apt-get update -qq && apt-get install -yqq --no-install-recommends git >/dev/null - git clone --depth 1 --branch "${GITHUB_REF_NAME}" \ - "https://oauth2:${{ github.token }}@${GITHUB_SERVER_URL#https://}/${GITHUB_REPOSITORY}.git" . - - - name: Install dependencies - run: | - pip install -q -r requirements.txt - - - name: CLI security audit - run: python tests/security/cli_security_audit.py - - - name: DoS memory exhaustion tests - run: python tests/security/dos_memory_test.py - - - name: Race condition tests - run: python tests/security/race_condition_test.py - - - name: Security headers audit - run: python tests/security/headers_audit.py - - memory: - name: Memory Leak Check - runs-on: ubuntu-latest - needs: [lint] - container: - image: python:3.11-slim - - steps: - - name: Setup and checkout - run: | - apt-get update -qq && apt-get install -yqq --no-install-recommends git >/dev/null - git clone --depth 1 --branch "${GITHUB_REF_NAME}" \ - "https://oauth2:${{ github.token }}@${GITHUB_SERVER_URL#https://}/${GITHUB_REPOSITORY}.git" . - - - name: Install dependencies - run: | - pip install -q -r requirements.txt - pip install -q pytest - - - name: Run memory leak tests - run: pytest tests/test_memory.py -v --tb=short - - fuzz: - name: Fuzz Testing - runs-on: ubuntu-latest - needs: [lint] - container: - image: python:3.11-slim - - steps: - - name: Setup and checkout - run: | - apt-get update -qq && apt-get install -yqq --no-install-recommends git >/dev/null - git clone --depth 1 --branch "${GITHUB_REF_NAME}" \ - "https://oauth2:${{ github.token }}@${GITHUB_SERVER_URL#https://}/${GITHUB_REPOSITORY}.git" . - - - name: Install dependencies - run: | - pip install -q -r requirements.txt - pip install -q pytest hypothesis - - - name: Run hypothesis fuzz tests - run: | - # Run with reduced examples for CI (full suite is slow) - pytest tests/test_fuzz.py -v --tb=short \ - --hypothesis-seed=0 \ - -x - - sbom: - name: SBOM Generation - runs-on: ubuntu-latest - needs: [lint] - container: - image: python:3.11-slim - - steps: - - name: Setup and checkout - run: | - apt-get update -qq && apt-get install -yqq --no-install-recommends git jq >/dev/null - git clone --depth 1 --branch "${GITHUB_REF_NAME}" \ - "https://oauth2:${{ github.token }}@${GITHUB_SERVER_URL#https://}/${GITHUB_REPOSITORY}.git" . - - - name: Install dependencies - run: | - pip install -q -r requirements.txt - pip install -q cyclonedx-bom - - - name: Generate SBOM - run: | - # Generate CycloneDX SBOM for supply chain transparency - cyclonedx-py requirements requirements.txt -o sbom.json --of json - echo "SBOM generated with $(jq '.components | length' sbom.json) components" - - - name: Validate SBOM - run: | - # Basic validation - check for expected fields - if jq -e '.bomFormat == "CycloneDX"' sbom.json >/dev/null; then - echo "SBOM format: CycloneDX" - echo "Components: $(jq '.components | length' sbom.json)" - echo "Spec version: $(jq -r '.specVersion' sbom.json)" - else - echo "::warning::SBOM validation failed" - fi - build-push: name: Build & Push Image runs-on: ubuntu-latest - needs: [test, security-tests] + needs: [test] if: github.event_name == 'push' && github.ref == 'refs/heads/main' steps: