name: Tests on: push: branches: [ main, master, dev, develop, feature/** ] pull_request: branches: [ main, master, dev, develop ] jobs: validate-workers: name: Validate Workers runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run worker validation run: | chmod +x .github/scripts/validate-workers.sh .github/scripts/validate-workers.sh build-workers: name: Build Worker Docker Images runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # Fetch all history for proper diff - name: Check which workers were modified id: check-workers run: | if [ "${{ github.event_name }}" == "pull_request" ]; then # For PRs, check changed files CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD) echo "Changed files:" echo "$CHANGED_FILES" else # For direct pushes, check last commit CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD) fi # Check if docker-compose.yml changed (build all workers) if echo "$CHANGED_FILES" | grep -q "^docker-compose.yml"; then echo "workers_to_build=worker-python worker-secrets worker-rust worker-android worker-ossfuzz" >> $GITHUB_OUTPUT echo "workers_modified=true" >> $GITHUB_OUTPUT echo "✅ docker-compose.yml modified - building all workers" exit 0 fi # Detect which specific workers changed WORKERS_TO_BUILD="" if echo "$CHANGED_FILES" | grep -q "^workers/python/"; then WORKERS_TO_BUILD="$WORKERS_TO_BUILD worker-python" echo "✅ Python worker modified" fi if echo "$CHANGED_FILES" | grep -q "^workers/secrets/"; then WORKERS_TO_BUILD="$WORKERS_TO_BUILD worker-secrets" echo "✅ Secrets worker modified" fi if echo "$CHANGED_FILES" | grep -q "^workers/rust/"; then WORKERS_TO_BUILD="$WORKERS_TO_BUILD worker-rust" echo "✅ Rust worker modified" fi if echo "$CHANGED_FILES" | grep -q "^workers/android/"; then WORKERS_TO_BUILD="$WORKERS_TO_BUILD worker-android" echo "✅ Android worker modified" fi if echo "$CHANGED_FILES" | grep -q "^workers/ossfuzz/"; then WORKERS_TO_BUILD="$WORKERS_TO_BUILD worker-ossfuzz" echo "✅ OSS-Fuzz worker modified" fi if [ -z "$WORKERS_TO_BUILD" ]; then echo "workers_modified=false" >> $GITHUB_OUTPUT echo "⏭️ No worker changes detected - skipping build" else echo "workers_to_build=$WORKERS_TO_BUILD" >> $GITHUB_OUTPUT echo "workers_modified=true" >> $GITHUB_OUTPUT echo "Building workers:$WORKERS_TO_BUILD" fi - name: Set up Docker Buildx if: steps.check-workers.outputs.workers_modified == 'true' uses: docker/setup-buildx-action@v3 - name: Build worker images if: steps.check-workers.outputs.workers_modified == 'true' run: | WORKERS="${{ steps.check-workers.outputs.workers_to_build }}" echo "Building worker Docker images: $WORKERS" docker compose build $WORKERS --no-cache continue-on-error: false lint: name: Lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install dependencies run: | python -m pip install --upgrade pip pip install ruff mypy bandit - name: Run ruff run: ruff check backend/src backend/toolbox backend/tests backend/benchmarks --output-format=github - name: Run mypy (continue on error) run: mypy backend/src backend/toolbox || true continue-on-error: true - name: Run bandit (continue on error) run: bandit --recursive backend/src || true continue-on-error: true unit-tests: name: Unit Tests runs-on: ubuntu-latest strategy: matrix: python-version: ['3.11', '3.12'] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y build-essential - name: Install Python dependencies working-directory: ./backend run: | python -m pip install --upgrade pip pip install -e ".[dev]" pip install pytest pytest-asyncio pytest-cov pytest-xdist - name: Run unit tests working-directory: ./backend run: | pytest tests/unit/ \ -v \ --cov=toolbox/modules \ --cov=src \ --cov-report=xml \ --cov-report=term \ --cov-report=html \ -n auto - name: Upload coverage to Codecov if: matrix.python-version == '3.11' uses: codecov/codecov-action@v4 with: file: ./backend/coverage.xml flags: unittests name: codecov-backend - name: Upload coverage HTML if: matrix.python-version == '3.11' uses: actions/upload-artifact@v4 with: name: coverage-report path: ./backend/htmlcov/ # integration-tests: # name: Integration Tests # runs-on: ubuntu-latest # needs: unit-tests # # services: # postgres: # image: postgres:15 # env: # POSTGRES_USER: postgres # POSTGRES_PASSWORD: postgres # POSTGRES_DB: fuzzforge_test # options: >- # --health-cmd pg_isready # --health-interval 10s # --health-timeout 5s # --health-retries 5 # ports: # - 5432:5432 # # steps: # - uses: actions/checkout@v4 # # - name: Set up Python # uses: actions/setup-python@v5 # with: # python-version: '3.11' # # - name: Set up Docker Buildx # uses: docker/setup-buildx-action@v3 # # - name: Install Python dependencies # working-directory: ./backend # run: | # python -m pip install --upgrade pip # pip install -e ".[dev]" # pip install pytest pytest-asyncio # # - name: Start services (Temporal, MinIO) # run: | # docker-compose -f docker-compose.yml up -d temporal minio # sleep 30 # # - name: Run integration tests # working-directory: ./backend # run: | # pytest tests/integration/ -v --tb=short # env: # DATABASE_URL: postgresql://postgres:postgres@localhost:5432/fuzzforge_test # TEMPORAL_ADDRESS: localhost:7233 # MINIO_ENDPOINT: localhost:9000 # # - name: Shutdown services # if: always() # run: docker-compose down test-summary: name: Test Summary runs-on: ubuntu-latest needs: [validate-workers, lint, unit-tests] if: always() steps: - name: Check test results run: | if [ "${{ needs.validate-workers.result }}" != "success" ]; then echo "Worker validation failed" exit 1 fi if [ "${{ needs.unit-tests.result }}" != "success" ]; then echo "Unit tests failed" exit 1 fi echo "All tests passed!"