1
+ name : Build and Push Production Images
2
+ # Builds the frontend into production containers for release and pushes to GitHub Container Registry with stable tag
3
+
4
+ permissions :
5
+ contents : read # Default to read-only permissions for all jobs
6
+ on :
7
+ release :
8
+ types : [released] # This workflow only runs when a new GitHub release is *actually* released publicly
9
+ workflow_dispatch : # Also allows manual triggering from GitHub UI
10
+
11
+ env :
12
+ REGISTRY : ghcr.io
13
+ IMAGE_NAME : ${{ github.repository }} # Repository path for the image
14
+
15
+ jobs :
16
+ build_test_run :
17
+ runs-on : ubuntu-24.04
18
+ steps :
19
+ - uses : actions/checkout@v4 # Checkout the repository code
20
+ - name : Set up Node.js
21
+ uses : actions/setup-node@v3 # Set up Node.js environment
22
+ with :
23
+ node-version : 21.x # Using Node.js 21.x as in the regular CI workflow
24
+ cache : ' npm' # Enable npm caching for faster builds
25
+
26
+ - name : Install dependencies
27
+ run : npm run ci # Clean Install of dependencies
28
+ - name : Run build
29
+ run : npm run build --if-present # Build the Next.js application
30
+
31
+ # TODO Uncomment when tests are implemented
32
+ # - name: Run tests
33
+ # run: npm test # Run tests when they are implemented
34
+
35
+ build_and_push_docker :
36
+ runs-on : ubuntu-24.04
37
+ needs : build_test_run
38
+ permissions :
39
+ contents : read # Read repository contents
40
+ packages : write # Write to GitHub Packages
41
+ attestations : write # Allow attestation creation
42
+ id-token : write # Required for OIDC signing
43
+
44
+ steps :
45
+ - uses : actions/checkout@v4 # Checkout code for the Docker build
46
+
47
+ - name : Setup QEMU
48
+ uses : docker/setup-qemu-action@v2 # Set up QEMU for multi-architecture builds
49
+ with :
50
+ platforms : linux/amd64,linux/arm64 # Build for both Intel/AMD and ARM architectures
51
+
52
+ - name : Docker login
53
+ uses : docker/login-action@v2 # Log in to GitHub Container Registry
54
+ with :
55
+ registry : ${{ env.REGISTRY }}
56
+ username : ${{ github.actor }}
57
+ password : ${{ secrets.GITHUB_TOKEN }}
58
+
59
+ - uses : docker/setup-buildx-action@v3 # Set up Docker Buildx
60
+ with :
61
+ install : true # Install Buildx
62
+
63
+ - name : Show Docker Build Cache (Before)
64
+ run : | # Display cache info before build
65
+ echo "🔍 Checking buildx cache BEFORE build..."
66
+ docker buildx du || echo "No cache found yet."
67
+
68
+ # Compute stable tag for production image
69
+ - name : Determine Image Tags
70
+ id : tags # Set output ID for this step
71
+ run : |
72
+ IMAGE_NAME="${{ env.REGISTRY }}/${{ github.repository }}"
73
+ echo "frontend_tags=$IMAGE_NAME:stable" >> $GITHUB_OUTPUT # Tag image as "stable"
74
+ echo "frontend_image_name=$IMAGE_NAME" >> $GITHUB_OUTPUT
75
+
76
+ - name : Build + Push Frontend
77
+ id : push_frontend # Set ID for this step to reference outputs
78
+ uses : docker/build-push-action@v5
79
+ with :
80
+ context : . # Build context is repository root
81
+ file : ./Dockerfile # Use the Dockerfile at repository root
82
+ target : runner # Use the runner stage from the Dockerfile
83
+ platforms : linux/amd64,linux/arm64 # Multi-architecture build
84
+ push : true # Push image to registry
85
+ provenance : true # Enable provenance metadata
86
+ sbom : true # Generate Software Bill of Materials
87
+ build-args : | # Environment variables for the build
88
+ NEXT_PUBLIC_BACKEND_SERVICE_PROTOCOL=${{ secrets.BACKEND_SERVICE_PROTOCOL }}
89
+ NEXT_PUBLIC_BACKEND_SERVICE_HOST=${{ secrets.BACKEND_SERVICE_HOST }}
90
+ NEXT_PUBLIC_BACKEND_SERVICE_PORT=${{ secrets.BACKEND_PORT }}
91
+ NEXT_PUBLIC_BACKEND_API_VERSION=${{ secrets.BACKEND_API_VERSION }}
92
+ FRONTEND_SERVICE_PORT=${{ secrets.FRONTEND_SERVICE_PORT }}
93
+ FRONTEND_SERVICE_INTERFACE=${{ secrets.FRONTEND_SERVICE_INTERFACE }}
94
+ tags : ${{ steps.tags.outputs.frontend_tags }} # Use "stable" tag from previous step
95
+ cache-from : type=gha # Use GitHub Actions cache
96
+ cache-to : type=gha,mode=max # Cache for future builds
97
+
98
+ - name : Show Docker Build Cache (After)
99
+ run : | # Display cache info after build
100
+ echo "📦 Checking buildx cache AFTER build..."
101
+ docker buildx du || echo "Failed to get updated cache info."
102
+
103
+ # Install Cosign for image signing
104
+ - name : Install Cosign
105
+ uses : sigstore/cosign-installer@v3
106
+
107
+ # Sign the container image
108
+ - name : Sign image with Cosign
109
+ env :
110
+ COSIGN_EXPERIMENTAL : " true"
111
+ run : |
112
+ cosign sign --yes ${{ steps.tags.outputs.frontend_image_name }}:stable
113
+
114
+ # Attest build provenance
115
+ - name : Attest Frontend
116
+ if : github.event_name == 'release' || github.event_name == 'workflow_dispatch' # Only attest on release or manual trigger
117
+ uses : actions/attest-build-provenance@v2 # Use GitHub attestation action
118
+ with :
119
+ subject-name : ${{ steps.tags.outputs.frontend_image_name }} # Image name to attest
120
+ subject-digest : ${{ steps.push_frontend.outputs.digest }} # Image digest to attest
121
+ push-to-registry : true # Push attestation to registry
122
+
123
+ - name : Print Usage Instructions
124
+ run : | # Print usage instructions
125
+ echo "Frontend Image Pushed to ghcr.io as STABLE:"
126
+ echo " docker pull ${{ steps.tags.outputs.frontend_image_name }}:stable"
127
+ echo "Run it locally:"
128
+ echo " docker run --rm --env-file .env -p 3000:3000 ${{ steps.tags.outputs.frontend_image_name }}:stable"
129
+ echo "Verify signature:"
130
+ echo " cosign verify ${{ steps.tags.outputs.frontend_image_name }}:stable"
0 commit comments