name: CI/CD Pipeline on: push: branches: [ main, develop ] pull_request: branches: [ main ] env: REGISTRY: ghcr.io IMAGE_NAME: Dvorinka/trackeep jobs: test: name: Test runs-on: ubuntu-latest services: postgres: image: postgres:15 env: POSTGRES_PASSWORD: postgres POSTGRES_DB: trackeep_test options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 5432:5432 steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v4 with: go-version: '1.25' cache: true cache-dependency-path: backend/go.sum - name: Install backend dependencies run: | cd backend go mod download - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' cache-dependency-path: | frontend/package.json landing/package.json - name: Run backend tests run: | cd backend go test -v -race -coverprofile=coverage.out ./... env: DATABASE_URL: postgres://postgres:postgres@localhost:5432/trackeep_test?sslmode=disable - name: Upload coverage to Codecov uses: codecov/codecov-action@v4 with: file: ./backend/coverage.out flags: backend - name: Install frontend dependencies run: | cd frontend npm ci - name: Run frontend tests run: | cd frontend npm run test - name: Build frontend run: | cd frontend npm run build security-scan: name: Security Scan runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v4 with: go-version: '1.25' cache: true cache-dependency-path: backend/go.sum - name: Run go vet run: | cd backend go vet ./... - name: Run npm audit run: | cd frontend npm audit --audit-level high || echo "Security vulnerabilities found, but continuing build" build-and-push: name: Build and Push Images runs-on: ubuntu-latest needs: [test, security-scan] if: github.ref == 'refs/heads/main' permissions: contents: read packages: write steps: - name: Checkout code uses: actions/checkout@v4 - name: Log in to Container Registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata id: meta uses: docker/metadata-action@v4 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=ref,event=branch type=ref,event=pr type=sha,prefix={{branch}}- type=raw,value=latest,enable={{is_default_branch}} - name: Build and push unified image uses: docker/build-push-action@v4 with: context: . push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} # deploy: # name: Deploy to Production # runs-on: ubuntu-latest # needs: build-and-push # if: github.ref == 'refs/heads/main' # environment: production # steps: # - name: Checkout code # uses: actions/checkout@v4 # - name: Deploy to server # uses: appleboy/ssh-action@v1.0.0 # with: # host: ${{ secrets.PROD_HOST }} # username: ${{ secrets.PROD_USER }} # key: ${{ secrets.PROD_SSH_KEY }} # script: | # cd /opt/trackeep # docker-compose -f docker-compose.prod.yml pull # docker-compose -f docker-compose.prod.yml up -d # docker system prune -f # - name: Run health check # run: | # sleep 30 # curl -f ${{ secrets.PROD_URL }}/health || exit 1