Supersedes the three individual Dependabot PRs (#1249, #1245, #1247) so the
pinned-SHA contract stays consistent in one commit.
actions/checkout v4 -> v7, actions/upload-artifact v4 -> v7 and
actions/download-artifact v4 -> v8 across every workflow. docker.yml moves
from checkout v6 to v7 with the rest.
publish-snap.yaml keeps full-commit pins, so the three new SHAs are updated
there and in the packaging policy tests that assert them
(snap-workflow-policy.test-helpers.mjs, publish-snap-workflow.test.mjs,
release-snap-assets.test.mjs). Each SHA was checked against the upstream tag
refs: checkout 3d3c42e5 = v7.0.1, upload-artifact 043fb46d = v7.0.1,
download-artifact 3e5f45b2 = v8.0.1. BUILD_ACTION_ALLOWLIST follows the
unpinned bumps in build-and-make.yaml.
download-artifact v8 changes two behaviours that matter for the Snap publish
path, both in our favour: an artifact digest mismatch now fails the run
instead of logging a warning, and the action only unzips responses whose
Content-Type says zip. The publish job downloads a normal upload-artifact
artifact by name, so decompression is unchanged, and it re-verifies the
receipt digest itself regardless.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Two independent CI failures on master:
1. `Check i18n drift` failed with 3 keys missing from `hu.json`
(`SETTINGS.PLAYER_UP_NEXT_RAIL`, `SETTINGS.PLAYER_UP_NEXT_RAIL_DESCRIPTION`,
`PORTALS.UP_NEXT`). PR #1231 added them to every locale, but its branch
predates the Hungarian locale merged in #1236, so `hu.json` never got them.
Both PRs were green in isolation. The failure also aborted the job before
the Tier A/B/C unit suites ran. Added the keys with real Hungarian
translations rather than English fallbacks.
2. CodeQL has failed on every master push for days. The analysis itself
completes; only the SARIF upload fails with "Resource not accessible by
integration" because the workflow has no `permissions:` block and the
default token is read-only. Added the standard grant.
While in that workflow: bumped `actions/checkout` v3 -> v4 (matches every other
workflow here) and dropped the obsolete `git checkout HEAD^2` step — the old
template's PR-head trick that current codeql-action handles itself, and the
only reason `fetch-depth: 2` was needed.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>