-
Notifications
You must be signed in to change notification settings - Fork 2
172 lines (159 loc) · 6.81 KB
/
Copy pathchecks.yml
File metadata and controls
172 lines (159 loc) · 6.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
name: Checks
on:
push:
branches: [main]
# `ready_for_review` is NOT in the default type set (opened, synchronize,
# reopened), and without it a pull request opened as a draft never gets its
# auto-approval: `pr-quality`'s auto-approve job is gated on
# `github.event.pull_request.draft == false`, so it skips while the PR is a
# draft and nothing re-runs it when the draft is lifted. The PR then sits at
# `reviewDecision: REVIEW_REQUIRED` with nothing red, and the merge tooling
# reports the Copilot review quota — true, and not the cause.
#
# The Go templates already carry this type set in their own pr-quality.yml;
# this template folded that job into `checks.yml` and lost it on the way.
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
merge_group:
schedule:
- cron: '0 6 * * 1'
permissions: {}
# Security + quality jobs with their explicit per-call-site permissions. This
# file is byte-identical and drift-enforced across every typo3-extension — the
# extension-specific test matrix lives in ci.yml (intentional-drift). Every
# `uses:` job grants exactly the reusable's caller contract; no reliance on
# default_workflow_permissions.
#
# ANY JOB ADDED BELOW MUST ALSO BE ADDED TO `gate.needs`. The gate is the only
# context a ruleset requires, so a job missing from that list is a job whose
# failure cannot block a merge — the coverage loss is silent, and nothing in CI
# catches it. GitHub Actions does not support YAML anchors in workflow files,
# so the list cannot be shared with the job definitions; it has to be kept in
# step by hand.
jobs:
security:
# Ran on this SHA already; lifting a draft changes no code (see `on:`).
if: github.event.action != 'ready_for_review'
uses: netresearch/typo3-ci-workflows/.github/workflows/security.yml@main
permissions:
contents: read
security-events: write
gitleaks:
# Ran on this SHA already; lifting a draft changes no code (see `on:`).
if: github.event.action != 'ready_for_review'
uses: netresearch/.github/.github/workflows/gitleaks.yml@main
permissions:
contents: read
security-events: write
zizmor:
# Ran on this SHA already; lifting a draft changes no code (see `on:`).
if: github.event.action != 'ready_for_review'
uses: netresearch/.github/.github/workflows/zizmor.yml@main
permissions:
contents: read
security-events: write
fuzz:
# Ran on this SHA already; lifting a draft changes no code (see `on:`).
if: github.event.action != 'ready_for_review'
uses: netresearch/typo3-ci-workflows/.github/workflows/fuzz.yml@main
permissions:
contents: read
license-check:
# Ran on this SHA already; lifting a draft changes no code (see `on:`).
if: github.event.action != 'ready_for_review'
uses: netresearch/typo3-ci-workflows/.github/workflows/license-check.yml@main
permissions:
contents: read
# `auto` rather than the `actions` default: a TYPO3 extension that ships
# JavaScript had none of it analysed, because the default scans workflows
# only and GitHub disables code-scanning default setup — which did cover
# javascript-typescript — as soon as an advanced configuration uploads its
# first SARIF. Merging this file is what triggers that handover, so the
# narrow default silently removed a control that had been in place.
codeql:
# Ran on this SHA already; lifting a draft changes no code (see `on:`).
if: github.event.action != 'ready_for_review'
uses: netresearch/.github/.github/workflows/codeql.yml@main
permissions:
contents: read
security-events: write
actions: read
with:
languages: auto
scorecard:
if: github.event_name == 'schedule' || (github.event_name == 'push' && github.ref_name == github.event.repository.default_branch)
uses: netresearch/.github/.github/workflows/scorecard.yml@main
permissions:
contents: read
security-events: write
id-token: write
actions: read
dependency-review:
if: github.event_name == 'pull_request'
uses: netresearch/.github/.github/workflows/dependency-review.yml@main
permissions:
contents: read
pull-requests: write
pr-quality:
if: github.event_name == 'pull_request'
uses: netresearch/.github/.github/workflows/pr-quality.yml@main
permissions:
contents: read
pull-requests: write
# One stable check name for this workflow, so a branch ruleset has something
# it can require on EVERY event.
#
# Requiring the individual job checks breaks a merge queue. Two of the jobs
# above are pull-request-only by nature — `dependency-review` compares the
# dependency delta of a pull request, `pr-quality` inspects its title, body
# and author — and a `uses:` job whose `if:` is false is skipped WITHOUT
# materialising the called workflow's job names, so `dependency-review /
# Dependency Review` and `pr-quality / Quality Gate` simply never appear on a
# merge_group ref. A ruleset requiring them holds every queue entry until
# `check_response_timeout_minutes` expires and then dequeues it. Measured
# 2026-08-05 on netresearch/t3x-nr-llm: a pull request sat in the queue past
# the 60-minute timeout waiting for contexts that cannot arrive.
#
# The same is true of the code-scanning checks (`CodeQL`, `betterleaks`,
# `zizmor`, `Opengrep OSS`): those are posted by the github-advanced-security
# app against the pull request, not by these jobs, so they are not requirable
# for a queue either. Require `All security checks` instead — it depends on
# every job here and its name does not change with the event.
gate:
name: All security checks
needs:
- security
- gitleaks
- zizmor
- fuzz
- license-check
- codeql
- scorecard
- dependency-review
- pr-quality
if: ${{ always() }}
runs-on: ubuntu-latest
timeout-minutes: 2
permissions: {}
steps:
- name: Harden Runner
uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
with:
egress-policy: audit
# `skipped` passes: a job that does not apply to this event has nothing
# to say about the commit. Only `failure` and `cancelled` fail the gate.
- name: Fail unless every job succeeded or was skipped
shell: bash
env:
RESULTS: ${{ toJSON(needs) }}
run: |
bad=$(jq -r '
to_entries[]
| select(.value.result != "success" and .value.result != "skipped")
| "\(.key)=\(.value.result)"' <<<"$RESULTS")
if [ -n "$bad" ]; then
echo "::error::Security checks gate failed — $(tr "\n" " " <<<"$bad")"
exit 1
fi
jq -r 'to_entries[] | " \(.key): \(.value.result)"' <<<"$RESULTS"
echo "All jobs succeeded or were skipped."