Skip to content

CI Workflow

The CI pipeline runs on every pull request to main and on pushes to main. It validates code quality, builds artefacts, scans for vulnerabilities, and runs UI tests — all orchestrated through reusable GitHub Actions workflows.

Pipeline Overview

graph TD
    A[generate_project_matrix] --> B[lint_test_build_and_scan]
    B --> C[build_docker_image]
    C --> D[docker_security_check]
    C --> E[run_ui_tests]
    A --> F[generate_summary]
    B --> F
    C --> F
    D --> F
    E --> F
    F --> G[report-results]
    F --> H[status_check]

    style A fill:#e1f5ff
    style B fill:#fff3e0
    style C fill:#e8f5e9
    style D fill:#ffebee
    style E fill:#f3e5f5
    style F fill:#fff9c4
    style G fill:#fff9c4
    style H fill:#fff9c4

Jobs

1. Generate Project Matrix

Workflow: generate-project-matrix.yml

Uses Nx to detect which projects are affected by the current changes. This matrix drives all downstream jobs — if a project isn't affected, its jobs are skipped entirely.

On pushes to main (or in CD mode), all projects are included regardless of changes.

2. Lint, Test, Build and Scan

Workflow: lint-test-build-and-scan.yml

Runs in parallel for each affected project using a matrix strategy (max 4 parallel jobs):

  1. Lint — ESLint with the project's flat config
  2. Test — Jest with code coverage
  3. Build — Nx build target
  4. SonarQube Scan — Static analysis and coverage upload (skipped for Dependabot PRs)

3. Build Docker Image

Workflow: docker-build.yml Condition: Only runs when petfolio-business is affected

Builds a multi-stage Docker image for the Next.js application and uploads it as a CI artefact for downstream jobs. Runs after lint/test/build to avoid wasting time building an image from broken code.

4. Docker Security Check

Workflow: docker-security-check.yml Condition: Only runs when petfolio-business is affected

Scans the built Docker image for vulnerabilities using Trivy:

  • Counts vulnerabilities by severity (critical, high, medium, low)
  • Identifies fixable vulnerabilities
  • Applies a security gate — fails on any critical vulnerabilities or more than 10 high vulnerabilities
  • Uploads the full Trivy JSON report as an artefact (30 day retention)
  • Creates a GitHub issue on main branch failures

Results are included in the unified PR summary comment under a collapsible Docker Security Scan section.

5. UI Tests

Workflow: ui-tests.yml Condition: Only runs when petfolio-business is affected

Runs Playwright end-to-end tests against the built Docker image:

  1. Downloads the Docker image artefact
  2. Starts the container via the start-docker-container composite action
  3. Installs Playwright chromium browser
  4. Runs npx nx e2e petfolio-ui-tests -- --project=chromium with BASE_URL pointing at the container
  5. Parses JUnit XML results to extract test counts and any failure details
  6. Uploads Playwright HTML report and test results as artefacts (7 day retention)
  7. Stops and removes the container

Results are included in the unified PR summary comment under a collapsible UI Test Results section, showing failed test names and error messages when there are failures.

6. Generate Summary and Report Results

Workflow: workflow-summary-template.yml

Collects outputs from all upstream jobs and builds a unified markdown summary with collapsible sections:

Section Headline Detail (collapsible)
Workflow Status Job pass/fail/skip counts Failed job names with links
Docker Security Scan Vulnerability severity counts Full scan report with CVE table
UI Test Results Test/failure/error counts Failed test names with error messages

This summary is posted as a single PR comment (updated on each push) and used to create GitHub issues for main branch failures.

7. Status Check

A required check that gates PR merges. It inspects the results of all upstream jobs and fails if any job failed or was cancelled.

Composite Actions

start-docker-container

Location: .github/actions/start-docker-container/action.yml

Reusable composite action for starting a Docker container with health checking:

Input Required Default Description
imageName yes Docker image to run
port yes 4200:4200 Port mapping
containerName yes Container name
environmentVariables no Space-separated KEY=value pairs

Behaviour:

  1. Runs the container in detached mode with optional environment variables
  2. Polls until the container is running (up to 60 seconds)
  3. Polls the Docker healthcheck status (up to 90 seconds)
  4. On healthcheck failure, captures container logs and uploads them as an artefact

Concurrency

  • PR branches use cancel-in-progress: true — pushing a new commit cancels the in-progress run
  • The main branch allows parallel runs so concurrent merges don't cancel each other

Reusable Workflow Pattern

All CI jobs use the workflow_call trigger, making them reusable workflows that can be composed. The CI workflow (ci.yml) also supports being called from a CD pipeline via workflow_call with a cdMode input that includes all projects regardless of affected detection.

Key Files

File Purpose
.github/workflows/ci.yml Main orchestrator
.github/workflows/generate-project-matrix.yml Nx affected detection
.github/workflows/lint-test-build-and-scan.yml Per-project validation
.github/workflows/docker-build.yml Docker image build
.github/workflows/docker-security-check.yml Trivy vulnerability scanning
.github/workflows/ui-tests.yml Playwright E2E tests
.github/workflows/workflow-summary-template.yml PR comment and issue creation
.github/actions/start-docker-container/action.yml Container lifecycle composite action