github-security-report 0.15.0__tar.gz → 0.17.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {github_security_report-0.15.0 → github_security_report-0.17.0}/PKG-INFO +209 -14
- {github_security_report-0.15.0 → github_security_report-0.17.0}/README.md +206 -11
- {github_security_report-0.15.0 → github_security_report-0.17.0}/pyproject.toml +4 -4
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/_version.py +2 -2
- github_security_report-0.17.0/src/github_security_report/categories/__init__.py +92 -0
- github_security_report-0.17.0/src/github_security_report/categories/keys.py +76 -0
- github_security_report-0.17.0/src/github_security_report/categories/signals.py +113 -0
- github_security_report-0.17.0/src/github_security_report/categories/tables.py +244 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/cli/app.py +35 -5
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/cli/modes.py +97 -4
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/cli/outputs.py +55 -12
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/cli/publish.py +4 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/cli/serialise.py +4 -0
- github_security_report-0.17.0/src/github_security_report/client/codeql_parsers.py +129 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/client/org_reads.py +5 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/client/parsers.py +5 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/client/queries.py +12 -3
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/client/reads.py +143 -1
- github_security_report-0.17.0/src/github_security_report/client/writes.py +284 -0
- github_security_report-0.17.0/src/github_security_report/codeql/__init__.py +50 -0
- github_security_report-0.17.0/src/github_security_report/codeql/cleanup.py +123 -0
- github_security_report-0.17.0/src/github_security_report/codeql/facts.py +277 -0
- github_security_report-0.17.0/src/github_security_report/codeql/tables.py +253 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/collect/__init__.py +6 -0
- github_security_report-0.17.0/src/github_security_report/collect/codeql.py +66 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/collect/extras.py +28 -15
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/collect/org.py +19 -51
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/collect/protocols.py +15 -0
- github_security_report-0.17.0/src/github_security_report/collect/scoping.py +122 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/config/loader.py +12 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/config/models.py +27 -1
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/config/schema.py +63 -36
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/layout.py +14 -28
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/models.py +6 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/ordering.py +13 -16
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/posture/__init__.py +2 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/posture/enablement.py +29 -4
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/posture/facts.py +2 -0
- github_security_report-0.15.0/src/github_security_report/remediate.py → github_security_report-0.17.0/src/github_security_report/remediate/__init__.py +115 -101
- github_security_report-0.17.0/src/github_security_report/remediate/codeql.py +99 -0
- github_security_report-0.17.0/src/github_security_report/remediate/model.py +154 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/render/html.py +29 -16
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/render/markdown.py +34 -22
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/render/slack.py +45 -30
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/render/terminal.py +68 -63
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/report/__init__.py +10 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/report/aggregate.py +69 -1
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/report/display.py +47 -1
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/report/tables.py +63 -5
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/scope.py +69 -2
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/summary.py +50 -3
- github_security_report-0.15.0/src/github_security_report/categories.py +0 -384
- github_security_report-0.15.0/src/github_security_report/client/writes.py +0 -136
- {github_security_report-0.15.0 → github_security_report-0.17.0}/.gitignore +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/LICENSE +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/LICENSES/Apache-2.0.txt +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/scripts/README.md +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/__init__.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/authors.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/classify.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/cli/__init__.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/cli/__main__.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/cli/boundary.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/cli/options.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/client/__init__.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/client/alerts.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/client/batch_errors.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/client/copilot.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/client/endpoints.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/client/errors.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/client/reviews.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/client/transport.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/collect/context.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/collect/repo.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/config/__init__.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/config/order.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/gating.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/gitctx.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/issues.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/posture/releases.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/pulls/__init__.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/pulls/columns.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/pulls/counting.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/pulls/presentation.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/pulls/table.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/py.typed +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/ranking.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/render/__init__.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/render/slack_limits.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/report/signals.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/rulesets.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/runner.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/secret_patterns.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/severity.py +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/templates/index.html.j2 +0 -0
- {github_security_report-0.15.0 → github_security_report-0.17.0}/src/github_security_report/templates/report.html.j2 +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: github-security-report
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.17.0
|
|
4
4
|
Summary: Security and quality reporting across GitHub organisations
|
|
5
5
|
Project-URL: Homepage, https://github.com/lfreleng-actions/github-security-report-action
|
|
6
6
|
Project-URL: Repository, https://github.com/lfreleng-actions/github-security-report-action
|
|
@@ -36,8 +36,8 @@ Requires-Dist: pytest-asyncio==1.4.0; extra == 'dev'
|
|
|
36
36
|
Requires-Dist: pytest-cov==7.1.0; extra == 'dev'
|
|
37
37
|
Requires-Dist: pytest==9.1.1; extra == 'dev'
|
|
38
38
|
Requires-Dist: respx==0.23.1; extra == 'dev'
|
|
39
|
-
Requires-Dist: ruff==0.16.
|
|
40
|
-
Requires-Dist: syrupy==6.
|
|
39
|
+
Requires-Dist: ruff==0.16.8; extra == 'dev'
|
|
40
|
+
Requires-Dist: syrupy==6.1.1; extra == 'dev'
|
|
41
41
|
Requires-Dist: types-jsonschema==4.26.0.20260518; extra == 'dev'
|
|
42
42
|
Requires-Dist: types-pyyaml==6.0.12.20250915; extra == 'dev'
|
|
43
43
|
Description-Content-Type: text/markdown
|
|
@@ -101,6 +101,33 @@ if you want to probe everything regardless.
|
|
|
101
101
|
Further sections report **configuration posture** and **freshness** as plain
|
|
102
102
|
tables (org mode):
|
|
103
103
|
|
|
104
|
+
- **CodeQL scan health** — two tables beneath **CodeQL: Results/Findings** (the
|
|
105
|
+
CodeQL alerts table), whose "Clean" says nothing about whether CodeQL is
|
|
106
|
+
still running:
|
|
107
|
+
- **Stale Configurations** lists every CodeQL configuration whose last scan
|
|
108
|
+
trails the default branch's newest commit by more than
|
|
109
|
+
`codeql_stale_days` (default 30) — the condition GitHub's tool status page
|
|
110
|
+
flags as *"Code Scanning results may be out of date"*. Each row names the
|
|
111
|
+
setup type (**Default**, GitHub-managed; or **Advanced**, a workflow in the
|
|
112
|
+
repository), the language, the last *successful* scan, and the cause:
|
|
113
|
+
analyses failing (a run that errors still uploads, but its results do not
|
|
114
|
+
count as a scan), default setup switched off, a workflow removed or
|
|
115
|
+
disabled, or an advanced workflow
|
|
116
|
+
**superseded** by default setup (GitHub rejects advanced CodeQL uploads
|
|
117
|
+
while default setup is on). An *orphaned* configuration will never scan
|
|
118
|
+
again; delete it from the tool status page once the live setup covers its
|
|
119
|
+
language.
|
|
120
|
+
- **Language Coverage** lists repositories where GitHub detects a
|
|
121
|
+
CodeQL-supported language that no current configuration scans — typically
|
|
122
|
+
an advanced workflow whose language matrix omits one the repository
|
|
123
|
+
contains, such as `actions` for its own workflows. On default setup GitHub
|
|
124
|
+
reports only the languages it is set to scan, so a detected language
|
|
125
|
+
deliberately left out of default setup is not visible to this check.
|
|
126
|
+
|
|
127
|
+
Both consider only repositories where CodeQL has run at least once; the rest
|
|
128
|
+
already appear in the Results/Findings not-enabled list. Finding a stale
|
|
129
|
+
configuration means reading each repository's whole CodeQL analysis history,
|
|
130
|
+
since GitHub cannot filter it by configuration.
|
|
104
131
|
- **Dependabot** — three tables: repositories with vulnerability **alerts not
|
|
105
132
|
enabled**, repositories with **security updates not enabled**, and ecosystems
|
|
106
133
|
with no update `cooldown` configured (mandatory; any value passes).
|
|
@@ -118,6 +145,20 @@ tables (org mode):
|
|
|
118
145
|
exposes no org-wide or GraphQL equivalent) and, like every other category,
|
|
119
146
|
always collected; hide it with the `private_vulnerability_reporting` render
|
|
120
147
|
toggle.
|
|
148
|
+
- **Auto-merge** — repositories where the **Allow auto-merge** setting is off,
|
|
149
|
+
so a pull request cannot be queued to merge itself once its requirements are
|
|
150
|
+
met. The setting only offers the option: an auto-merging pull request still
|
|
151
|
+
waits for the required checks, reviews and branch protections the repository
|
|
152
|
+
already enforces, so enabling it relaxes nothing. What it removes is the
|
|
153
|
+
interval between a change becoming mergeable and somebody noticing — the
|
|
154
|
+
window a reviewed dependency update sits in while the vulnerability it fixes
|
|
155
|
+
stays unpatched. Read from the batched GraphQL prefetch, so it costs no extra
|
|
156
|
+
request; hide it with the `auto_merge` render toggle.
|
|
157
|
+
|
|
158
|
+
The four enablement categories count the repositories with and without the
|
|
159
|
+
feature (plus any whose state could not be read), and by default name whichever
|
|
160
|
+
known list is shorter — see
|
|
161
|
+
[Enabled or disabled repository lists](#enabled-or-disabled-repository-lists).
|
|
121
162
|
|
|
122
163
|
## Operating modes
|
|
123
164
|
|
|
@@ -182,6 +223,7 @@ organisation and **Repository access** set to *All repositories*, then grant:
|
|
|
182
223
|
| Secret scanning alerts | Open secret-scanning alerts, across every GitHub pattern category |
|
|
183
224
|
| Issues | Open issues and their labels (GitHub Issues table) |
|
|
184
225
|
| Administration | Dependabot enablement + security-updates status, and effective branch rules |
|
|
226
|
+
| Actions | Workflow state behind a stale CodeQL configuration |
|
|
185
227
|
|
|
186
228
|
**Organization permissions:**
|
|
187
229
|
|
|
@@ -302,6 +344,7 @@ environment-variable name, never embedded.
|
|
|
302
344
|
"include_test": false,
|
|
303
345
|
"repo_min_age_days": 28,
|
|
304
346
|
"release_max_age_days": 60,
|
|
347
|
+
"codeql_stale_days": 30,
|
|
305
348
|
"graph_batch": 10,
|
|
306
349
|
"order": { "style": "auto" }
|
|
307
350
|
},
|
|
@@ -326,6 +369,17 @@ individual output. Set a value to `0` to remove the limit entirely and show
|
|
|
326
369
|
every offender. Each can also be set at the CLI with `--top-n`,
|
|
327
370
|
`--top-n-report`, `--top-n-cli`, and `--top-n-slack`.
|
|
328
371
|
|
|
372
|
+
`report.codeql_stale_days` (default `30`, minimum `1`) is the CodeQL
|
|
373
|
+
stale-configuration threshold: a configuration is stale once its last scan
|
|
374
|
+
trails the default branch's newest commit by more than that many days. It is
|
|
375
|
+
measured against the branch head rather than the clock, so a repository nobody
|
|
376
|
+
has pushed to is not flagged just for being quiet. GitHub does not publish the
|
|
377
|
+
threshold behind its own "may be out of date" warning; across the
|
|
378
|
+
`lfreleng-actions` estate healthy configurations trailed their head by at most
|
|
379
|
+
five days and abandoned ones by more than eighty, so the default sits well
|
|
380
|
+
clear of both. The same threshold decides which configurations count as current
|
|
381
|
+
for Language Coverage.
|
|
382
|
+
|
|
329
383
|
The Releases / Tagging section has two independent freshness levers:
|
|
330
384
|
|
|
331
385
|
- `report.repo_min_age_days` (default `28`, `0` = include all) is a grace
|
|
@@ -353,7 +407,25 @@ organisation, as `--top-n` does.
|
|
|
353
407
|
|
|
354
408
|
The per-org `exclude` list removes repositories from analysis entirely; they are
|
|
355
409
|
reported as **excluded** (distinct from "not enabled"), so an intentional
|
|
356
|
-
exclusion is visible rather than silently dropped.
|
|
410
|
+
exclusion is visible rather than silently dropped. Entries match repository
|
|
411
|
+
names case-insensitively, as GitHub does.
|
|
412
|
+
|
|
413
|
+
Every category reports those exclusions beneath its counts, so an
|
|
414
|
+
organisation-wide list repeats under each one. `report.excluded_display`
|
|
415
|
+
governs that line on every surface:
|
|
416
|
+
|
|
417
|
+
| Value | Excluded line |
|
|
418
|
+
| ----- | ------------- |
|
|
419
|
+
| `always-show` (default) | Shown under every category |
|
|
420
|
+
| `always-hide` | Never shown |
|
|
421
|
+
| `conditional-hide` | Shown only for a category whose exclusions differ from the organisation's `exclude` list, and then in full |
|
|
422
|
+
|
|
423
|
+
Hiding the line changes nothing else: every count is unaffected, and the report
|
|
424
|
+
header's repository count already leaves excluded repositories out. So a clean
|
|
425
|
+
category reads `All Clean` once no Excluded line qualifies it. Today every
|
|
426
|
+
category reports the organisation's own list, so `conditional-hide` currently
|
|
427
|
+
hides the same lines `always-hide` does. It differs once a category excludes
|
|
428
|
+
repositories of its own. The `report.json` artifact always lists the exclusions.
|
|
357
429
|
|
|
358
430
|
Archived and test repositories are excluded from analysis by default. Opt them
|
|
359
431
|
back in with `report.include_archived` / `report.include_test` in the config, or
|
|
@@ -384,16 +456,17 @@ both true.
|
|
|
384
456
|
|
|
385
457
|
The example above hides Zizmor on every surface, and keeps Releases / Tagging
|
|
386
458
|
out of the terminal and Slack while still publishing it to the Markdown and HTML
|
|
387
|
-
Pages output. The valid category keys are: `codeql`,
|
|
388
|
-
`
|
|
389
|
-
`
|
|
390
|
-
`
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
459
|
+
Pages output. The valid category keys are: `codeql`,
|
|
460
|
+
`codeql_stale_configurations`, `codeql_language_coverage`, `scorecard`,
|
|
461
|
+
`zizmor`, `aislop`, `dependabot_alerts`, `secret_scanning`,
|
|
462
|
+
`dependabot_alerts_enabled`, `dependabot_updates_enabled`,
|
|
463
|
+
`dependabot_cooldown`, `releases`, `mutable_releases`,
|
|
464
|
+
`private_vulnerability_reporting`, `auto_merge`, `github_issues`,
|
|
465
|
+
`pull_requests`, `pull_requests_assigned`. Like the other `report` settings,
|
|
466
|
+
`categories` can be set globally and overridden per organisation (overrides
|
|
467
|
+
merge key-by-key, so flipping one output leaves the rest untouched). The
|
|
468
|
+
machine-readable `report.json` artifact always contains the complete dataset,
|
|
469
|
+
regardless of these toggles.
|
|
397
470
|
|
|
398
471
|
When several organisations share one Slack channel they render into a single
|
|
399
472
|
combined digest, so the per-org Slack toggles are unioned for that channel: a
|
|
@@ -454,6 +527,52 @@ Slack-style ceiling, but they still apply their own row limits — only the
|
|
|
454
527
|
GitHub Pages report whenever `pages_url` is set and short enough to render as a
|
|
455
528
|
link.
|
|
456
529
|
|
|
530
|
+
### Enabled or disabled repository lists
|
|
531
|
+
|
|
532
|
+
The four boolean feature categories — `dependabot_alerts_enabled`,
|
|
533
|
+
`dependabot_updates_enabled`, `private_vulnerability_reporting` and `auto_merge`
|
|
534
|
+
— sort each repository into one of three buckets: enabled, not enabled, or
|
|
535
|
+
**unknown** when the feature's state could not be read. The unknown bucket is
|
|
536
|
+
counted but never named, and never treated as either side, so the enabled and
|
|
537
|
+
not-enabled counts need not sum to the repositories analysed. Beneath the counts,
|
|
538
|
+
one of the two known sides is named; `report.repo_list` chooses which, on every
|
|
539
|
+
surface:
|
|
540
|
+
|
|
541
|
+
| Value | Names |
|
|
542
|
+
| ----- | ----- |
|
|
543
|
+
| `auto` (default) | Whichever list is shorter |
|
|
544
|
+
| `enabled` | The repositories with the feature on |
|
|
545
|
+
| `disabled` | The repositories with the feature off |
|
|
546
|
+
|
|
547
|
+
`auto` keeps a footer short whichever way an organisation leans: a feature
|
|
548
|
+
nearly every repository has lists its few holdouts, and one almost none have
|
|
549
|
+
lists its few adopters. Two cases resolve towards the actionable side: a tie
|
|
550
|
+
names the repositories without the feature, and so does a category where
|
|
551
|
+
*nothing* is enabled, since naming an empty list would print nothing where a
|
|
552
|
+
reader wants the repositories to fix. Both sides are always counted, whichever is
|
|
553
|
+
named.
|
|
554
|
+
|
|
555
|
+
A category can override the global value:
|
|
556
|
+
|
|
557
|
+
```json
|
|
558
|
+
{
|
|
559
|
+
"report": {
|
|
560
|
+
"repo_list": "auto",
|
|
561
|
+
"categories": {
|
|
562
|
+
"dependabot_alerts_enabled": { "repo_list": "disabled" }
|
|
563
|
+
}
|
|
564
|
+
},
|
|
565
|
+
"organizations": [{ "name": "lfreleng-actions" }]
|
|
566
|
+
}
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
Here Dependabot alerts always name the repositories to fix, and the other three
|
|
570
|
+
feature categories name whichever side is shorter. `repo_list` applies only to
|
|
571
|
+
those four categories; setting it on any other is a configuration error, since a
|
|
572
|
+
table with qualitative columns has no enabled list to name. These categories
|
|
573
|
+
render as a name list rather than a one-column table on every surface. The
|
|
574
|
+
`report.json` artifact is unaffected.
|
|
575
|
+
|
|
457
576
|
### Per-category row ordering
|
|
458
577
|
|
|
459
578
|
Each table ships a sensible default ordering — largest backlog first, stalest
|
|
@@ -1401,8 +1520,30 @@ uvx github-security-report remediate \
|
|
|
1401
1520
|
# Limit to specific categories (repeatable).
|
|
1402
1521
|
uvx github-security-report remediate --org lfreleng-actions \
|
|
1403
1522
|
--category codeql --category private_vulnerability_reporting --apply
|
|
1523
|
+
|
|
1524
|
+
# Limit to specific repositories, for any category (comma-separated and/or
|
|
1525
|
+
# repeatable; `name` in any configured org, or `owner/name`).
|
|
1526
|
+
uvx github-security-report remediate --org lfreleng-actions \
|
|
1527
|
+
--repos dependamerge,python-nss-ng --apply
|
|
1404
1528
|
```
|
|
1405
1529
|
|
|
1530
|
+
`--repos` narrows the run itself, not just its output. Everything done per
|
|
1531
|
+
repository (the feature probes, the batched prefetch, the CodeQL history walk
|
|
1532
|
+
and every write) covers only the named repositories, so a targeted run skips
|
|
1533
|
+
the bulk of a full one. The organisation-wide alert sweeps are the exception:
|
|
1534
|
+
each is a single org-bulk request, so its cost follows the organisation's open
|
|
1535
|
+
alert backlog rather than its repository count. It combines with
|
|
1536
|
+
`--category`. Every name is checked against every configured organisation
|
|
1537
|
+
before anything is written: a name that matches no repository (almost always
|
|
1538
|
+
a typo), or one that matches only repositories the configuration excludes
|
|
1539
|
+
(the `exclude` list, archived, fork, template or test), stops the run with
|
|
1540
|
+
exit code 2 and says which. A bare name excluded in one organisation but in
|
|
1541
|
+
scope in another runs against the in-scope one only; naming a repository never
|
|
1542
|
+
brings an excluded one back. A `--repos` value that names nothing also stops
|
|
1543
|
+
the run, rather than falling back to every repository. The run then collects
|
|
1544
|
+
exactly the repositories that check validated, without listing the
|
|
1545
|
+
organisation again, and prints `Limited to:` beneath its heading.
|
|
1546
|
+
|
|
1406
1547
|
The remediable categories are the simple on/off features with a documented
|
|
1407
1548
|
enablement endpoint:
|
|
1408
1549
|
|
|
@@ -1413,11 +1554,65 @@ enablement endpoint:
|
|
|
1413
1554
|
| `dependabot_alerts_enabled` | Dependabot vulnerability alerts |
|
|
1414
1555
|
| `dependabot_updates_enabled` | Dependabot security updates (plus alerts) |
|
|
1415
1556
|
| `private_vulnerability_reporting` | Private vulnerability reporting |
|
|
1557
|
+
| `auto_merge` | The repository's "Allow auto-merge" setting |
|
|
1416
1558
|
|
|
1417
1559
|
Qualitative findings (Scorecard, zizmor, open Dependabot alerts, cooldown,
|
|
1418
1560
|
release freshness/mutability) are reported but not auto-remediated. Remediation
|
|
1419
1561
|
is organisation-scoped (`--scope org`, the default and only supported scope).
|
|
1420
1562
|
|
|
1563
|
+
### Cleaning up stale CodeQL configurations
|
|
1564
|
+
|
|
1565
|
+
One category is **destructive**, so it runs only when named. The no-argument
|
|
1566
|
+
run never includes it:
|
|
1567
|
+
|
|
1568
|
+
```bash
|
|
1569
|
+
# Preview: which configurations would go, and which are refused and why.
|
|
1570
|
+
uvx github-security-report remediate --org lfreleng-actions \
|
|
1571
|
+
--category codeql_stale_configurations
|
|
1572
|
+
|
|
1573
|
+
# Apply.
|
|
1574
|
+
uvx github-security-report remediate --org lfreleng-actions \
|
|
1575
|
+
--category codeql_stale_configurations --apply
|
|
1576
|
+
```
|
|
1577
|
+
|
|
1578
|
+
It acts on the rows of **CodeQL: Stale Configurations**, according to their
|
|
1579
|
+
cause:
|
|
1580
|
+
|
|
1581
|
+
<!-- markdownlint-disable MD013 -->
|
|
1582
|
+
|
|
1583
|
+
| Cause | Action |
|
|
1584
|
+
| ----- | ------ |
|
|
1585
|
+
| Default setup disabled; workflow removed; superseded by default setup; language removed from default setup | **Delete** the configuration: it can never upload again |
|
|
1586
|
+
| Workflow disabled after inactivity | **Re-enable** the workflow, restoring the scan |
|
|
1587
|
+
| Analyses failing, default setup changing state or not uploading, uploaded outside GitHub Actions, workflow disabled by hand, active but not uploading, or state unreadable | Reported only; needs a person |
|
|
1588
|
+
|
|
1589
|
+
<!-- markdownlint-enable MD013 -->
|
|
1590
|
+
|
|
1591
|
+
Deleting removes a configuration's analyses, which clears GitHub's *"Code
|
|
1592
|
+
Scanning results may be out of date"* warning but also removes its alert
|
|
1593
|
+
history. A deletion is therefore **refused**, in a dry run as in an apply,
|
|
1594
|
+
when:
|
|
1595
|
+
|
|
1596
|
+
- no current configuration scans its language: the stale results are then
|
|
1597
|
+
the only record of it, so add scanning for the language first (the refusal
|
|
1598
|
+
names it, and **CodeQL: Language Coverage** lists the gap);
|
|
1599
|
+
- it would help close an open alert. This is judged across **every deletion
|
|
1600
|
+
planned in the repository**, not one at a time: an alert held by two stale
|
|
1601
|
+
configurations would close if both went, so both are refused, although
|
|
1602
|
+
neither holds it alone. An alert also reported by a live configuration
|
|
1603
|
+
blocks nothing;
|
|
1604
|
+
- the repository's open alerts cannot be read.
|
|
1605
|
+
|
|
1606
|
+
Refusals are listed beside the work done and do not fail the run. Deletion is
|
|
1607
|
+
paced at one request a second across the whole run, as GitHub asks of
|
|
1608
|
+
mutating requests, and is resumable: an interrupted run's next pass picks up
|
|
1609
|
+
the remaining analyses. GitHub answers requests it will not authorise with
|
|
1610
|
+
`404`, so a deletion's `404` counts as already done only once the analysis
|
|
1611
|
+
also reads back as gone; a token that may not delete fails instead of
|
|
1612
|
+
reporting a cleanup that never happened. The token needs the classic `repo`
|
|
1613
|
+
scope. See [ADR-0005](docs/adr/0005-codeql-configuration-cleanup.md) for the
|
|
1614
|
+
reasoning.
|
|
1615
|
+
|
|
1421
1616
|
## Bulk Remediation Scripts
|
|
1422
1617
|
|
|
1423
1618
|
The standalone scripts below predate the `remediate` subcommand and remain for
|
|
@@ -57,6 +57,33 @@ if you want to probe everything regardless.
|
|
|
57
57
|
Further sections report **configuration posture** and **freshness** as plain
|
|
58
58
|
tables (org mode):
|
|
59
59
|
|
|
60
|
+
- **CodeQL scan health** — two tables beneath **CodeQL: Results/Findings** (the
|
|
61
|
+
CodeQL alerts table), whose "Clean" says nothing about whether CodeQL is
|
|
62
|
+
still running:
|
|
63
|
+
- **Stale Configurations** lists every CodeQL configuration whose last scan
|
|
64
|
+
trails the default branch's newest commit by more than
|
|
65
|
+
`codeql_stale_days` (default 30) — the condition GitHub's tool status page
|
|
66
|
+
flags as *"Code Scanning results may be out of date"*. Each row names the
|
|
67
|
+
setup type (**Default**, GitHub-managed; or **Advanced**, a workflow in the
|
|
68
|
+
repository), the language, the last *successful* scan, and the cause:
|
|
69
|
+
analyses failing (a run that errors still uploads, but its results do not
|
|
70
|
+
count as a scan), default setup switched off, a workflow removed or
|
|
71
|
+
disabled, or an advanced workflow
|
|
72
|
+
**superseded** by default setup (GitHub rejects advanced CodeQL uploads
|
|
73
|
+
while default setup is on). An *orphaned* configuration will never scan
|
|
74
|
+
again; delete it from the tool status page once the live setup covers its
|
|
75
|
+
language.
|
|
76
|
+
- **Language Coverage** lists repositories where GitHub detects a
|
|
77
|
+
CodeQL-supported language that no current configuration scans — typically
|
|
78
|
+
an advanced workflow whose language matrix omits one the repository
|
|
79
|
+
contains, such as `actions` for its own workflows. On default setup GitHub
|
|
80
|
+
reports only the languages it is set to scan, so a detected language
|
|
81
|
+
deliberately left out of default setup is not visible to this check.
|
|
82
|
+
|
|
83
|
+
Both consider only repositories where CodeQL has run at least once; the rest
|
|
84
|
+
already appear in the Results/Findings not-enabled list. Finding a stale
|
|
85
|
+
configuration means reading each repository's whole CodeQL analysis history,
|
|
86
|
+
since GitHub cannot filter it by configuration.
|
|
60
87
|
- **Dependabot** — three tables: repositories with vulnerability **alerts not
|
|
61
88
|
enabled**, repositories with **security updates not enabled**, and ecosystems
|
|
62
89
|
with no update `cooldown` configured (mandatory; any value passes).
|
|
@@ -74,6 +101,20 @@ tables (org mode):
|
|
|
74
101
|
exposes no org-wide or GraphQL equivalent) and, like every other category,
|
|
75
102
|
always collected; hide it with the `private_vulnerability_reporting` render
|
|
76
103
|
toggle.
|
|
104
|
+
- **Auto-merge** — repositories where the **Allow auto-merge** setting is off,
|
|
105
|
+
so a pull request cannot be queued to merge itself once its requirements are
|
|
106
|
+
met. The setting only offers the option: an auto-merging pull request still
|
|
107
|
+
waits for the required checks, reviews and branch protections the repository
|
|
108
|
+
already enforces, so enabling it relaxes nothing. What it removes is the
|
|
109
|
+
interval between a change becoming mergeable and somebody noticing — the
|
|
110
|
+
window a reviewed dependency update sits in while the vulnerability it fixes
|
|
111
|
+
stays unpatched. Read from the batched GraphQL prefetch, so it costs no extra
|
|
112
|
+
request; hide it with the `auto_merge` render toggle.
|
|
113
|
+
|
|
114
|
+
The four enablement categories count the repositories with and without the
|
|
115
|
+
feature (plus any whose state could not be read), and by default name whichever
|
|
116
|
+
known list is shorter — see
|
|
117
|
+
[Enabled or disabled repository lists](#enabled-or-disabled-repository-lists).
|
|
77
118
|
|
|
78
119
|
## Operating modes
|
|
79
120
|
|
|
@@ -138,6 +179,7 @@ organisation and **Repository access** set to *All repositories*, then grant:
|
|
|
138
179
|
| Secret scanning alerts | Open secret-scanning alerts, across every GitHub pattern category |
|
|
139
180
|
| Issues | Open issues and their labels (GitHub Issues table) |
|
|
140
181
|
| Administration | Dependabot enablement + security-updates status, and effective branch rules |
|
|
182
|
+
| Actions | Workflow state behind a stale CodeQL configuration |
|
|
141
183
|
|
|
142
184
|
**Organization permissions:**
|
|
143
185
|
|
|
@@ -258,6 +300,7 @@ environment-variable name, never embedded.
|
|
|
258
300
|
"include_test": false,
|
|
259
301
|
"repo_min_age_days": 28,
|
|
260
302
|
"release_max_age_days": 60,
|
|
303
|
+
"codeql_stale_days": 30,
|
|
261
304
|
"graph_batch": 10,
|
|
262
305
|
"order": { "style": "auto" }
|
|
263
306
|
},
|
|
@@ -282,6 +325,17 @@ individual output. Set a value to `0` to remove the limit entirely and show
|
|
|
282
325
|
every offender. Each can also be set at the CLI with `--top-n`,
|
|
283
326
|
`--top-n-report`, `--top-n-cli`, and `--top-n-slack`.
|
|
284
327
|
|
|
328
|
+
`report.codeql_stale_days` (default `30`, minimum `1`) is the CodeQL
|
|
329
|
+
stale-configuration threshold: a configuration is stale once its last scan
|
|
330
|
+
trails the default branch's newest commit by more than that many days. It is
|
|
331
|
+
measured against the branch head rather than the clock, so a repository nobody
|
|
332
|
+
has pushed to is not flagged just for being quiet. GitHub does not publish the
|
|
333
|
+
threshold behind its own "may be out of date" warning; across the
|
|
334
|
+
`lfreleng-actions` estate healthy configurations trailed their head by at most
|
|
335
|
+
five days and abandoned ones by more than eighty, so the default sits well
|
|
336
|
+
clear of both. The same threshold decides which configurations count as current
|
|
337
|
+
for Language Coverage.
|
|
338
|
+
|
|
285
339
|
The Releases / Tagging section has two independent freshness levers:
|
|
286
340
|
|
|
287
341
|
- `report.repo_min_age_days` (default `28`, `0` = include all) is a grace
|
|
@@ -309,7 +363,25 @@ organisation, as `--top-n` does.
|
|
|
309
363
|
|
|
310
364
|
The per-org `exclude` list removes repositories from analysis entirely; they are
|
|
311
365
|
reported as **excluded** (distinct from "not enabled"), so an intentional
|
|
312
|
-
exclusion is visible rather than silently dropped.
|
|
366
|
+
exclusion is visible rather than silently dropped. Entries match repository
|
|
367
|
+
names case-insensitively, as GitHub does.
|
|
368
|
+
|
|
369
|
+
Every category reports those exclusions beneath its counts, so an
|
|
370
|
+
organisation-wide list repeats under each one. `report.excluded_display`
|
|
371
|
+
governs that line on every surface:
|
|
372
|
+
|
|
373
|
+
| Value | Excluded line |
|
|
374
|
+
| ----- | ------------- |
|
|
375
|
+
| `always-show` (default) | Shown under every category |
|
|
376
|
+
| `always-hide` | Never shown |
|
|
377
|
+
| `conditional-hide` | Shown only for a category whose exclusions differ from the organisation's `exclude` list, and then in full |
|
|
378
|
+
|
|
379
|
+
Hiding the line changes nothing else: every count is unaffected, and the report
|
|
380
|
+
header's repository count already leaves excluded repositories out. So a clean
|
|
381
|
+
category reads `All Clean` once no Excluded line qualifies it. Today every
|
|
382
|
+
category reports the organisation's own list, so `conditional-hide` currently
|
|
383
|
+
hides the same lines `always-hide` does. It differs once a category excludes
|
|
384
|
+
repositories of its own. The `report.json` artifact always lists the exclusions.
|
|
313
385
|
|
|
314
386
|
Archived and test repositories are excluded from analysis by default. Opt them
|
|
315
387
|
back in with `report.include_archived` / `report.include_test` in the config, or
|
|
@@ -340,16 +412,17 @@ both true.
|
|
|
340
412
|
|
|
341
413
|
The example above hides Zizmor on every surface, and keeps Releases / Tagging
|
|
342
414
|
out of the terminal and Slack while still publishing it to the Markdown and HTML
|
|
343
|
-
Pages output. The valid category keys are: `codeql`,
|
|
344
|
-
`
|
|
345
|
-
`
|
|
346
|
-
`
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
415
|
+
Pages output. The valid category keys are: `codeql`,
|
|
416
|
+
`codeql_stale_configurations`, `codeql_language_coverage`, `scorecard`,
|
|
417
|
+
`zizmor`, `aislop`, `dependabot_alerts`, `secret_scanning`,
|
|
418
|
+
`dependabot_alerts_enabled`, `dependabot_updates_enabled`,
|
|
419
|
+
`dependabot_cooldown`, `releases`, `mutable_releases`,
|
|
420
|
+
`private_vulnerability_reporting`, `auto_merge`, `github_issues`,
|
|
421
|
+
`pull_requests`, `pull_requests_assigned`. Like the other `report` settings,
|
|
422
|
+
`categories` can be set globally and overridden per organisation (overrides
|
|
423
|
+
merge key-by-key, so flipping one output leaves the rest untouched). The
|
|
424
|
+
machine-readable `report.json` artifact always contains the complete dataset,
|
|
425
|
+
regardless of these toggles.
|
|
353
426
|
|
|
354
427
|
When several organisations share one Slack channel they render into a single
|
|
355
428
|
combined digest, so the per-org Slack toggles are unioned for that channel: a
|
|
@@ -410,6 +483,52 @@ Slack-style ceiling, but they still apply their own row limits — only the
|
|
|
410
483
|
GitHub Pages report whenever `pages_url` is set and short enough to render as a
|
|
411
484
|
link.
|
|
412
485
|
|
|
486
|
+
### Enabled or disabled repository lists
|
|
487
|
+
|
|
488
|
+
The four boolean feature categories — `dependabot_alerts_enabled`,
|
|
489
|
+
`dependabot_updates_enabled`, `private_vulnerability_reporting` and `auto_merge`
|
|
490
|
+
— sort each repository into one of three buckets: enabled, not enabled, or
|
|
491
|
+
**unknown** when the feature's state could not be read. The unknown bucket is
|
|
492
|
+
counted but never named, and never treated as either side, so the enabled and
|
|
493
|
+
not-enabled counts need not sum to the repositories analysed. Beneath the counts,
|
|
494
|
+
one of the two known sides is named; `report.repo_list` chooses which, on every
|
|
495
|
+
surface:
|
|
496
|
+
|
|
497
|
+
| Value | Names |
|
|
498
|
+
| ----- | ----- |
|
|
499
|
+
| `auto` (default) | Whichever list is shorter |
|
|
500
|
+
| `enabled` | The repositories with the feature on |
|
|
501
|
+
| `disabled` | The repositories with the feature off |
|
|
502
|
+
|
|
503
|
+
`auto` keeps a footer short whichever way an organisation leans: a feature
|
|
504
|
+
nearly every repository has lists its few holdouts, and one almost none have
|
|
505
|
+
lists its few adopters. Two cases resolve towards the actionable side: a tie
|
|
506
|
+
names the repositories without the feature, and so does a category where
|
|
507
|
+
*nothing* is enabled, since naming an empty list would print nothing where a
|
|
508
|
+
reader wants the repositories to fix. Both sides are always counted, whichever is
|
|
509
|
+
named.
|
|
510
|
+
|
|
511
|
+
A category can override the global value:
|
|
512
|
+
|
|
513
|
+
```json
|
|
514
|
+
{
|
|
515
|
+
"report": {
|
|
516
|
+
"repo_list": "auto",
|
|
517
|
+
"categories": {
|
|
518
|
+
"dependabot_alerts_enabled": { "repo_list": "disabled" }
|
|
519
|
+
}
|
|
520
|
+
},
|
|
521
|
+
"organizations": [{ "name": "lfreleng-actions" }]
|
|
522
|
+
}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
Here Dependabot alerts always name the repositories to fix, and the other three
|
|
526
|
+
feature categories name whichever side is shorter. `repo_list` applies only to
|
|
527
|
+
those four categories; setting it on any other is a configuration error, since a
|
|
528
|
+
table with qualitative columns has no enabled list to name. These categories
|
|
529
|
+
render as a name list rather than a one-column table on every surface. The
|
|
530
|
+
`report.json` artifact is unaffected.
|
|
531
|
+
|
|
413
532
|
### Per-category row ordering
|
|
414
533
|
|
|
415
534
|
Each table ships a sensible default ordering — largest backlog first, stalest
|
|
@@ -1357,8 +1476,30 @@ uvx github-security-report remediate \
|
|
|
1357
1476
|
# Limit to specific categories (repeatable).
|
|
1358
1477
|
uvx github-security-report remediate --org lfreleng-actions \
|
|
1359
1478
|
--category codeql --category private_vulnerability_reporting --apply
|
|
1479
|
+
|
|
1480
|
+
# Limit to specific repositories, for any category (comma-separated and/or
|
|
1481
|
+
# repeatable; `name` in any configured org, or `owner/name`).
|
|
1482
|
+
uvx github-security-report remediate --org lfreleng-actions \
|
|
1483
|
+
--repos dependamerge,python-nss-ng --apply
|
|
1360
1484
|
```
|
|
1361
1485
|
|
|
1486
|
+
`--repos` narrows the run itself, not just its output. Everything done per
|
|
1487
|
+
repository (the feature probes, the batched prefetch, the CodeQL history walk
|
|
1488
|
+
and every write) covers only the named repositories, so a targeted run skips
|
|
1489
|
+
the bulk of a full one. The organisation-wide alert sweeps are the exception:
|
|
1490
|
+
each is a single org-bulk request, so its cost follows the organisation's open
|
|
1491
|
+
alert backlog rather than its repository count. It combines with
|
|
1492
|
+
`--category`. Every name is checked against every configured organisation
|
|
1493
|
+
before anything is written: a name that matches no repository (almost always
|
|
1494
|
+
a typo), or one that matches only repositories the configuration excludes
|
|
1495
|
+
(the `exclude` list, archived, fork, template or test), stops the run with
|
|
1496
|
+
exit code 2 and says which. A bare name excluded in one organisation but in
|
|
1497
|
+
scope in another runs against the in-scope one only; naming a repository never
|
|
1498
|
+
brings an excluded one back. A `--repos` value that names nothing also stops
|
|
1499
|
+
the run, rather than falling back to every repository. The run then collects
|
|
1500
|
+
exactly the repositories that check validated, without listing the
|
|
1501
|
+
organisation again, and prints `Limited to:` beneath its heading.
|
|
1502
|
+
|
|
1362
1503
|
The remediable categories are the simple on/off features with a documented
|
|
1363
1504
|
enablement endpoint:
|
|
1364
1505
|
|
|
@@ -1369,11 +1510,65 @@ enablement endpoint:
|
|
|
1369
1510
|
| `dependabot_alerts_enabled` | Dependabot vulnerability alerts |
|
|
1370
1511
|
| `dependabot_updates_enabled` | Dependabot security updates (plus alerts) |
|
|
1371
1512
|
| `private_vulnerability_reporting` | Private vulnerability reporting |
|
|
1513
|
+
| `auto_merge` | The repository's "Allow auto-merge" setting |
|
|
1372
1514
|
|
|
1373
1515
|
Qualitative findings (Scorecard, zizmor, open Dependabot alerts, cooldown,
|
|
1374
1516
|
release freshness/mutability) are reported but not auto-remediated. Remediation
|
|
1375
1517
|
is organisation-scoped (`--scope org`, the default and only supported scope).
|
|
1376
1518
|
|
|
1519
|
+
### Cleaning up stale CodeQL configurations
|
|
1520
|
+
|
|
1521
|
+
One category is **destructive**, so it runs only when named. The no-argument
|
|
1522
|
+
run never includes it:
|
|
1523
|
+
|
|
1524
|
+
```bash
|
|
1525
|
+
# Preview: which configurations would go, and which are refused and why.
|
|
1526
|
+
uvx github-security-report remediate --org lfreleng-actions \
|
|
1527
|
+
--category codeql_stale_configurations
|
|
1528
|
+
|
|
1529
|
+
# Apply.
|
|
1530
|
+
uvx github-security-report remediate --org lfreleng-actions \
|
|
1531
|
+
--category codeql_stale_configurations --apply
|
|
1532
|
+
```
|
|
1533
|
+
|
|
1534
|
+
It acts on the rows of **CodeQL: Stale Configurations**, according to their
|
|
1535
|
+
cause:
|
|
1536
|
+
|
|
1537
|
+
<!-- markdownlint-disable MD013 -->
|
|
1538
|
+
|
|
1539
|
+
| Cause | Action |
|
|
1540
|
+
| ----- | ------ |
|
|
1541
|
+
| Default setup disabled; workflow removed; superseded by default setup; language removed from default setup | **Delete** the configuration: it can never upload again |
|
|
1542
|
+
| Workflow disabled after inactivity | **Re-enable** the workflow, restoring the scan |
|
|
1543
|
+
| Analyses failing, default setup changing state or not uploading, uploaded outside GitHub Actions, workflow disabled by hand, active but not uploading, or state unreadable | Reported only; needs a person |
|
|
1544
|
+
|
|
1545
|
+
<!-- markdownlint-enable MD013 -->
|
|
1546
|
+
|
|
1547
|
+
Deleting removes a configuration's analyses, which clears GitHub's *"Code
|
|
1548
|
+
Scanning results may be out of date"* warning but also removes its alert
|
|
1549
|
+
history. A deletion is therefore **refused**, in a dry run as in an apply,
|
|
1550
|
+
when:
|
|
1551
|
+
|
|
1552
|
+
- no current configuration scans its language: the stale results are then
|
|
1553
|
+
the only record of it, so add scanning for the language first (the refusal
|
|
1554
|
+
names it, and **CodeQL: Language Coverage** lists the gap);
|
|
1555
|
+
- it would help close an open alert. This is judged across **every deletion
|
|
1556
|
+
planned in the repository**, not one at a time: an alert held by two stale
|
|
1557
|
+
configurations would close if both went, so both are refused, although
|
|
1558
|
+
neither holds it alone. An alert also reported by a live configuration
|
|
1559
|
+
blocks nothing;
|
|
1560
|
+
- the repository's open alerts cannot be read.
|
|
1561
|
+
|
|
1562
|
+
Refusals are listed beside the work done and do not fail the run. Deletion is
|
|
1563
|
+
paced at one request a second across the whole run, as GitHub asks of
|
|
1564
|
+
mutating requests, and is resumable: an interrupted run's next pass picks up
|
|
1565
|
+
the remaining analyses. GitHub answers requests it will not authorise with
|
|
1566
|
+
`404`, so a deletion's `404` counts as already done only once the analysis
|
|
1567
|
+
also reads back as gone; a token that may not delete fails instead of
|
|
1568
|
+
reporting a cleanup that never happened. The token needs the classic `repo`
|
|
1569
|
+
scope. See [ADR-0005](docs/adr/0005-codeql-configuration-cleanup.md) for the
|
|
1570
|
+
reasoning.
|
|
1571
|
+
|
|
1377
1572
|
## Bulk Remediation Scripts
|
|
1378
1573
|
|
|
1379
1574
|
The standalone scripts below predate the `remediate` subcommand and remain for
|
|
@@ -63,9 +63,9 @@ dev = [
|
|
|
63
63
|
"pytest-asyncio==1.4.0",
|
|
64
64
|
"pytest-cov==7.1.0",
|
|
65
65
|
"respx==0.23.1",
|
|
66
|
-
"syrupy==6.
|
|
66
|
+
"syrupy==6.1.1",
|
|
67
67
|
"mypy==2.3.1",
|
|
68
|
-
"ruff==0.16.
|
|
68
|
+
"ruff==0.16.8",
|
|
69
69
|
"types-jsonschema==4.26.0.20260518",
|
|
70
70
|
"types-PyYAML==6.0.12.20250915",
|
|
71
71
|
]
|
|
@@ -95,9 +95,9 @@ dev = [
|
|
|
95
95
|
"pytest-asyncio==1.4.0",
|
|
96
96
|
"pytest-cov==7.1.0",
|
|
97
97
|
"respx==0.23.1",
|
|
98
|
-
"syrupy==6.
|
|
98
|
+
"syrupy==6.1.1",
|
|
99
99
|
"mypy==2.3.1",
|
|
100
|
-
"ruff==0.16.
|
|
100
|
+
"ruff==0.16.8",
|
|
101
101
|
"types-jsonschema==4.26.0.20260518",
|
|
102
102
|
"types-PyYAML==6.0.12.20250915",
|
|
103
103
|
]
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.
|
|
22
|
-
__version_tuple__ = version_tuple = (0,
|
|
21
|
+
__version__ = version = '0.17.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 17, 0)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|