name: CI/CD Pipeline on: push: branches: [ main, develop ] pull_request: branches: [ main ] # Concurrency control to prevent multiple runs of the same workflow concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true # Workflow permissions permissions: contents: read security-events: write actions: read packages: write env: GO_VERSION: '1.25.0' ZIG_VERSION: '0.15.2' jobs: test: name: Test runs-on: ubuntu-latest timeout-minutes: 30 services: redis: image: redis:7 ports: - 6379:6379 options: >- --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 steps: - name: Checkout code uses: actions/checkout@v5 - name: Set up Go uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} - name: Cache Go modules uses: actions/cache@v4 with: path: | ~/.cache/go-build ~/go/pkg/mod key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum', '**/go.mod') }} restore-keys: | ${{ runner.os }}-go- - name: Set up Zig uses: goto-bus-stop/setup-zig@v2 with: version: ${{ env.ZIG_VERSION }} - name: Cache Zig build uses: actions/cache@v4 with: path: | ~/.cache/zig cli/zig-cache cli/zig-out key: ${{ runner.os }}-zig-${{ hashFiles('cli/**') }} restore-keys: | ${{ runner.os }}-zig- - name: Install dependencies run: | go mod download sudo apt-get update sudo apt-get install -y podman redis-tools - name: Verify dependencies run: go mod verify - name: Run tests run: make test env: REDIS_URL: redis://localhost:6379 - name: Test internal/queue package run: go test -v -race -coverprofile=queue-coverage.out ./internal/queue/... env: REDIS_URL: redis://localhost:6379 - name: Run comprehensive tests run: make test-all env: REDIS_URL: redis://localhost:6379 - name: Run linters run: make lint - name: Generate coverage report run: make coverage - name: Upload coverage to Codecov uses: codecov/codecov-action@v4 with: file: ./coverage.out flags: unittests name: codecov-umbrella build: name: Build runs-on: ubuntu-latest needs: test timeout-minutes: 15 steps: - name: Checkout code uses: actions/checkout@v5 - name: Set up Go uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} - name: Set up Zig uses: goto-bus-stop/setup-zig@v2 with: version: ${{ env.ZIG_VERSION }} - name: Cache Go modules uses: actions/cache@v4 with: path: | ~/.cache/go-build ~/go/pkg/mod key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum', '**/go.mod') }} restore-keys: | ${{ runner.os }}-go- - name: Install build dependencies run: | sudo apt-get update sudo apt-get install -y podman - name: Build binaries run: | make build make cli-build # Build Zig CLI (dev and prod) cd cli && zig build dev && zig build prod && cd .. # Note: prod builds use rsync_placeholder wrapper # For true embedded rsync, add static binary to cli/src/assets/rsync_release.bin - name: Test binaries run: | ./bin/user_manager --help ./bin/worker --help ./bin/tui --help ./bin/data_manager --help # Test Zig CLI ./cli/zig-out/prod/ml --help # Verify binary size (should be small with placeholder rsync) ls -lh ./cli/zig-out/prod/ml - name: Upload build artifacts uses: actions/upload-artifact@v4 with: name: fetch_ml_binaries path: | bin/ cli/zig-out/ dist/ retention-days: 30 test-scripts: name: Test Scripts runs-on: ubuntu-latest needs: test timeout-minutes: 15 steps: - name: Checkout code uses: actions/checkout@v5 - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y podman redis-tools bats - name: Test scripts run: | # Test script functionality chmod +x scripts/*.sh # Test quick start script (dry run) ./scripts/quick_start.sh --help || true # Test security monitor ./scripts/security-monitor.sh help # Test auto setup ./scripts/auto_setup.sh help # Test deployment scripts ./scripts/deploy-secure.sh --help || true ./scripts/deploy-production.sh --help || true security-scan: name: Security Scan runs-on: ubuntu-latest timeout-minutes: 20 steps: - name: Checkout code uses: actions/checkout@v5 - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master with: scan-type: 'fs' scan-ref: '.' format: 'sarif' output: 'trivy-results.sarif' - name: Upload Trivy scan results to GitHub Security tab uses: github/codeql-action/upload-sarif@v2 if: always() with: sarif_file: 'trivy-results.sarif' - name: Gosec Security Scanner run: | go install github.com/securecodewarrior/gosec/v2/cmd/gosec@latest gosec ./... docker-build: name: Docker Build runs-on: ubuntu-latest needs: [test, build, test-scripts] if: github.event_name == 'push' && github.ref == 'refs/heads/main' timeout-minutes: 30 steps: - name: Checkout code uses: actions/checkout@v5 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push Docker image uses: docker/build-push-action@v6 with: context: . platforms: linux/amd64,linux/arm64 push: true tags: | ghcr.io/${{ github.repository }}:latest ghcr.io/${{ github.repository }}:${{ github.sha }} cache-from: type=gha cache-to: type=gha,mode=max