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):
- Lint — ESLint with the project's flat config
- Test — Jest with code coverage
- Build — Nx build target
- 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
mainbranch 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:
- Downloads the Docker image artefact
- Starts the container via the
start-docker-containercomposite action - Installs Playwright chromium browser
- Runs
npx nx e2e petfolio-ui-tests -- --project=chromiumwithBASE_URLpointing at the container - Parses JUnit XML results to extract test counts and any failure details
- Uploads Playwright HTML report and test results as artefacts (7 day retention)
- 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:
- Runs the container in detached mode with optional environment variables
- Polls until the container is running (up to 60 seconds)
- Polls the Docker healthcheck status (up to 90 seconds)
- 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
mainbranch 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 |