name: CI on: push: branches: [main, develop] pull_request: branches: [main, develop] env: TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} TURBO_TEAM: ${{ secrets.TURBO_TEAM }} jobs: lint-and-typecheck: name: Lint and Type Check runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 with: submodules: recursive - name: Setup pnpm uses: pnpm/action-setup@v2 with: version: 8 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '18' cache: 'pnpm' - name: Install dependencies run: pnpm install --frozen-lockfile - name: Run security audit run: pnpm audit --audit-level moderate || true - name: Lint run: pnpm lint - name: Type check run: pnpm type-check test: name: Test runs-on: ubuntu-latest services: postgres: image: postgres:15-alpine env: POSTGRES_PASSWORD: postgres POSTGRES_USER: postgres POSTGRES_DB: test options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 5432:5432 env: DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test TEST_DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test steps: - name: Checkout code uses: actions/checkout@v4 with: submodules: recursive - name: Setup pnpm uses: pnpm/action-setup@v2 with: version: 8 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '18' cache: 'pnpm' - name: Install dependencies run: pnpm install --frozen-lockfile - name: Run tests run: pnpm test - name: Upload coverage uses: codecov/codecov-action@v3 if: always() with: token: ${{ secrets.CODECOV_TOKEN }} files: ./coverage/lcov.info fail_ci_if_error: false build: name: Build runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 with: submodules: recursive - name: Setup pnpm uses: pnpm/action-setup@v2 with: version: 8 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '18' cache: 'pnpm' - name: Install dependencies run: pnpm install --frozen-lockfile - name: Build run: pnpm build security-scan: name: Security Scan runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 with: submodules: recursive - 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 results to GitHub Security uses: github/codeql-action/upload-sarif@v2 with: sarif_file: 'trivy-results.sarif' sbom: name: Generate SBOM runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 with: submodules: recursive - name: Setup pnpm uses: pnpm/action-setup@v2 with: version: 8 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '18' cache: 'pnpm' - name: Install dependencies run: pnpm install --frozen-lockfile - name: Install Syft uses: anchore/sbom-action/download-syft@v0 with: syft-version: latest - name: Generate SBOM run: | syft packages dir:. -o spdx-json > sbom.spdx.json syft packages dir:. -o cyclonedx-json > sbom.cyclonedx.json - name: Upload SBOM artifacts uses: actions/upload-artifact@v3 with: name: sbom path: | sbom.spdx.json sbom.cyclonedx.json - name: Run Grype scan uses: anchore/scan-action@v3 id: grype with: path: "." fail-build: false severity-cutoff: high - name: Upload Grype results uses: github/codeql-action/upload-sarif@v2 if: always() with: sarif_file: ${{ steps.grype.outputs.sarif }} docker-build: name: Build Docker Images runs-on: ubuntu-latest if: github.event_name == 'push' && github.ref == 'refs/heads/main' needs: [build] strategy: matrix: service: - intake - identity - finance - dataroom steps: - name: Checkout code uses: actions/checkout@v4 with: submodules: recursive - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata id: meta uses: docker/metadata-action@v5 with: images: ghcr.io/${{ github.repository }}/${{ matrix.service }} tags: | type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=sha - name: Build and push uses: docker/build-push-action@v5 with: context: ./services/${{ matrix.service }} push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max - name: Sign image with Cosign uses: sigstore/cosign-installer@v3 if: github.ref == 'refs/heads/main' - name: Sign container image run: | cosign sign --yes ${{ steps.meta.outputs.tags }}