Skip to content

[FEATURE] Add CI gate for the shared reusable workflows (lint, security, conformance, freshness)#16

Merged
linawolf merged 3 commits into
TYPO3-Documentation:mainfrom
CybotTM:task/ci-lint-gate
Jul 7, 2026
Merged

[FEATURE] Add CI gate for the shared reusable workflows (lint, security, conformance, freshness)#16
linawolf merged 3 commits into
TYPO3-Documentation:mainfrom
CybotTM:task/ci-lint-gate

Conversation

@CybotTM

@CybotTM CybotTM commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a CI gate to this repository so every PR and push to main validates the shared reusable workflows — beyond lint, it now also covers security, conformance and freshness. This implements the mitigation called out in ADR-003 (#6): consumer repositories reference these workflows at @main, so a broken or compromised merge here immediately affects every consumer repo. Until now this repository had no PR-triggered CI at all.

What the gate checks

Job Tool Coverage
actionlint rhysd/actionlint 1.7.12, binary download verified against the published sha256 Workflow syntax, workflow_call input references, expression types, action with: validation, shellcheck on all run: blocks
yamllint yamllint 1.38.0, --strict YAML conformance of .github/ per the committed .yamllint.yml
zizmor zizmor 1.26.1 Security audit: template injection, credential persistence (artipacked), GitHub App token misuse, Dependabot cooldown, online audits (ref confusion, impostor commits) via GITHUB_TOKEN
conformance .github/scripts/check_conformance.py README workflow table ↔ files in sync (both directions), workflow_call-only triggers, every input documented

All Python tools are hash-locked in .github/requirements.txt (installed with pip --require-hashes --only-binary :all:), and a new .github/dependabot.yml keeps both the action SHA pins and the tool versions current (weekly, 7-day cooldown against hijacked-release windows).

Commits

  1. [BUGFIX] — pre-existing conformance findings on main, so the gate is green from day one: unquoted $(pwd) in reusable-test-documentation.yml (SC2046), missing trailing newlines in reusable-backport.yml / reusable-apply-precommit.yml.
  2. [TASK] — security hardening from the zizmor audit: persist-credentials: false on all read-only checkouts; job-level permissions: contents: read added to reusable-test-documentation.yml (the only workflow that had none); composer-args / render-flags moved to env-var indirection (no template expansion into scripts); justified inline ignores for command-style inputs (code by contract, set in the calling repo's committed workflow) and for the two write workflows whose credential handling must not be changed blind (see follow-ups).
  3. [FEATURE] — the gate itself (4 jobs), .yamllint.yml, hash-locked requirements, conformance script, Dependabot config, README "Quality gate" section.

Independent review round

Three independent reviewers (code, security, runtime) were run over this PR and #15. Their confirmed findings are incorporated: the consumer contract for command-style inputs is now documented in the README (static literals only, never github.event.* data), the conformance script accepts all valid on: forms (scalar/list/mapping), the README no longer over-claims Dependabot coverage for the curl-installed actionlint binary (bumped manually, noted in ci.yml), and #15 was hardened to pass this gate in any merge order. Deliberately rejected: scoping the backport App token in this PR (the pinned create-github-app-token@v1 predates permission-* support validation — remains a tracked follow-up to do together with the v3 migration).

Verification

All four checks run locally green against this branch (zizmor: “No findings”, both offline and with a token for the online audits), against #15's reusable-node-command.yml, and against a simulated merged tree of both PRs (conformance: 8 workflows checked) — the gate stays green in any merge order.

Deliberately not in this PR (follow-ups)

  • Behavioral smoke tests: a job invoking reusable-node-command.yml via a local uses: ./.github/workflows/... reference (works only after [TASK] Add reusable Node command workflow #15 merges); the PHP reusables need a small fixture project and/or a working-directory input first.
  • Backport token modernization: reusable-backport.yml still uses create-github-app-token@v1 without permission scoping (zizmor github-app, currently ignore-listed with justification) — migrate to the v3.2.0 + permission-* pattern already used by reusable-apply-precommit.yml, coordinated with consumer secrets.
  • apply-precommit credential validation: confirm peter-evans/create-pull-request pushes purely via its token input, then set persist-credentials: false there too.
  • Required status checks: mark the four jobs required via branch protection / ruleset (admin permission) — completes the ADR-003 mitigation.

…lows

Quote $(pwd) in reusable-test-documentation.yml (SC2046) and add
missing trailing newlines in reusable-backport.yml and
reusable-apply-precommit.yml.

Signed-off-by: Sebastian Mendel <github@sebastianmendel.de>
@CybotTM CybotTM force-pushed the task/ci-lint-gate branch 3 times, most recently from 9ddc0e6 to c49df78 Compare July 4, 2026 10:21
CybotTM added 2 commits July 4, 2026 12:56
Set persist-credentials: false on all read-only checkouts, add the
missing job-level permissions block to reusable-test-documentation.yml,
move the flag-style inputs composer-args and render-flags to
environment variable indirection, and add justified inline zizmor
ignores for command-style inputs (code by contract from the calling
repository) and for the two write workflows whose credential handling
must not change without validation (backport, apply-precommit).

Signed-off-by: Sebastian Mendel <github@sebastianmendel.de>
Every push and PR now runs four checks over the shared workflows:
actionlint (syntax, expressions, shellcheck; checksum-pinned binary),
yamllint in strict mode, zizmor (security audit: template injection,
credential persistence, token misuse), and a conformance script that
keeps the README workflow table, workflow_call triggers and input
documentation in sync. Python tools are hash-locked in
.github/requirements.txt; Dependabot (new) keeps action pins and tool
versions current with a 7-day cooldown. The README documents the
consumer contract that command-style inputs must be static literals.

This implements the mitigation required by ADR-003: consumers
reference these workflows at @main, so main must stay reliable.

Signed-off-by: Sebastian Mendel <github@sebastianmendel.de>
@CybotTM CybotTM force-pushed the task/ci-lint-gate branch from c49df78 to 5b4531e Compare July 4, 2026 10:56
@CybotTM CybotTM changed the title [FEATURE] Add CI lint gate for the shared reusable workflows [FEATURE] Add CI gate for the shared reusable workflows (lint, security, conformance, freshness) Jul 4, 2026

@linawolf linawolf left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes make sense to me as far as I can tell

@linawolf linawolf merged commit 559a564 into TYPO3-Documentation:main Jul 7, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants