chore: update dependencies and improve web vitals reporting #36
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: Docker Image CI/CD | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| tags: [ 'v*.*.*' ] | |
| pull_request: | |
| branches: [ main, develop ] | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| BACKEND_IMAGE_NAME: ${{ github.repository }}-backend | |
| FRONTEND_IMAGE_NAME: ${{ github.repository }}-frontend | |
| jobs: | |
| test: | |
| name: Test Docker Build | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| service: [backend, frontend] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Test build ${{ matrix.service }} | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./Dockerfile.${{ matrix.service }} | |
| push: false | |
| tags: test-${{ matrix.service }}:latest | |
| cache-from: type=gha,scope=${{ matrix.service }} | |
| cache-to: type=gha,mode=max,scope=${{ matrix.service }} | |
| build-and-push-backend: | |
| name: Build and Push Backend to GHCR | |
| needs: test | |
| if: github.event_name != 'pull_request' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| id-token: write | |
| attestations: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract Docker metadata for Backend | |
| id: meta-backend | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.BACKEND_IMAGE_NAME }} | |
| tags: | | |
| type=ref,event=branch,pattern=develop | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=semver,pattern={{major}} | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| labels: | | |
| org.opencontainers.image.title=MQA React Backend | |
| org.opencontainers.image.description=Backend API for Metadata Quality Assessment Tool | |
| org.opencontainers.image.vendor=mjanez | |
| maintainer=mjanez | |
| - name: Build and push Backend Docker image | |
| id: build-and-push-backend | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./Dockerfile.backend | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| tags: ${{ steps.meta-backend.outputs.tags }} | |
| labels: ${{ steps.meta-backend.outputs.labels }} | |
| cache-from: type=gha,scope=backend | |
| cache-to: type=gha,mode=max,scope=backend | |
| build-args: | | |
| NODE_ENV=production | |
| BUILD_DATE=${{ github.event.repository.updated_at }} | |
| VCS_REF=${{ github.sha }} | |
| - name: Generate artifact attestation for Backend | |
| uses: actions/attest-build-provenance@v1 | |
| with: | |
| subject-name: ${{ env.REGISTRY }}/${{ env.BACKEND_IMAGE_NAME }} | |
| subject-digest: ${{ steps.build-and-push-backend.outputs.digest }} | |
| push-to-registry: true | |
| - name: Generate SBOM for Backend | |
| uses: anchore/sbom-action@v0 | |
| with: | |
| image: ${{ env.REGISTRY }}/${{ env.BACKEND_IMAGE_NAME }}@${{ steps.build-and-push-backend.outputs.digest }} | |
| format: spdx-json | |
| output-file: sbom-backend-spdx.json | |
| - name: Upload Backend SBOM | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: sbom-backend | |
| path: sbom-backend-spdx.json | |
| build-and-push-frontend: | |
| name: Build and Push Frontend to GHCR | |
| needs: test | |
| if: github.event_name != 'pull_request' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| id-token: write | |
| attestations: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract Docker metadata for Frontend | |
| id: meta-frontend | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.FRONTEND_IMAGE_NAME }} | |
| tags: | | |
| type=ref,event=branch,pattern=develop | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=semver,pattern={{major}} | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| labels: | | |
| org.opencontainers.image.title=MQA React Frontend | |
| org.opencontainers.image.description=Frontend Application for Metadata Quality Assessment Tool | |
| org.opencontainers.image.vendor=mjanez | |
| maintainer=mjanez | |
| - name: Build and push Frontend Docker image | |
| id: build-and-push-frontend | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./Dockerfile.frontend | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| tags: ${{ steps.meta-frontend.outputs.tags }} | |
| labels: ${{ steps.meta-frontend.outputs.labels }} | |
| cache-from: type=gha,scope=frontend | |
| cache-to: type=gha,mode=max,scope=frontend | |
| build-args: | | |
| NODE_ENV=production | |
| PUBLIC_URL=/ | |
| REACT_APP_BACKEND_URL=/api | |
| BUILD_DATE=${{ github.event.repository.updated_at }} | |
| VCS_REF=${{ github.sha }} | |
| - name: Generate artifact attestation for Frontend | |
| uses: actions/attest-build-provenance@v1 | |
| with: | |
| subject-name: ${{ env.REGISTRY }}/${{ env.FRONTEND_IMAGE_NAME }} | |
| subject-digest: ${{ steps.build-and-push-frontend.outputs.digest }} | |
| push-to-registry: true | |
| - name: Generate SBOM for Frontend | |
| uses: anchore/sbom-action@v0 | |
| with: | |
| image: ${{ env.REGISTRY }}/${{ env.FRONTEND_IMAGE_NAME }}@${{ steps.build-and-push-frontend.outputs.digest }} | |
| format: spdx-json | |
| output-file: sbom-frontend-spdx.json | |
| - name: Upload Frontend SBOM | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: sbom-frontend | |
| path: sbom-frontend-spdx.json | |
| scan: | |
| name: Security Scan | |
| needs: [build-and-push-backend, build-and-push-frontend] | |
| if: github.event_name != 'pull_request' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| security-events: write | |
| strategy: | |
| matrix: | |
| service: [backend, frontend] | |
| include: | |
| - service: backend | |
| image_name: ${{ github.repository }}-backend | |
| - service: frontend | |
| image_name: ${{ github.repository }}-frontend | |
| steps: | |
| - name: Run Trivy vulnerability scanner | |
| uses: aquasecurity/trivy-action@master | |
| with: | |
| image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }} | |
| format: 'sarif' | |
| output: 'trivy-results.sarif' | |
| - name: Upload Trivy results to GitHub Security tab | |
| uses: github/codeql-action/upload-sarif@v3 | |
| with: | |
| sarif_file: 'trivy-results.sarif' | |
| pr-comment: | |
| name: Comment on PR | |
| needs: test | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| pull-requests: write | |
| steps: | |
| - name: Comment PR with image details | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const output = `#### 🐳 Docker Images Build Test Completed | |
| **Registry:** \`ghcr.io\` | |
| **Backend Image:** \`${{ env.REGISTRY }}/${{ env.BACKEND_IMAGE_NAME }}\` | |
| **Frontend Image:** \`${{ env.REGISTRY }}/${{ env.FRONTEND_IMAGE_NAME }}\` | |
| > ℹ️ **Note**: PR images are only built and pushed when merged to main/develop branches. | |
| #### To test locally: | |
| \`\`\`bash | |
| # Clone PR branch | |
| git fetch origin pull/${{ github.event.pull_request.number }}/head:pr-${{ github.event.pull_request.number }} | |
| git checkout pr-${{ github.event.pull_request.number }} | |
| # Build and run with docker-compose | |
| docker compose up -d --build | |
| # Access application | |
| # Frontend: https://localhost | |
| # Backend API: https://localhost/api/health | |
| \`\`\` | |
| #### Or build images manually: | |
| \`\`\`bash | |
| # Build backend | |
| docker build -t mqa-backend:pr-${{ github.event.pull_request.number }} -f Dockerfile.backend . | |
| # Build frontend | |
| docker build -t mqa-frontend:pr-${{ github.event.pull_request.number }} -f Dockerfile.frontend . | |
| # Run services | |
| docker network create mqa-network | |
| docker run -d --name mqa-backend \\ | |
| --network mqa-network \\ | |
| -e NODE_ENV=production \\ | |
| mqa-backend:pr-${{ github.event.pull_request.number }} | |
| docker run -d --name mqa-frontend \\ | |
| --network mqa-network \\ | |
| -p 3000:3000 \\ | |
| mqa-frontend:pr-${{ github.event.pull_request.number }} | |
| \`\`\` | |
| *Built from commit: \`${{ github.sha }}\` | |
| services: | |
| mqa-app: | |
| image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:pr-${{ github.event.pull_request.number }} | |
| ports: | |
| - "3000:3000" | |
| - "3001:3001" | |
| \`\`\` | |
| *Built from commit: ${{ github.sha }}*`; | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: output | |
| }); |