Skip to content

Commit 1562e1f

Browse files
authored
Merge pull request #113 from refactor-group/82-feature-request-suggestion-create-fe-image-workflow
82 feature request suggestion create fe image workflow
2 parents 5ecf9cd + 7b30867 commit 1562e1f

File tree

3 files changed

+219
-1
lines changed

3 files changed

+219
-1
lines changed

.github/workflows/build_and_push_image.yml renamed to .github/workflows/build_and_push_nonproduction_images.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Build and Push Frontend Image
1+
name: Build and Push Non-Production Images
22

33
on:
44
push:
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
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"

.github/workflows/deploy_to_do.yml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
name: Deploy to DigitalOcean via Tailscale UI
2+
3+
permissions:
4+
contents: read # Read-only access to repository contents
5+
on:
6+
workflow_dispatch:
7+
8+
jobs:
9+
deploy:
10+
name: Deploy Frontend to DigitalOcean # Job name for display
11+
runs-on: ubuntu-24.04 # Use latest Ubuntu runner
12+
permissions: # job-level permissions necessary for Tailscale
13+
contents: read # Read repository contents
14+
id-token: write # Required for OIDC token operations (Tailscale)
15+
16+
steps:
17+
# Set up Tailscale connection to securely access the droplet
18+
- name: Set up Tailscale Connection # Connect to Tailscale network
19+
uses: tailscale/github-action@v3 # Use Tailscale's official action
20+
with:
21+
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }} # Tailscale OAuth client ID
22+
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }} # Tailscale OAuth secret
23+
tags: tag:github-actions # Tag for this Tailscale node
24+
version: latest # Use latest Tailscale version
25+
use-cache: 'true' # Cache Tailscale for faster setup
26+
27+
# Verify SSH connection before attempting deployment
28+
- name: Set up SSH Connection # Setup and verify SSH key
29+
run: |
30+
mkdir -p ~/.ssh # Create SSH directory
31+
echo "${{ secrets.DO_SSH_KEY }}" > ~/.ssh/id_ed25519 # Save SSH key from secrets
32+
chmod 600 ~/.ssh/id_ed25519 # Set correct permissions
33+
34+
# Add host key to known_hosts to prevent prompts
35+
ssh-keyscan -H ${{ secrets.DO_TAILSCALE_NAME }} >> ~/.ssh/known_hosts
36+
37+
# Test connection to ensure everything is working
38+
ssh -o BatchMode=yes -i ~/.ssh/id_ed25519 ${{ secrets.DO_USERNAME }}@${{ secrets.DO_TAILSCALE_NAME }} 'echo "SSH connection successful"'
39+
40+
# Main deployment step - SSH to the server and deploy the frontend
41+
- name: Deploy Frontend Container # Main deployment step
42+
run: |
43+
# Set up SSH connection
44+
ssh -o BatchMode=yes -i ~/.ssh/id_ed25519 ${{ secrets.DO_USERNAME }}@${{ secrets.DO_TAILSCALE_NAME }} '
45+
set -e # Exit on any error
46+
47+
echo "📦 Starting frontend deployment..." # Announce deployment start
48+
49+
# Login to GitHub Container Registry
50+
echo "${{ secrets.GHCR_PAT }}" | docker login ghcr.io -u ${{ secrets.GHCR_USERNAME }} --password-stdin
51+
52+
# Pull the latest frontend image
53+
docker pull ${{ secrets.FRONTEND_IMAGE_NAME }}
54+
55+
# Stop and remove existing container if it exists
56+
docker stop nextjs-app 2>/dev/null || true
57+
docker rm nextjs-app 2>/dev/null || true
58+
59+
# Run new container with environment variables
60+
docker run -d --name nextjs-app \
61+
--restart unless-stopped \
62+
-p ${{ secrets.FRONTEND_SERVICE_PORT }}:${{ secrets.FRONTEND_SERVICE_PORT }} \
63+
-e NEXT_PUBLIC_BACKEND_SERVICE_PROTOCOL=${{ secrets.NEXT_PUBLIC_BACKEND_SERVICE_PROTOCOL }} \
64+
-e NEXT_PUBLIC_BACKEND_SERVICE_HOST=${{ secrets.NEXT_PUBLIC_BACKEND_SERVICE_HOST }} \
65+
-e NEXT_PUBLIC_BACKEND_SERVICE_PORT=${{ secrets.NEXT_PUBLIC_BACKEND_SERVICE_PORT }} \
66+
-e NEXT_PUBLIC_BACKEND_API_VERSION=${{ secrets.NEXT_PUBLIC_BACKEND_API_VERSION }} \
67+
-e NEXT_PUBLIC_TIPTAP_APP_ID=${{ secrets.NEXT_PUBLIC_TIPTAP_APP_ID }} \
68+
-e FRONTEND_SERVICE_INTERFACE=${{ secrets.FRONTEND_SERVICE_INTERFACE }} \
69+
-e FRONTEND_SERVICE_PORT=${{ secrets.FRONTEND_SERVICE_PORT }} \
70+
${{ secrets.FRONTEND_IMAGE_NAME }}
71+
72+
# Verify the container is running
73+
echo "⏳ Waiting for container to initialize..." # Wait for startup
74+
sleep 5 # Brief pause
75+
76+
# Check container status
77+
if docker ps | grep -q nextjs-app; then
78+
echo "✅ Deployment successful! Frontend container is running."
79+
else
80+
echo "❌ Deployment failed. Container logs:"
81+
docker logs nextjs-app
82+
exit 1 # Fail the workflow
83+
fi
84+
85+
# Display container info
86+
echo "🔍 Container details:"
87+
docker ps | grep nextjs-app
88+
'

0 commit comments

Comments
 (0)