Skip to content

Commit c1e449a

Browse files
authored
Merge pull request #2 from sanspace/feat/release-infra
add release.yml
2 parents 856a482 + 2dea253 commit c1e449a

1 file changed

Lines changed: 104 additions & 0 deletions

File tree

.github/workflows/release.yml

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
name: Release Pipeline
2+
3+
on:
4+
release:
5+
types: [created]
6+
workflow_dispatch: # Added for easier iterative testing as we discussed
7+
8+
env:
9+
REGISTRY: ghcr.io
10+
# This dynamically sets the base image name to your repo path
11+
IMAGE_BASE: ${{ github.repository }}
12+
13+
jobs:
14+
build-and-push:
15+
runs-on: ubuntu-latest
16+
strategy:
17+
fail-fast: false
18+
matrix:
19+
# Modernized to handle both components mentioned in your bootstrap script
20+
include:
21+
- service: backend
22+
context: ./backend
23+
image: ghcr.io/${{ github.repository }}/backend
24+
- service: frontend
25+
context: ./frontend
26+
image: ghcr.io/${{ github.repository }}/frontend
27+
28+
permissions:
29+
contents: read
30+
packages: write
31+
id-token: write # Required for Keyless Cosign signing
32+
security-events: write # Required to upload Trivy scan results to Security tab
33+
34+
steps:
35+
- name: Checkout repository
36+
uses: actions/checkout@v4
37+
38+
- name: Set up Docker Buildx
39+
uses: docker/setup-buildx-action@v3
40+
41+
- name: Log in to the Container registry
42+
uses: docker/login-action@v3
43+
with:
44+
registry: ${{ env.REGISTRY }}
45+
username: ${{ github.actor }}
46+
password: ${{ secrets.GITHUB_TOKEN }}
47+
48+
- name: Extract metadata (tags, labels)
49+
id: meta
50+
uses: docker/metadata-action@v5
51+
with:
52+
images: ${{ matrix.image }}
53+
tags: |
54+
type=semver,pattern={{version}}
55+
type=sha,prefix=sha-
56+
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
57+
58+
- name: Build and push Docker image
59+
id: build-push
60+
uses: docker/build-push-action@v5
61+
with:
62+
context: ${{ matrix.context }}
63+
push: true
64+
tags: ${{ steps.meta.outputs.tags }}
65+
labels: ${{ steps.meta.outputs.labels }}
66+
# Modern Feature: GitHub Actions Cache to speed up iterative builds
67+
cache-from: type=gha
68+
cache-to: type=gha,mode=max
69+
70+
- name: Run Trivy vulnerability scanner
71+
uses: aquasecurity/trivy-action@0.20.0
72+
with:
73+
image-ref: ${{ matrix.image }}@${{ steps.build-push.outputs.digest }}
74+
format: 'sarif'
75+
output: 'trivy-results.sarif'
76+
severity: 'CRITICAL,HIGH'
77+
78+
- name: Upload Trivy scan results to GitHub Security
79+
uses: github/codeql-action/upload-sarif@v3
80+
with:
81+
sarif_file: 'trivy-results.sarif'
82+
category: ${{ matrix.service }}
83+
84+
- name: Install Cosign
85+
uses: sigstore/cosign-installer@v3.5.0
86+
87+
- name: Sign image and Attest SBOM
88+
env:
89+
DIGEST: ${{ steps.build-push.outputs.digest }}
90+
run: |
91+
# Keyless signing via GitHub OIDC
92+
cosign sign --yes "${{ matrix.image }}@${{ env.DIGEST }}"
93+
94+
# Modern Feature: Instead of just 'attaching', we create a signed attestation
95+
# This makes the SBOM part of the image's verifiable transparency log
96+
cosign attest --yes --type cyclonedx --predicate <(trivy image --format cyclonedx "${{ matrix.image }}@${{ env.DIGEST }}") "${{ matrix.image }}@${{ env.DIGEST }}"
97+
98+
- name: Generate SLSA Provenance
99+
# This provides a non-falsifiable record of where and how the image was built
100+
uses: github-early-access/generate-build-provenance@v1
101+
with:
102+
subject-name: ${{ matrix.image }}
103+
subject-digest: ${{ steps.build-push.outputs.digest }}
104+
push-to-registry: true

0 commit comments

Comments
 (0)