Consolidate CI into path-aware component matrix and retire non-executable workflows#5
Conversation
PR Summary by QodoConsolidate CI into a path-aware component matrix with normalized reports
AI Description
Diagram
High-Level Assessment
Files changed (7)
|
Code Review by Qodo
1. CI changes skip checks
|
| pull_request: | ||
| branches: [main] | ||
| paths: | ||
| - 'webapp/frontend/**' | ||
| - 'webapp/backend/**' | ||
| - 'webapp/tests/**' | ||
| - 'marketing-site/**' | ||
| - '.github/workflows/ci-matrix.yml' | ||
| - 'CONTRIBUTING.md' | ||
| push: | ||
| branches: [main] | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| changes: | ||
| name: Detect changed components | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| webapp_frontend: ${{ steps.filter.outputs.webapp_frontend }} | ||
| webapp_backend: ${{ steps.filter.outputs.webapp_backend }} | ||
| marketing_site: ${{ steps.filter.outputs.marketing_site }} | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Filter changed paths | ||
| id: filter | ||
| uses: dorny/paths-filter@v3 | ||
| with: | ||
| filters: | | ||
| webapp_frontend: | ||
| - 'webapp/frontend/**' | ||
| webapp_backend: | ||
| - 'webapp/backend/**' | ||
| - 'webapp/tests/**' | ||
| marketing_site: | ||
| - 'marketing-site/**' | ||
|
|
||
| component-checks: | ||
| name: ${{ matrix.component.name }} checks | ||
| runs-on: ubuntu-latest | ||
| needs: changes | ||
| if: | | ||
| github.event_name != 'pull_request' || | ||
| (matrix.component.id == 'webapp-frontend' && needs.changes.outputs.webapp_frontend == 'true') || | ||
| (matrix.component.id == 'webapp-backend' && needs.changes.outputs.webapp_backend == 'true') || | ||
| (matrix.component.id == 'marketing-site' && needs.changes.outputs.marketing_site == 'true') |
There was a problem hiding this comment.
1. Ci changes skip checks 🐞 Bug ☼ Reliability
On pull requests, component-checks only runs when dorny/paths-filter marks a component as changed, but the filter rules exclude .github/workflows/ci-matrix.yml and CONTRIBUTING.md even though those files trigger the workflow. As a result, PRs that only modify the CI workflow/docs can run zero component jobs and provide no validation of the CI change itself.
Agent Prompt
### Issue description
`ci-matrix.yml` triggers on changes to `.github/workflows/ci-matrix.yml` and `CONTRIBUTING.md`, but the `changes` job’s `filters` don’t include those paths. For PRs that only touch those files, all `needs.changes.outputs.*` values are false and the entire `component-checks` matrix is skipped, meaning CI workflow changes are not exercised.
### Issue Context
This is specifically caused by the mismatch between `on.pull_request.paths` and the `dorny/paths-filter` `filters`, combined with the `component-checks.if` gate relying exclusively on the filter outputs for PRs.
### Fix Focus Areas
- .github/workflows/ci-matrix.yml[4-53]
### Suggested fix
Add a dedicated filter (e.g., `ci_infra`) for `.github/workflows/ci-matrix.yml` and `CONTRIBUTING.md` (and any other CI-contract files you want), then update the `component-checks.if` condition so that when `ci_infra == 'true'` you run the full matrix (or at least a representative subset).
Example approach:
- In `filters`, add:
- `ci_infra: ['.github/workflows/ci-matrix.yml', 'CONTRIBUTING.md']`
- In `component-checks.if` (PR case), OR in `needs.changes.outputs.ci_infra == 'true'` for all components (or restructure to: if PR and (ci_infra || component_changed)).
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| if [ "${{ matrix.component.id }}" = "webapp-frontend" ]; then | ||
| cd "${{ matrix.component.path }}" | ||
| npm install --legacy-peer-deps 2>&1 | tee "../../${report_root}/install.log" | ||
| lint_status=0 |
There was a problem hiding this comment.
2. Frontend install non-deterministic 🐞 Bug ☼ Reliability
The webapp-frontend CI path uses npm install even though webapp/frontend has a package-lock.json, which is less deterministic than npm ci and can drift dependency resolution across runs. This can cause CI vs local mismatches and harder-to-reproduce failures.
Agent Prompt
### Issue description
`component-checks` runs `npm install --legacy-peer-deps` for `webapp-frontend` even though a lockfile exists. In CI, `npm ci` is the deterministic install mode and better matches the lockfile contract.
### Issue Context
The repo contains `webapp/frontend/package-lock.json`, so CI can use `npm ci` (optionally still with `--legacy-peer-deps` if required by the dependency graph).
### Fix Focus Areas
- .github/workflows/ci-matrix.yml[92-101]
### Suggested fix
Replace:
- `npm install --legacy-peer-deps`
with:
- `npm ci --legacy-peer-deps`
(or `npm ci` if `--legacy-peer-deps` is not needed).
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| ci-summary: | ||
| name: CI summary | ||
| runs-on: ubuntu-latest | ||
| needs: [component-checks] | ||
| if: always() | ||
| steps: | ||
| - name: Download summary artifacts | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| pattern: ci-summary-* | ||
| path: ci-summary | ||
| merge-multiple: true | ||
|
|
||
| - name: Publish workflow summary | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| echo "# CI Matrix Summary" >> "$GITHUB_STEP_SUMMARY" | ||
| if ls ci-summary/*.md >/dev/null 2>&1; then | ||
| for file in ci-summary/*.md; do | ||
| cat "$file" >> "$GITHUB_STEP_SUMMARY" | ||
| echo >> "$GITHUB_STEP_SUMMARY" | ||
| done | ||
| else | ||
| echo "No component jobs ran for this change set." >> "$GITHUB_STEP_SUMMARY" |
There was a problem hiding this comment.
3. Summary breaks when none run 🐞 Bug ☼ Reliability
ci-summary always runs actions/download-artifact for ci-summary-*, but when no component jobs run (e.g., workflow/docs-only PRs), there may be zero matching artifacts and the download step can fail before the job can emit the intended fallback summary message. This makes the workflow summary path brittle for empty matrices.
Agent Prompt
### Issue description
The `ci-summary` job downloads `ci-summary-*` artifacts unconditionally. If the matrix produced no summary artifacts, the download step may fail and prevent the later script from writing the fallback "No component jobs ran" message.
### Issue Context
This is most likely when `component-checks` is skipped for all matrix entries.
### Fix Focus Areas
- .github/workflows/ci-matrix.yml[166-190]
### Suggested fix
Make the download step tolerant of the "no artifacts" case, for example by:
- Skipping download when `needs.component-checks.result == 'skipped'`, OR
- Adding `continue-on-error: true` to the download step and letting the subsequent `ls ci-summary/*.md` gate the messaging, OR
- If supported, configuring the download action to ignore missing artifacts.
Then ensure the publish step still writes the fallback message when no summaries exist.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
@copilot review |
There was a problem hiding this comment.
Pull request overview
Consolidates GitHub Actions CI into a single, component-oriented matrix workflow with path-aware execution on PRs, standardized report/artifact outputs, and removes legacy/non-aligned workflows while documenting the new CI contract in CONTRIBUTING.md.
Changes:
- Added a unified
.github/workflows/ci-matrix.ymlworkflow with a changed-path detector and per-component checks/artifacts plus an aggregated run summary. - Standardized CI outputs under
ci-reports/<component-id>/and documented the reporting/artifact contract inCONTRIBUTING.md. - Retired multiple legacy/template workflows and moved non-executable placeholders into
docs/ci/legacy-workflows/; adjusted marketing-site lint wiring.
Reviewed changes
Copilot reviewed 15 out of 18 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
.github/workflows/ci-matrix.yml |
New unified CI entrypoint with change-detection, component matrix execution, standardized artifacts, and final summary aggregation. |
CONTRIBUTING.md |
Documents matrix scope, triggers, and the reports/artifacts contract. |
webapp/frontend/.eslintrc.cjs |
Adds an ESLint configuration for the frontend component. |
marketing-site/package.json |
Aligns marketing-site lint script with the updated ESLint wiring. |
marketing-site/eslint.config.mjs |
Introduces flat ESLint config for the marketing site. |
docs/ci/legacy-workflows/workflow-system.yml |
Archives a non-executable legacy workflow placeholder under docs. |
docs/ci/legacy-workflows/PinkFlow-pipeline.yml |
Archives a non-executable legacy pipeline placeholder under docs. |
.github/workflows/webpack.yml |
Removed legacy/template workflow. |
.github/workflows/super-linter.yml |
Removed legacy/template workflow. |
.github/workflows/static.yml |
Removed legacy/template workflow. |
.github/workflows/Rust-Core-CI-Gateway-Delivery.yml |
Removed legacy/non-aligned workflow. |
.github/workflows/rust-ci.yml |
Removed legacy/non-aligned workflow. |
.github/workflows/pylint.yml |
Removed legacy/template workflow. |
.github/workflows/nextjs.yml |
Removed legacy/template workflow. |
.github/workflows/go.yml |
Removed legacy/template workflow. |
.github/workflows/github-pages.yml |
Removed legacy/non-aligned workflow. |
.github/workflows/deno.yml |
Removed legacy/template workflow. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - name: Checkout | ||
| uses: actions/checkout@v4 |
| cd "${{ matrix.component.path }}" | ||
| npm install --legacy-peer-deps 2>&1 | tee "../../${report_root}/install.log" |
| import nextVitals from 'eslint-config-next/core-web-vitals' | ||
|
|
||
| const config = [...nextVitals] | ||
|
|
||
| export default config |
| import nextVitals from 'eslint-config-next/core-web-vitals' | ||
|
|
||
| const config = [...nextVitals] |
CI was fragmented across inconsistent and partially non-executable workflows, with mixed branch strategy and no unified reporting contract. This change introduces a single component-oriented pipeline that runs deterministically by surface area and emits normalized artifacts/summaries.
Unified CI entrypoint
.github/workflows/ci-matrix.ymlas the primary workflow for:pull_requestonmain(path-aware execution)pushonmain(full matrix)workflow_dispatchwebapp/frontendwebapp/backendmarketing-sitePath-aware execution model
changesjob usingdorny/paths-filterto detect touched components.mainpushes, all entries run.Standardized filesystem reports + artifacts
ci-reports/<component-id>/.ci-reports-*).ci-summaryjob that publishes run-level summary content.Workflow hygiene / ownership cleanup
docs/ci/legacy-workflows/PinkFlow-pipeline.ymldocs/ci/legacy-workflows/workflow-system.ymlCI contract documentation
CONTRIBUTING.mdwith matrix scope, trigger behavior, and report/artifact contract.marketing-site/eslint.config.mjs, script alignment) to match current CI behavior.