Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
0495a9f
Remove amd64 builds since we don't need them currently
jhodapp Sep 19, 2025
fe260a1
Emulate the backend's lint, build, test, push to GHCR GitHub Action w…
jhodapp Sep 19, 2025
306d6c0
Use the correct flags for eslint running in the builder
jhodapp Sep 19, 2025
aa94d8f
Remove Rust-build specific env var from the Next.js build process
jhodapp Sep 19, 2025
6928b8a
Optimize CI/CD caching for better performance
jhodapp Sep 19, 2025
1824caf
Apply official Next.js caching strategy from Vercel docs
jhodapp Sep 19, 2025
811df40
Simple change to test to see if Next.js build caching is working
jhodapp Sep 19, 2025
22f5ad4
Fix Next.js build cache detection
jhodapp Sep 19, 2025
e3b12a7
Fix Next.js cache race conditions with job-specific keys
jhodapp Sep 19, 2025
371a0db
Remove redundant legacy workflow and fix npm command
jhodapp Sep 19, 2025
e575c19
Update to node 22 to agree with the project
jhodapp Sep 21, 2025
4d49563
Upgrade to Node.js 24 and actions/setup-node@v5
jhodapp Sep 21, 2025
5df2592
Remove unused Next.js cache from lint job
jhodapp Sep 21, 2025
667f7a3
Upgrade docker/login-action from v2 to v3
jhodapp Sep 21, 2025
e9738d3
Add concurrency controls to auto-cancel redundant workflow runs
jhodapp Sep 21, 2025
32d4d50
Add explicit cache-dependency-path for reliable npm cache invalidation
jhodapp Sep 21, 2025
8dab663
Update the lock file for the node v24 changes
jhodapp Sep 21, 2025
f628ade
Update eslint-config-next to 15.4.7 to match Next.js version
jhodapp Sep 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Build outputs and caches
.next/
coverage/
dist/
build/

# Dependencies
node_modules/

# Environment and config
.env*
.env.local
.env.development.local
.env.test.local
.env.production.local

# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Development and testing
.eslintcache
.nyc_output
playwright-report/
test-results/

# Version control and CI
.git/
.github/
.gitignore

# IDE and editor files
.vscode/
.idea/
*.swp
*.swo
*~

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Documentation
README.md
CHANGELOG.md
docs/

# Temporary files
*.tmp
*.temp
tmp/
temp/
174 changes: 115 additions & 59 deletions .github/workflows/build_and_push_nonproduction_images.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build and Push Non-Production Images
name: Build, Test & Push to GHCR

on:
push:
Expand All @@ -8,102 +8,134 @@ on:
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:
build_and_push_amd64:
# === LINT JOB ===
lint:
name: Lint & Format Check
runs-on: ubuntu-24.04

permissions:
contents: read
packages: write
id-token: write
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:
- uses: actions/checkout@v4
- name: Checkout
uses: actions/checkout@v4

- uses: docker/setup-buildx-action@v3
- name: Setup Node.js
uses: actions/setup-node@v5
with:
install: true
node-version: 24.x
cache: 'npm'
cache-dependency-path: package-lock.json

- name: Docker login
uses: docker/login-action@v2
# 🎯 Next.js build cache (job-specific to prevent race conditions)
- name: Cache Next.js build
uses: actions/cache@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
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: Set Image Tag
id: vars
run: |
BRANCH_NAME=${GITHUB_HEAD_REF:-${GITHUB_REF##*/}}
IMAGE_BASE="${{ env.REGISTRY }}/${{ env.ORG_NAME }}/${{ env.REPO_NAME }}/${BRANCH_NAME}"
echo "tag=${IMAGE_BASE}:amd64" >> $GITHUB_OUTPUT
- name: Install dependencies
run: npm ci --prefer-offline

- name: Build + Push AMD64
id: build
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.vars.outputs.tag }}
cache-from: type=gha,scope=amd64
cache-to: type=gha,mode=max,scope=amd64
- name: Build application
run: npm run build

build_and_push_arm64:
runs-on: ubuntu-24.04
- 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:
- uses: actions/checkout@v4
- name: Checkout
uses: actions/checkout@v4

- uses: docker/setup-buildx-action@v3
with:
install: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Docker login
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set Image Tag
id: vars
- name: Determine Image Tags
id: tags
run: |
BRANCH_NAME=${GITHUB_HEAD_REF:-${GITHUB_REF##*/}}
IMAGE_BASE="${{ env.REGISTRY }}/${{ env.ORG_NAME }}/${{ env.REPO_NAME }}/${BRANCH_NAME}"
echo "tag=${IMAGE_BASE}:arm64" >> $GITHUB_OUTPUT
echo "frontend_tags=$IMAGE_BASE:latest,$IMAGE_BASE:${{ github.sha }}" >> $GITHUB_OUTPUT
echo "frontend_image_name=$IMAGE_BASE" >> $GITHUB_OUTPUT

- name: Build + Push ARM64
id: build
- name: Build and Push Frontend Image
id: push_frontend
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
target: runner
platforms: linux/arm64
platforms: linux/amd64
push: true
provenance: true
sbom: true
Expand All @@ -116,6 +148,30 @@ jobs:
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.vars.outputs.tag }}
cache-from: type=gha,scope=arm64
cache-to: type=gha,mode=max,scope=arm64
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"
Loading