Commit Graph

7 Commits

Author SHA1 Message Date
Julien Gautier a0ee9fb3ca fix(deps): revert TS6/ESLint10/webpack-cli7 majors and gate future majors
CI / commits (pull_request) Successful in 2m6s
CI / check (pull_request) Successful in 2m33s
CI / a11y (pull_request) Successful in 1m32s
CI / perf (pull_request) Successful in 2m32s
CI / scan (pull_request) Failing after 5m58s
Three Renovate-driven major bumps that landed via `nx affected`
passing trivially (deps-only change → no project flagged as
affected) have been silently breaking the build since they merged:

- **TypeScript 5→6** (#33) — TS6 deprecates `baseUrl`; every lib's
  `tsconfig.lib.json` now fails with `TS5101: Option 'baseUrl' is
  deprecated and will stop functioning in TypeScript 7.0`. Revert
  to TypeScript 5.9.x; we'll revisit when the broader Angular/Nx
  ecosystem aligns on TS6.
- **ESLint 9→10** (#36) — `@nx/eslint@22.7.1` was built against
  ESLint 9 and fails project-graph extraction with `Unable to find
  eslint`. Revert to ESLint 9.x; bring `@eslint/js`,
  `eslint-plugin-playwright`, and `jsonc-eslint-parser` back to
  their ESLint-9-compatible versions in the same revert.
- **webpack-cli 5→7** (#34) — webpack-cli 7 removed the
  `--node-env=production` flag that Nx's webpack target generates,
  breaking `portal-bff:build`. Revert to webpack-cli 5.x; revisit
  when Nx's webpack executor is updated.

The `ajv@<8.18.0` override added in #42 was over-broad: it forced
ESLint's transitively-bundled ajv to v8, which doesn't accept the
legacy options ESLint 9 passes. Narrow the override to
`@angular-devkit/core>ajv@<8.18.0` so only the targeted chain
(nestjs-prisma > @angular-devkit/core > ajv) is bumped, leaving
ESLint's ajv alone.

Verified locally: `pnpm exec nx run-many -t lint test build` is
green on all 8 projects; `pnpm audit --audit-level=moderate`
reports zero vulnerabilities.

To prevent future silent breakages, add a Renovate package rule
that gates **all major updates** behind the dependency dashboard
(`dependencyDashboardApproval: true`). Renovate stops creating PRs
for majors automatically — they appear as checkboxes in the
dashboard, and only get a PR when a human ticks the box. Patch
and minor bumps still flow on the daily cron.

`docs/development.md` "Reviewing Renovate PRs" is updated to
explain the gate and why it exists, citing the three offenders we
caught the hard way.
2026-05-06 22:01:44 +02:00
julien f9ed3cf82a chore(ci): skip perf and commits gates on Renovate-authored PRs (#23)
CI / commits (push) Has been skipped
CI / check (push) Successful in 2m20s
CI / scan (push) Failing after 2m34s
CI / a11y (push) Successful in 1m7s
CI / perf (push) Successful in 3m43s
## Summary
Renovate's dep-bump PRs run the full pipeline today (`check`, `scan`, `commits`, `perf`, `a11y`). Two of those gates have near-zero signal on a typical bump and dominate the wall-clock cost:

- **`perf`** — Lighthouse build + 3-iteration median across the critical-routes list. 3-5 min per PR for a metric that is essentially zero on a patch/minor dep bump (the SPA today serves the static placeholder; even with real routes a typical bump stays inside the median noise floor).
- **`commits`** — re-validates commit messages that Renovate generates from a Conventional-Commits-conformant template. Tautological.

Skip both when the PR author is the `apf-portal-bot` Gitea user. The `push` event on `main` still runs the full pipeline post-merge, so any regression caught by `perf` is detected seconds after merge — fast enough to revert.

Net result: Renovate PRs run `check + scan + a11y` only, ≈ 4-5 min faster per PR.

## ADR amendment

ADR-0017 is amended in the same change:
- "Where Lighthouse CI runs" table now distinguishes human PR / bot PR / push to main / scheduled / local.
- New "Pre-merge gating policy: human PRs vs bot PRs" subsection records the rationale and the human-takeover edge case.
- §Confirmation entry for `perf` is reworded to reflect the conditional gate.

## Test plan
- [ ] After merge, the next Renovate-triggered PR (auto-rebase or new bump) shows only `check`, `scan`, `a11y` queued — no `perf`, no `commits`.
- [ ] A human-opened PR (e.g. this one) still queues all 5 gates.
- [ ] On `push` to `main` post-merge, the full pipeline runs including `perf`.

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #23
2026-05-05 16:12:19 +02:00
julien f58cf13e33 fix(ci): give Renovate a git identity and a github.com token (#13)
CI / check (push) Successful in 2m24s
CI / commits (push) Has been skipped
CI / scan (push) Failing after 1m8s
CI / a11y (push) Successful in 1m32s
CI / perf (push) Successful in 2m52s
## Summary
First successful Renovate run (after the docker-image fix in #12) extracted 116 deps cleanly but every branch update failed with `fatal: empty ident name not allowed`, then the whole repo aborted on `Lock file error - aborting`. Two root causes:

- **No git identity** — the bot user had an email but no **Full Name** on its Gitea profile, so Renovate produced incomplete git authorship.
- **No github.com auth** — Renovate could not look up versions of GitHub-hosted Actions (`actions/checkout`, etc.) or `containerbase/node-prebuild` (the Node binary it dynamically fetches for lockfile maintenance) — anonymous rate limit (60 req/h) hit.

Fixes:

1. **`renovate.json`** — pin `gitAuthor` explicitly. The Full Name was also set on the bot's Gitea profile for UI consistency, but the override in config means we don't depend on out-of-band UI state.
2. **`.gitea/workflows/renovate.yml`** — pass `RENOVATE_GITHUB_COM_TOKEN` from the new `GITHUBCOM_TOKEN` repo secret (no underscore between GITHUB and COM — Gitea reserves the `GITHUB_*` namespace).
3. **`docs/development.md`** — onboarding procedure now covers both tokens + the Full Name step.

## Manual setup required after merge
Already done in this iteration:
- Bot's Full Name set in Gitea ("APF Portal Bot").
- `GITHUBCOM_TOKEN` repo secret created with a zero-scope github.com PAT.

(If the PAT was leaked during setup, regenerate before merging — the workflow only references the secret name, not the value.)

## Test plan
- [ ] After merge, trigger Renovate manually (Actions → Renovate → Run workflow).
- [ ] No `empty ident name` warning in the logs.
- [ ] No `Lock file error - aborting`; repo finishes with `INFO: Repository finished … "cloned": true`.
- [ ] Renovate creates the dependency dashboard issue + the first batch of grouped PRs (Angular, Nx, NestJS, Prisma, …) signed by `apf-portal-bot`.

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #13
2026-05-05 13:47:30 +02:00
julien 82911f9319 chore(ci): set up Renovate dependency automation (#11)
CI / commits (push) Has been skipped
CI / check (push) Successful in 1m21s
CI / scan (push) Failing after 1m27s
CI / a11y (push) Successful in 44s
CI / perf (push) Successful in 2m28s
## Summary
Wire up Renovate to keep dependencies fresh without manual triage.

- **Workflow** — `.gitea/workflows/renovate.yml`: cron daily at 03:00 UTC + `workflow_dispatch`, runs on the existing self-hosted runners. Picked 03:00 specifically so Monday's tick sits inside Renovate's default `lockFileMaintenance.schedule` ("before 4am Monday") and triggers the weekly lockfile refresh in passing.
- **Config** — `renovate.json`: `config:recommended` baseline + groupings (Angular, Nx, NestJS, Prisma, Vitest, TypeScript tooling, ESLint, SWC, Tailwind), Conventional-Commits commit messages, OSV.dev as vulnerability source, dependency dashboard issue.
- **Docs** — new §5 in `docs/development.md` covering the bot onboarding (manual, one-shot), how to trigger Renovate manually, how to review its PRs. The placeholder roadmap entry is dropped from §8.

No ADR — Renovate is operational tooling, not an architectural decision (and on Gitea it's the only viable bot anyway, no real alternative to capture).

## Manual setup required after merge

The workflow is wired but inert until the bot is onboarded once on Gitea:

1. Create a non-admin Gitea user `apf-portal-bot`.
2. Add the bot as a **Write** collaborator on this repo.
3. Sign in as the bot, generate a PAT (scopes: read/write `repository`, read/write `issue`, read `user`).
4. Add the PAT as the repo secret `RENOVATE_TOKEN` (Settings → Actions → Secrets).

Detailed steps in [`docs/development.md`](docs/development.md) → "Dependency updates (Renovate)".

## Test plan
- [ ] After bot onboarding, trigger the workflow manually (Repo → Actions → Renovate → Run workflow).
- [ ] First run creates the "Renovate Dependency Dashboard" issue and a batch of grouped PRs (Angular, Nx, …).
- [ ] Each generated PR has CI green (`check`, `scan`, `commits`, `perf`, `a11y`).
- [ ] Commit subject matches `chore(deps): …` / `fix(deps): …` so the `commits` gate doesn't reject.

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #11
2026-05-04 17:37:13 +02:00
Julien Gautier 156e7ca2df chore: add PR template and document title/body convention
CI / check (push) Failing after 5s
CI / commits (push) Has been skipped
CI / scan (push) Failing after 6s
CI / perf (push) Failing after 3s
CI / a11y (push) Failing after 1s
Formalise the PR-flow conventions while we install the PR-flow itself.

.gitea/pull_request_template.md auto-populates the PR body in Gitea
with five sections: Summary / Motivation / Implementation notes /
Verification (with CI-gate checkboxes + ADR/diagram update flags) /
Related. Sections can be left blank when irrelevant; the template
guides without adding ceremony. Header HTML comment reminds the
contributor of the PR title format and links to the full convention.

docs/development.md §5 (Conventional commit cycle) gains a 'PR
conventions' subsection that:
- explains why the PR title format matters (squash-merge subject on
  main, validated by commitlint in the CI 'commits' job)
- separates feature-branch commit hygiene (exploratory OK) from PR
  title hygiene (must conform)
- documents the type vocabulary (feat/fix/docs/style/refactor/perf/
  test/build/ci/chore/revert)
- proposes an optional scope vocabulary (apps, libs, cross-cutting
  domains like decisions/docs/ci/deps)
- describes the body template

No new ADR. The PR title format is derived from ADR-0007 (Conventional
Commits at the commit-msg layer) plus ADR-0015 (squash-merge means PR
title becomes the commit subject on main). The body template is
tactical guidance, not architectural.
2026-04-30 23:03:13 +02:00
Julien Gautier 7d27cd8773 docs: turn development.md §7 into a phase-mapped roadmap
CI / check (push) Failing after 2s
CI / commits (push) Has been skipped
CI / perf (push) Failing after 12s
CI / a11y (push) Failing after 3s
CI / scan (push) Failing after 1m33s
The section was a short bullet list of 'sections to be added' - it
underplayed how broad the future content really is, and gave no
visibility on what triggers each. Replace it with a structured table
that maps every planned section to (a) its ADR phase and (b) the
specific implementation work that unlocks it. A contributor reading
the doc today now sees:

- which dev-loops will exist (auth, sessions, MFA step-up, OTel,
  audit, downstream APIs, component patterns, a11y, perf debugging,
  Renovate, release, GitLab migration, architecture diagrams)
- under which ADR each lands
- what concrete event in the codebase makes each section real

Plus the explicit policy: each entry stays a subsection of this doc
until we have at least three substantial sub-topics, at which point
the file is split into docs/development/ with an index. Avoids
creating empty placeholder files (per CLAUDE.md: 'documentation when
genuinely useful, not just to tick a box') while signalling the
future structure clearly.

Cross-references each row to its triggering ADR so the table doubles
as a 'what's pending implementation' radar. Foreshadows the §7 → file
split that will happen once content density justifies it.
2026-04-30 20:11:01 +02:00
Julien Gautier b69d3a2206 docs: add development.md as the day-to-day reference for working on apf_portal
CI / check (push) Failing after 2s
CI / commits (push) Has been skipped
CI / perf (push) Failing after 12s
CI / a11y (push) Failing after 2s
CI / scan (push) Failing after 1m44s
A new contributor (or returning lead) opening the repo gets:
- the final repo layout, with one-line annotations per top-level dir
- the prerequisite tooling list (Node 24 LTS, pnpm 10, mkcert,
  optional local Trivy/gitleaks, Docker for Postgres)
- the fresh-clone setup steps (clone, pnpm install, prisma generate,
  sanity check)
- the daily commands organised by intent: serve, test (incl. single
  file), lint, build, generate (apps / libs / components), Prisma,
  the four ci:* scripts that mirror the CI gates
- the conventional commit cycle end-to-end (branch naming, hook
  enforcement, PR gates, squash-merge, release tagging)
- a 'where to look' table cross-linking the project rules
  (CLAUDE.md), the ADRs, the setup guides, and the personal notes
- an explicit 'to be added' section listing what the doc will grow
  into (local infra Docker Compose, auth dev-loop, component
  patterns, debugging tips, release workflow, Renovate policy)

The doc is intentionally non-exhaustive at v1 - it captures what a
contributor needs today and is structured to grow as the workflow
sharpens. Indexed in docs/README.md under a new 'Daily development'
section, separate from the one-off onboarding guides under
docs/setup/.
2026-04-30 19:58:37 +02:00