Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ad6f7a7507 | |||
| 403b0750d6 | |||
| f9ed3cf82a |
+11
-1
@@ -79,7 +79,10 @@ jobs:
|
|||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
commits:
|
commits:
|
||||||
if: github.event_name == 'pull_request'
|
# PRs opened by Renovate (apf-portal-bot) carry commit messages
|
||||||
|
# generated from a vetted Conventional-Commits template — running
|
||||||
|
# commitlint on them is tautological. Per ADR-0017 amendment.
|
||||||
|
if: github.event_name == 'pull_request' && github.event.pull_request.user.login != 'apf-portal-bot'
|
||||||
runs-on: [self-hosted, on-prem]
|
runs-on: [self-hosted, on-prem]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -93,6 +96,13 @@ jobs:
|
|||||||
- run: COMMIT_LINT_FROM=origin/main pnpm ci:commits
|
- run: COMMIT_LINT_FROM=origin/main pnpm ci:commits
|
||||||
|
|
||||||
perf:
|
perf:
|
||||||
|
# Skip the Lighthouse run on PRs opened by Renovate (apf-portal-bot):
|
||||||
|
# the per-PR perf signal on a dep bump is essentially zero (no
|
||||||
|
# routes yet, bundle is the static placeholder), and the Lighthouse
|
||||||
|
# round-trip burns several minutes per PR. Push events on `main`
|
||||||
|
# still run perf — we catch regressions immediately post-merge,
|
||||||
|
# not pre-merge. Per ADR-0017 amendment.
|
||||||
|
if: github.event_name != 'pull_request' || github.event.pull_request.user.login != 'apf-portal-bot'
|
||||||
runs-on: [self-hosted, on-prem]
|
runs-on: [self-hosted, on-prem]
|
||||||
# Lighthouse CI drives a real Chrome instance; the default act runner
|
# Lighthouse CI drives a real Chrome instance; the default act runner
|
||||||
# image (catthehacker/ubuntu:act-22.04) ships without one. The :full
|
# image (catthehacker/ubuntu:act-22.04) ships without one. The :full
|
||||||
|
|||||||
@@ -103,11 +103,27 @@ Each route is scored against the thresholds above. **Failure on any threshold is
|
|||||||
|
|
||||||
### Where Lighthouse CI runs
|
### Where Lighthouse CI runs
|
||||||
|
|
||||||
| Environment | Cadence | Purpose | Blocking? |
|
| Environment | Cadence | Purpose | Blocking? |
|
||||||
| ------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------- | ----------------------------------------------------- |
|
| --------------------------------------- | ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ----------------------------------------------------- |
|
||||||
| **CI on every PR** | per push | Catch regressions before merge | **Yes** |
|
| **CI on human-authored PRs** | per push | Catch regressions before merge | **Yes** |
|
||||||
| **CI scheduled (weekly)** on prod env | cron in `security-scheduled.yml` from [ADR-0015](0015-cicd-gitea-actions.md), extended to cover perf | Detect drift / regressions in real environment | Reports as alerts; doesn't block, but triggers triage |
|
| **CI on Renovate (bot) PRs** | _skipped_ | Per-PR perf signal on a dep bump is ≈0; Lighthouse cost is ≥3-5 min per PR | _No (skipped)_ |
|
||||||
| **Local dev** | manual via `pnpm nx run portal-shell:lighthouse` | Developer-side feedback | Non-blocking |
|
| **CI on `push` to `main`** (post-merge) | per merge | Catch regressions immediately after merge — applies to bot PRs too | **Yes** |
|
||||||
|
| **CI scheduled (weekly)** on prod env | cron in `security-scheduled.yml` from [ADR-0015](0015-cicd-gitea-actions.md), extended to cover perf | Detect drift / regressions in real environment | Reports as alerts; doesn't block, but triggers triage |
|
||||||
|
| **Local dev** | manual via `pnpm nx run portal-shell:lighthouse` | Developer-side feedback | Non-blocking |
|
||||||
|
|
||||||
|
### Pre-merge gating policy: human PRs vs bot PRs
|
||||||
|
|
||||||
|
The `perf` job is skipped on PRs whose author is the dedicated Renovate bot user (`apf-portal-bot`). Rationale:
|
||||||
|
|
||||||
|
- A dependency bump on this codebase has near-zero direct impact on the bundle the user receives — the SPA today serves the static placeholder, and even once real routes ship, the Lighthouse score on a patch/minor dep bump rarely moves outside the median noise floor (±2-5 points).
|
||||||
|
- A full Lighthouse round-trip (build prod + 3-iteration median across the critical-routes list) costs 3-5 minutes per PR. Multiplied by the steady-state Renovate cadence (~5-15 PRs per week once dependencies are diversified), this is a real wall-clock cost on shared runners with no reliable signal in return.
|
||||||
|
- The post-merge `push` to `main` still runs the full `perf` gate. A regression that does sneak through a Renovate PR is caught seconds after merge, before the next PR queues a build — fast enough to revert without disruption.
|
||||||
|
|
||||||
|
This policy is **conservative on human PRs** (the perf gate stays mandatory pre-merge, where the latitude for change is highest) and **pragmatic on bot PRs** (where the change vocabulary is narrow and the post-merge gate already provides the safety net).
|
||||||
|
|
||||||
|
The same skip is applied to the `commits` job: Renovate generates commit messages from a Conventional-Commits-conformant template, so re-validating them with commitlint is tautological.
|
||||||
|
|
||||||
|
Edge case: if a human takes over a Renovate-authored PR and force-pushes substantive changes, the gate stays skipped (the PR _author_ is still the bot). This is accepted as a marginal case; the human can either run `ci:perf` locally or accept that the post-merge `push` gate will catch any regression. Re-evaluation if it happens often enough to be a real annoyance.
|
||||||
|
|
||||||
### Variability mitigation
|
### Variability mitigation
|
||||||
|
|
||||||
@@ -143,7 +159,7 @@ These budgets are **not** enforced as hard CI gates — load profile in CI is un
|
|||||||
|
|
||||||
### Performance regressions are bugs, not backlog
|
### Performance regressions are bugs, not backlog
|
||||||
|
|
||||||
A regression on any of the front-end gates blocks the merge. A regression on a back-end SLO that surfaces in production (alert fires) is triaged with the same priority as a security finding — root-caused, fixed, post-mortemed if it took the SLO out for more than 24 h.
|
A regression on any of the front-end gates blocks the merge for human PRs, and blocks `push` to `main` for any PR (including Renovate-authored ones — see the gating-policy subsection above). A regression on a back-end SLO that surfaces in production (alert fires) is triaged with the same priority as a security finding — root-caused, fixed, post-mortemed if it took the SLO out for more than 24 h.
|
||||||
|
|
||||||
### a11y / perf trade-off
|
### a11y / perf trade-off
|
||||||
|
|
||||||
@@ -195,7 +211,7 @@ No browser-side RUM SDK in v1. The OTel browser tracing from [ADR-0012](0012-obs
|
|||||||
- `lighthouserc.js` exists at the repo root with the critical-routes list, the assertions matching the thresholds above, and a 3-iteration median configuration.
|
- `lighthouserc.js` exists at the repo root with the critical-routes list, the assertions matching the thresholds above, and a 3-iteration median configuration.
|
||||||
- `apps/portal-shell/project.json` declares `budgets` of type `"error"` with the values above.
|
- `apps/portal-shell/project.json` declares `budgets` of type `"error"` with the values above.
|
||||||
- `package.json` exposes `ci:perf`, runnable locally with the same exit code as CI.
|
- `package.json` exposes `ci:perf`, runnable locally with the same exit code as CI.
|
||||||
- CI's `perf` gate from [ADR-0015](0015-cicd-gitea-actions.md) calls `pnpm ci:perf` and is blocking.
|
- CI's `perf` gate from [ADR-0015](0015-cicd-gitea-actions.md) calls `pnpm ci:perf`. It is blocking on human PRs and on `push` to `main`; skipped on PRs authored by the Renovate bot user (`apf-portal-bot`) per the gating-policy subsection above.
|
||||||
- `apps/portal-shell` exposes a Nx target `analyze` invoking `source-map-explorer` against the production build's source maps.
|
- `apps/portal-shell` exposes a Nx target `analyze` invoking `source-map-explorer` against the production build's source maps.
|
||||||
- The BFF p95/p99 budgets are documented in `apps/portal-bff/README.md` and translate into alert rules in the production observability backend (configured per future infrastructure ADR).
|
- The BFF p95/p99 budgets are documented in `apps/portal-bff/README.md` and translate into alert rules in the production observability backend (configured per future infrastructure ADR).
|
||||||
- The `security-scheduled.yml` workflow includes a weekly Lighthouse CI run against the prod URL set, with reports uploaded as build artefacts and an alert on any threshold breach.
|
- The `security-scheduled.yml` workflow includes a weekly Lighthouse CI run against the prod URL set, with reports uploaded as build artefacts and an alert on any threshold breach.
|
||||||
|
|||||||
+2
-1
@@ -244,7 +244,8 @@ Repo → Actions → "Renovate" workflow → Run workflow. Useful when you've ju
|
|||||||
|
|
||||||
### Reviewing Renovate PRs
|
### Reviewing Renovate PRs
|
||||||
|
|
||||||
- Each Renovate PR is gated by the same CI as a human PR — `check`, `scan`, `commits`, `perf`, `a11y`. Don't merge until all are green.
|
- Renovate PRs run a leaner CI pipeline than human PRs — `check`, `scan`, `a11y` only. The `perf` and `commits` gates are skipped (per [ADR-0017](decisions/0017-performance-budgets-lighthouse-ci.md) — Lighthouse signal on a dep bump is essentially zero, commitlint on bot-generated messages is tautological). The full `perf` gate still runs on `push` to `main` post-merge, so regressions are caught seconds after merge rather than before.
|
||||||
|
- Don't merge until the remaining gates are green.
|
||||||
- The "Renovate Dependency Dashboard" issue (auto-created on first run) lists every pending update grouped by status. Use it to triage which PRs to expedite.
|
- The "Renovate Dependency Dashboard" issue (auto-created on first run) lists every pending update grouped by status. Use it to triage which PRs to expedite.
|
||||||
- For a major bump that introduces breaking changes, **don't reflexively merge**: read the changelog, then either accept the work or close the PR with a "rejected" label. Renovate respects that label and won't keep re-opening the same major.
|
- For a major bump that introduces breaking changes, **don't reflexively merge**: read the changelog, then either accept the work or close the PR with a "rejected" label. Renovate respects that label and won't keep re-opening the same major.
|
||||||
- **Adding or removing** a dependency belongs in a feature PR, not in Renovate's scope. Renovate only updates _versions_ of existing deps.
|
- **Adding or removing** a dependency belongs in a feature PR, not in Renovate's scope. Renovate only updates _versions_ of existing deps.
|
||||||
|
|||||||
+2
-2
@@ -67,8 +67,8 @@
|
|||||||
"@playwright/test": "^1.36.0",
|
"@playwright/test": "^1.36.0",
|
||||||
"@schematics/angular": "~21.2.0",
|
"@schematics/angular": "~21.2.0",
|
||||||
"@swc-node/register": "1.11.1",
|
"@swc-node/register": "1.11.1",
|
||||||
"@swc/core": "1.15.8",
|
"@swc/core": "1.15.33",
|
||||||
"@swc/helpers": "0.5.18",
|
"@swc/helpers": "0.5.21",
|
||||||
"@tailwindcss/postcss": "^4.2.4",
|
"@tailwindcss/postcss": "^4.2.4",
|
||||||
"@types/jest": "^30.0.0",
|
"@types/jest": "^30.0.0",
|
||||||
"@types/node": "20.19.39",
|
"@types/node": "20.19.39",
|
||||||
|
|||||||
Generated
+255
-233
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user