From 2dea253199d83f805de5586572155cf017e245f5 Mon Sep 17 00:00:00 2001 From: San Srinivasan Date: Fri, 1 May 2026 01:01:31 +0000 Subject: [PATCH] add release.yml --- .github/workflows/release.yml | 104 ++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..84cd2276 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,104 @@ +name: Release Pipeline + +on: + release: + types: [created] + workflow_dispatch: # Added for easier iterative testing as we discussed + +env: + REGISTRY: ghcr.io + # This dynamically sets the base image name to your repo path + IMAGE_BASE: ${{ github.repository }} + +jobs: + build-and-push: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + # Modernized to handle both components mentioned in your bootstrap script + include: + - service: backend + context: ./backend + image: ghcr.io/${{ github.repository }}/backend + - service: frontend + context: ./frontend + image: ghcr.io/${{ github.repository }}/frontend + + permissions: + contents: read + packages: write + id-token: write # Required for Keyless Cosign signing + security-events: write # Required to upload Trivy scan results to Security tab + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ matrix.image }} + tags: | + type=semver,pattern={{version}} + type=sha,prefix=sha- + type=raw,value=latest,enable=${{ github.event_name == 'release' }} + + - name: Build and push Docker image + id: build-push + uses: docker/build-push-action@v5 + with: + context: ${{ matrix.context }} + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + # Modern Feature: GitHub Actions Cache to speed up iterative builds + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@0.20.0 + with: + image-ref: ${{ matrix.image }}@${{ steps.build-push.outputs.digest }} + format: 'sarif' + output: 'trivy-results.sarif' + severity: 'CRITICAL,HIGH' + + - name: Upload Trivy scan results to GitHub Security + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: 'trivy-results.sarif' + category: ${{ matrix.service }} + + - name: Install Cosign + uses: sigstore/cosign-installer@v3.5.0 + + - name: Sign image and Attest SBOM + env: + DIGEST: ${{ steps.build-push.outputs.digest }} + run: | + # Keyless signing via GitHub OIDC + cosign sign --yes "${{ matrix.image }}@${{ env.DIGEST }}" + + # Modern Feature: Instead of just 'attaching', we create a signed attestation + # This makes the SBOM part of the image's verifiable transparency log + cosign attest --yes --type cyclonedx --predicate <(trivy image --format cyclonedx "${{ matrix.image }}@${{ env.DIGEST }}") "${{ matrix.image }}@${{ env.DIGEST }}" + + - name: Generate SLSA Provenance + # This provides a non-falsifiable record of where and how the image was built + uses: github-early-access/generate-build-provenance@v1 + with: + subject-name: ${{ matrix.image }} + subject-digest: ${{ steps.build-push.outputs.digest }} + push-to-registry: true