mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-10 10:06:15 -08:00
Pipeline audit follow-up: reduce wasted runner time on PRs and tighten CI security, without reducing what actually gets validated. Runner-time waste: - Concurrency with PR-only cancel-in-progress on CI, E2E, and docker-build, so a new push cancels the previous commit's still-running checks. Non-PR runs use the unique run_id as the group, because GitHub keeps at most one pending run per group even with cancel-in-progress: false — a shared ref group could silently drop a queued master run. - paths-ignore for docs-only changes (Markdown, docs/, .plans/, .codex/, .claude/) on the Electron build matrix and the E2E suites; E2E also skips apps/website/**. The build workflow keeps apps/website/** because its Linux job builds the website to verify AppStream assets. Tag pushes are unaffected: GitHub does not evaluate paths filters for tags. - PRs lint affected projects only; master pushes keep the full run-many. Lint-global inputs (eslint.config.mjs, tools/eslint/**) now mark all 41 lint projects affected, including the run-commands targets database and packaging, so the max-lines baseline cannot be widened without lint. Hardening: - Explicit least-privilege permissions on CI, E2E, and build-and-make; the create-release job keeps its job-level contents: write. The repository default workflow token was switched to read-only. - New actionlint job (image pinned by digest, shellcheck at warning+), with the shared-anchor false positive suppressed in .github/actionlint.yaml. Fixed one real finding: unquoted $GITHUB_OUTPUT. - .github/dependabot.yml: weekly cadence, minor+patch grouped per ecosystem (npm, GitHub Actions, Docker), majors stay individual PRs. Docs updated: CLAUDE.md, docs/architecture/nx-workspace-boundaries.md, and docs/architecture/validation-map.md now describe affected-lint on PRs and the E2E path-filter exceptions.
129 lines
5.3 KiB
Markdown
129 lines
5.3 KiB
Markdown
# Validation Map
|
|
|
|
This map records the lowest-cost validation commands agents should reach for
|
|
before broad CI-sized runs.
|
|
|
|
## Discovery
|
|
|
|
```bash
|
|
pnpm nx show projects --withTarget test
|
|
pnpm nx show projects --withTarget lint
|
|
pnpm nx show projects --withTarget e2e
|
|
```
|
|
|
|
## Unit And Type Checks
|
|
|
|
| Area | Command |
|
|
| ---------------------------------- | ----------------------------------- |
|
|
| Angular renderer entry points | `pnpm run typecheck:web` |
|
|
| Electron main process entry points | `pnpm run typecheck:backend` |
|
|
| Full unit suite (all projects) | `pnpm run test:unit:ci` |
|
|
| EPG data access | `pnpm nx test epg-data-access` |
|
|
| Workspace shell utilities | `pnpm nx test workspace-shell-util` |
|
|
| Shared SQLite schema/connection | `pnpm nx test database` |
|
|
| Packaging metadata | `pnpm nx test packaging` |
|
|
|
|
## Lint
|
|
|
|
```bash
|
|
pnpm run lint # nx run-many --target=lint --all
|
|
pnpm nx lint <project> # single project
|
|
```
|
|
|
|
The CI workflow (`.github/workflows/ci.yml`) lints affected projects on PRs
|
|
(`nx affected`) and every project on master pushes.
|
|
This enforces `@nx/enforce-module-boundaries` (scope/domain/type tag
|
|
constraints), the legacy bare-alias ban, and the `max-lines` file-size rule
|
|
(hard maximum 400 lines per TypeScript file). Files that predate the
|
|
`max-lines` rule are baselined in `tools/eslint/max-lines-baseline.mjs`; after
|
|
splitting a baselined file below the limit, regenerate the list with
|
|
`node tools/eslint/generate-max-lines-baseline.mjs`. Never add new files to
|
|
the baseline.
|
|
|
|
## Coverage Tiers
|
|
|
|
Use `tools/coverage/coverage-policy.json` as the source of truth for coverage
|
|
ownership. Every project with a `test` target must be classified in a tier;
|
|
`pnpm run coverage:policy:check` (part of `coverage:ci`) fails CI when a new
|
|
project is missing from the policy, a listed project no longer exists, or a
|
|
Tier A entry has no test target. CI runs Tier A with coverage (uploaded to
|
|
Codecov) and each Tier B/C project's `validationCommand` (falling back to
|
|
`nx test`) without coverage; projects with an `e2e` target are skipped there
|
|
because the E2E workflow already runs them on every PR that touches app code.
|
|
Docs-only changes (Markdown, `docs/`, `.plans/`, `.codex/`, `.claude/`) and
|
|
`apps/website/**` changes skip the E2E workflow via `paths-ignore` — for those
|
|
PRs no E2E validation runs in CI, which is intentional: they cannot affect app
|
|
behavior.
|
|
|
|
| Tier | Rule | Validation |
|
|
| --- | --- | --- |
|
|
| A | Product/runtime Angular, Electron, backend, data-access, portal, playlist, workspace, playback, EPG, and shared UI code collects source coverage. | `pnpm run coverage:ci` |
|
|
| B | Validate behavior without percentage coverage, such as `website`, `packaging`, and Playwright E2E projects. | `pnpm nx test website`, `pnpm nx test packaging`, or the closest E2E target |
|
|
| C | Excluded from the source coverage baseline, such as mock servers, test helper libraries, and untested feature shells. | Validate through dependent flows, or add focused tests when changing behavior directly |
|
|
|
|
`apps/website` is an Astro marketing site. Its useful signal is a successful
|
|
static build plus targeted output checks, not a merged code coverage percentage.
|
|
Projects with a test target but no specs, such as `remote-control-web` and
|
|
`remote-control` today, should not be in Tier A until focused specs exist.
|
|
|
|
For local coverage inspection:
|
|
|
|
```bash
|
|
pnpm run coverage:unit:ci
|
|
pnpm run coverage:merge
|
|
pnpm run coverage:health
|
|
```
|
|
|
|
The merged report is written to `coverage/merged/` as HTML, LCOV, Cobertura,
|
|
and JSON summary output. CI uploads the merged Tier A report to Codecov with the
|
|
`unit` flag and keeps the HTML report as a GitHub artifact.
|
|
|
|
## E2E
|
|
|
|
| Area | Command |
|
|
| --------------------- | ----------------------------------------------- |
|
|
| Web app browser flows | `pnpm nx run web-e2e:e2e -- --project=chromium` |
|
|
| Electron flows | `pnpm nx run electron-backend-e2e:e2e` |
|
|
|
|
Use atomized E2E targets when available, for example
|
|
`pnpm nx run web-e2e:e2e-ci--src/xtream.e2e.ts`.
|
|
|
|
Playwright coverage is measured semantically by tags and critical journeys, not
|
|
by a source-line percentage. E2E reports should use tags such as `@critical`,
|
|
`@electron`, `@web`, `@xtream`, `@stalker`, `@m3u`, `@search`, `@epg`,
|
|
`@persistence`, `@settings`, `@pwa`, and `@self-hosted`.
|
|
|
|
After an E2E run, generate the semantic summary with:
|
|
|
|
```bash
|
|
pnpm run coverage:e2e:summary
|
|
```
|
|
|
|
For local investigation only, Chromium browser V8 coverage can be explored with:
|
|
|
|
```bash
|
|
pnpm run coverage:e2e:v8:web
|
|
```
|
|
|
|
## I18n
|
|
|
|
```bash
|
|
pnpm run i18n:check
|
|
```
|
|
|
|
The i18n check is non-mutating. It compares every locale file in
|
|
`apps/web/src/assets/i18n/` against `en.json` and fails on missing or extra keys.
|
|
Identical English fallback values are reported as warnings by default; use
|
|
`node tools/i18n/check-drift.mjs --fail-on-identical` for a stricter translation
|
|
audit.
|
|
|
|
## Logging
|
|
|
|
Runtime playback and EPG debug logs should use the existing logger or trace
|
|
helpers instead of unconditional `console.log`. Electron external-player traces
|
|
are gated by:
|
|
|
|
```bash
|
|
IPTVNATOR_TRACE_PLAYER=1 pnpm run serve:backend
|
|
```
|