Skip to content

Replace actions table list with vertical card stack #537

Replace actions table list with vertical card stack

Replace actions table list with vertical card stack #537

name: Build, Test & Push to GHCR
on:
push:
branches: [main]
pull_request:
branches: [main]
types: [opened, synchronize, reopened]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
env:
REGISTRY: ghcr.io
ORG_NAME: refactor-group
REPO_NAME: refactor-platform-fe
NODE_ENV: test
jobs:
# === LINT JOB ===
lint:
name: Lint & Format Check
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: 24.x
cache: 'npm'
cache-dependency-path: package-lock.json
- name: Install dependencies
run: npm ci --prefer-offline
- name: Run ESLint
run: npm run lint
# === TEST JOB ===
test:
name: Build & Test
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: 24.x
cache: 'npm'
cache-dependency-path: package-lock.json
# 🎯 Next.js build cache (job-specific to prevent race conditions)
- name: Cache Next.js build
uses: actions/cache@v4
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-test-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
restore-keys: |
${{ runner.os }}-nextjs-test-${{ hashFiles('**/package-lock.json') }}-
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
# 🎯 Playwright browser cache
- name: Cache Playwright browsers
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-playwright-
- name: Install dependencies
run: npm ci --prefer-offline
- name: Build application
run: npm run build
- name: Install Playwright browsers
run: npx playwright install --with-deps
- name: Run unit tests
run: npm run test:run
- name: Run E2E tests
run: npm run test:e2e
# === DOCKER BUILD & PUSH JOB ===
docker:
name: Build & Push Docker Image
runs-on: ubuntu-24.04
needs: [lint, test] # Only run if lint and test pass
if: github.event_name == 'push' || github.event_name == 'pull_request'
permissions:
contents: read
packages: write
attestations: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Docker login
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Determine Image Tags
id: tags
run: |
BRANCH_NAME=${GITHUB_HEAD_REF:-${GITHUB_REF##*/}}
BRANCH_NAME_LOWER=$(echo "$BRANCH_NAME" | tr '[:upper:]' '[:lower:]')
IMAGE_BASE="${{ env.REGISTRY }}/${{ env.ORG_NAME }}/${{ env.REPO_NAME }}/${BRANCH_NAME_LOWER}"
echo "frontend_tags=$IMAGE_BASE:latest,$IMAGE_BASE:${{ github.sha }}" >> $GITHUB_OUTPUT
echo "frontend_image_name=$IMAGE_BASE" >> $GITHUB_OUTPUT
- name: Build and Push Frontend Image
id: push_frontend
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
target: runner
platforms: linux/amd64
push: true
provenance: true
sbom: true
build-args: |
NEXT_PUBLIC_BACKEND_SERVICE_PROTOCOL=${{ vars.BACKEND_SERVICE_PROTOCOL }}
NEXT_PUBLIC_BACKEND_SERVICE_HOST=${{ vars.BACKEND_SERVICE_HOST }}
NEXT_PUBLIC_BACKEND_SERVICE_PORT=${{ vars.BACKEND_SERVICE_PORT }}
NEXT_PUBLIC_BACKEND_SERVICE_API_PATH=${{ vars.BACKEND_SERVICE_API_PATH }}
NEXT_PUBLIC_BACKEND_API_VERSION=${{ vars.BACKEND_API_VERSION }}
NEXT_PUBLIC_TIPTAP_APP_ID=${{ vars.TIPTAP_APP_ID }}
FRONTEND_SERVICE_PORT=${{ vars.FRONTEND_SERVICE_PORT }}
FRONTEND_SERVICE_INTERFACE=${{ vars.FRONTEND_SERVICE_INTERFACE }}
tags: ${{ steps.tags.outputs.frontend_tags }}
cache-from: type=gha,scope=frontend-nonprod
cache-to: type=gha,mode=max,scope=frontend-nonprod
labels: |
org.opencontainers.image.title=Refactor Platform Frontend
org.opencontainers.image.description=Next.js frontend for refactor coaching platform
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}
- name: Attest Frontend Build
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
uses: actions/attest-build-provenance@v2
with:
subject-name: ${{ steps.tags.outputs.frontend_image_name }}
subject-digest: ${{ steps.push_frontend.outputs.digest }}
push-to-registry: true
- name: Print Usage Instructions
run: |
echo "🎉 Build, Test & Push completed successfully!"
echo ""
echo "📦 Frontend Image Pushed:"
echo " docker pull ${{ steps.tags.outputs.frontend_image_name }}:latest"
echo " docker pull ${{ steps.tags.outputs.frontend_image_name }}:${{ github.sha }}"
echo ""
echo "🚀 Run Frontend:"
echo " docker run --rm --env-file .env -p 3000:3000 ${{ steps.tags.outputs.frontend_image_name }}:latest"