Replace actions table list with vertical card stack #537
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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" |