github-security-report 0.14.2__tar.gz → 0.16.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.14.2 → github_security_report-0.16.0}/PKG-INFO +209 -46
- {github_security_report-0.14.2 → github_security_report-0.16.0}/README.md +206 -43
- {github_security_report-0.14.2 → github_security_report-0.16.0}/pyproject.toml +4 -4
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/_version.py +2 -2
- github_security_report-0.16.0/src/github_security_report/categories/__init__.py +92 -0
- github_security_report-0.16.0/src/github_security_report/categories/keys.py +76 -0
- github_security_report-0.16.0/src/github_security_report/categories/signals.py +113 -0
- github_security_report-0.16.0/src/github_security_report/categories/tables.py +244 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/cli/app.py +6 -1
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/cli/modes.py +4 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/cli/outputs.py +55 -12
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/cli/publish.py +4 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/cli/serialise.py +4 -0
- github_security_report-0.16.0/src/github_security_report/client/codeql_parsers.py +119 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/client/org_reads.py +5 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/client/parsers.py +7 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/client/queries.py +28 -3
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/client/reads.py +95 -1
- github_security_report-0.16.0/src/github_security_report/client/reviews.py +76 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/client/writes.py +20 -0
- github_security_report-0.16.0/src/github_security_report/codeql/__init__.py +38 -0
- github_security_report-0.16.0/src/github_security_report/codeql/facts.py +189 -0
- github_security_report-0.16.0/src/github_security_report/codeql/tables.py +246 -0
- github_security_report-0.16.0/src/github_security_report/collect/codeql.py +66 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/collect/extras.py +25 -15
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/collect/protocols.py +15 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/config/loader.py +12 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/config/models.py +27 -1
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/config/schema.py +63 -36
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/layout.py +14 -28
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/models.py +28 -71
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/ordering.py +15 -18
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/posture/__init__.py +2 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/posture/enablement.py +29 -4
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/posture/facts.py +2 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/pulls/__init__.py +4 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/pulls/columns.py +10 -3
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/pulls/counting.py +24 -4
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/pulls/presentation.py +21 -1
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/pulls/table.py +4 -0
- github_security_report-0.16.0/src/github_security_report/ranking.py +86 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/remediate.py +10 -6
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/render/html.py +29 -16
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/render/markdown.py +34 -22
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/render/slack.py +45 -30
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/render/terminal.py +23 -40
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/report/__init__.py +11 -1
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/report/aggregate.py +60 -2
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/report/display.py +47 -1
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/report/tables.py +63 -5
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/summary.py +50 -3
- github_security_report-0.14.2/src/github_security_report/categories.py +0 -382
- {github_security_report-0.14.2 → github_security_report-0.16.0}/.gitignore +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/LICENSE +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/LICENSES/Apache-2.0.txt +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/scripts/README.md +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/__init__.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/authors.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/classify.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/cli/__init__.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/cli/__main__.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/cli/boundary.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/cli/options.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/client/__init__.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/client/alerts.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/client/batch_errors.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/client/copilot.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/client/endpoints.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/client/errors.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/client/transport.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/collect/__init__.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/collect/context.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/collect/org.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/collect/repo.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/config/__init__.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/config/order.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/gating.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/gitctx.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/issues.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/posture/releases.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/py.typed +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/render/__init__.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/render/slack_limits.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/report/signals.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/rulesets.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/runner.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/scope.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/secret_patterns.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/severity.py +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.0}/src/github_security_report/templates/index.html.j2 +0 -0
- {github_security_report-0.14.2 → github_security_report-0.16.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.16.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
|
|
@@ -355,6 +409,23 @@ 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
410
|
exclusion is visible rather than silently dropped.
|
|
357
411
|
|
|
412
|
+
Every category reports those exclusions beneath its counts, so an
|
|
413
|
+
organisation-wide list repeats under each one. `report.excluded_display`
|
|
414
|
+
governs that line on every surface:
|
|
415
|
+
|
|
416
|
+
| Value | Excluded line |
|
|
417
|
+
| ----- | ------------- |
|
|
418
|
+
| `always-show` (default) | Shown under every category |
|
|
419
|
+
| `always-hide` | Never shown |
|
|
420
|
+
| `conditional-hide` | Shown only for a category whose exclusions differ from the organisation's `exclude` list, and then in full |
|
|
421
|
+
|
|
422
|
+
Hiding the line changes nothing else: every count is unaffected, and the report
|
|
423
|
+
header's repository count already leaves excluded repositories out. So a clean
|
|
424
|
+
category reads `All Clean` once no Excluded line qualifies it. Today every
|
|
425
|
+
category reports the organisation's own list, so `conditional-hide` currently
|
|
426
|
+
hides the same lines `always-hide` does. It differs once a category excludes
|
|
427
|
+
repositories of its own. The `report.json` artifact always lists the exclusions.
|
|
428
|
+
|
|
358
429
|
Archived and test repositories are excluded from analysis by default. Opt them
|
|
359
430
|
back in with `report.include_archived` / `report.include_test` in the config, or
|
|
360
431
|
for a single run with `--include-archived` / `--include-test`.
|
|
@@ -384,16 +455,17 @@ both true.
|
|
|
384
455
|
|
|
385
456
|
The example above hides Zizmor on every surface, and keeps Releases / Tagging
|
|
386
457
|
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
|
-
|
|
458
|
+
Pages output. The valid category keys are: `codeql`,
|
|
459
|
+
`codeql_stale_configurations`, `codeql_language_coverage`, `scorecard`,
|
|
460
|
+
`zizmor`, `aislop`, `dependabot_alerts`, `secret_scanning`,
|
|
461
|
+
`dependabot_alerts_enabled`, `dependabot_updates_enabled`,
|
|
462
|
+
`dependabot_cooldown`, `releases`, `mutable_releases`,
|
|
463
|
+
`private_vulnerability_reporting`, `auto_merge`, `github_issues`,
|
|
464
|
+
`pull_requests`, `pull_requests_assigned`. Like the other `report` settings,
|
|
465
|
+
`categories` can be set globally and overridden per organisation (overrides
|
|
466
|
+
merge key-by-key, so flipping one output leaves the rest untouched). The
|
|
467
|
+
machine-readable `report.json` artifact always contains the complete dataset,
|
|
468
|
+
regardless of these toggles.
|
|
397
469
|
|
|
398
470
|
When several organisations share one Slack channel they render into a single
|
|
399
471
|
combined digest, so the per-org Slack toggles are unioned for that channel: a
|
|
@@ -454,6 +526,52 @@ Slack-style ceiling, but they still apply their own row limits — only the
|
|
|
454
526
|
GitHub Pages report whenever `pages_url` is set and short enough to render as a
|
|
455
527
|
link.
|
|
456
528
|
|
|
529
|
+
### Enabled or disabled repository lists
|
|
530
|
+
|
|
531
|
+
The four boolean feature categories — `dependabot_alerts_enabled`,
|
|
532
|
+
`dependabot_updates_enabled`, `private_vulnerability_reporting` and `auto_merge`
|
|
533
|
+
— sort each repository into one of three buckets: enabled, not enabled, or
|
|
534
|
+
**unknown** when the feature's state could not be read. The unknown bucket is
|
|
535
|
+
counted but never named, and never treated as either side, so the enabled and
|
|
536
|
+
not-enabled counts need not sum to the repositories analysed. Beneath the counts,
|
|
537
|
+
one of the two known sides is named; `report.repo_list` chooses which, on every
|
|
538
|
+
surface:
|
|
539
|
+
|
|
540
|
+
| Value | Names |
|
|
541
|
+
| ----- | ----- |
|
|
542
|
+
| `auto` (default) | Whichever list is shorter |
|
|
543
|
+
| `enabled` | The repositories with the feature on |
|
|
544
|
+
| `disabled` | The repositories with the feature off |
|
|
545
|
+
|
|
546
|
+
`auto` keeps a footer short whichever way an organisation leans: a feature
|
|
547
|
+
nearly every repository has lists its few holdouts, and one almost none have
|
|
548
|
+
lists its few adopters. Two cases resolve towards the actionable side: a tie
|
|
549
|
+
names the repositories without the feature, and so does a category where
|
|
550
|
+
*nothing* is enabled, since naming an empty list would print nothing where a
|
|
551
|
+
reader wants the repositories to fix. Both sides are always counted, whichever is
|
|
552
|
+
named.
|
|
553
|
+
|
|
554
|
+
A category can override the global value:
|
|
555
|
+
|
|
556
|
+
```json
|
|
557
|
+
{
|
|
558
|
+
"report": {
|
|
559
|
+
"repo_list": "auto",
|
|
560
|
+
"categories": {
|
|
561
|
+
"dependabot_alerts_enabled": { "repo_list": "disabled" }
|
|
562
|
+
}
|
|
563
|
+
},
|
|
564
|
+
"organizations": [{ "name": "lfreleng-actions" }]
|
|
565
|
+
}
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
Here Dependabot alerts always name the repositories to fix, and the other three
|
|
569
|
+
feature categories name whichever side is shorter. `repo_list` applies only to
|
|
570
|
+
those four categories; setting it on any other is a configuration error, since a
|
|
571
|
+
table with qualitative columns has no enabled list to name. These categories
|
|
572
|
+
render as a name list rather than a one-column table on every surface. The
|
|
573
|
+
`report.json` artifact is unaffected.
|
|
574
|
+
|
|
457
575
|
### Per-category row ordering
|
|
458
576
|
|
|
459
577
|
Each table ships a sensible default ordering — largest backlog first, stalest
|
|
@@ -736,17 +854,17 @@ organisation](#inside-or-outside-the-organisation):
|
|
|
736
854
|
|
|
737
855
|
```text
|
|
738
856
|
Pull Requests
|
|
739
|
-
|
|
740
|
-
┃ Repository ┃ Human ┃ Ext ┃ Auto ┃ Conflict ┃ Fail ┃ Copilot ┃ Draft ┃ Total ┃
|
|
741
|
-
|
|
742
|
-
│ lftools-uv │ 8 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 8 │
|
|
743
|
-
│ dependamerge │ 3 │ 0 │ 0 │ 0 │ 0 │ 2 │ 0 │ 3 │
|
|
744
|
-
│ gha-workflow-linter │ 2 │ 0 │ 0 │ 0 │ 1 │ 0 │ 1 │ 2 │
|
|
745
|
-
│ harden-runner-block- │ 1 │ 0 │ 0 │ 1 │ 0 │ 0 │ 1 │ 1 │
|
|
746
|
-
│ action │ │ │ │ │ │ │ │ │
|
|
747
|
-
|
|
748
|
-
│ Total │ 14 │ 0 │ 0 │ 1 │ 1 │ 2 │ 2 │ 14 │
|
|
749
|
-
|
|
857
|
+
┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━┳━━━━━━┳━━━━━━━━━━┳━━━━━━┳━━━━━━━━┳━━━━━━━━━┳━━━━━━━┳━━━━━━━┓
|
|
858
|
+
┃ Repository ┃ Human ┃ Ext ┃ Auto ┃ Conflict ┃ Fail ┃ Review ┃ Copilot ┃ Draft ┃ Total ┃
|
|
859
|
+
┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━╇━━━━━━╇━━━━━━━━━━╇━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━╇━━━━━━━┩
|
|
860
|
+
│ lftools-uv │ 8 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 8 │
|
|
861
|
+
│ dependamerge │ 3 │ 0 │ 0 │ 0 │ 0 │ 1 │ 2 │ 0 │ 3 │
|
|
862
|
+
│ gha-workflow-linter │ 2 │ 0 │ 0 │ 0 │ 1 │ 0 │ 0 │ 1 │ 2 │
|
|
863
|
+
│ harden-runner-block- │ 1 │ 0 │ 0 │ 1 │ 0 │ 0 │ 0 │ 1 │ 1 │
|
|
864
|
+
│ action │ │ │ │ │ │ │ │ │ │
|
|
865
|
+
├──────────────────────┼───────┼─────┼──────┼──────────┼──────┼────────┼─────────┼───────┼───────┤
|
|
866
|
+
│ Total │ 14 │ 0 │ 0 │ 1 │ 1 │ 1 │ 2 │ 2 │ 14 │
|
|
867
|
+
└──────────────────────┴───────┴─────┴──────┴──────────┴──────┴────────┴─────────┴───────┴───────┘
|
|
750
868
|
… and 9 more
|
|
751
869
|
❌ 13 With open pull requests
|
|
752
870
|
✅ 104 No open pull requests
|
|
@@ -760,34 +878,73 @@ The columns form **two independent groupings**:
|
|
|
760
878
|
| `Ext` | Human pull requests raised from outside the organisation — a **subset of Human**, which is why it sits beside it. |
|
|
761
879
|
| `Conflict` | Blocked on a merge conflict. |
|
|
762
880
|
| `Fail` | Latest checks did not pass. The rollup includes optional checks, so this is not by itself proof that the merge is blocked. |
|
|
881
|
+
| `Review` | A reviewer has **requested changes** — a person waiting on the author. |
|
|
763
882
|
| `Copilot` | Carries at least one **unresolved review thread** opened by GitHub's automated code reviewer. |
|
|
764
883
|
| `Draft` | Marked as a draft. |
|
|
765
884
|
|
|
766
|
-
`Conflict`, `Fail`, `Copilot` and `Draft` **overlap** each other and
|
|
767
|
-
split, so they do not sum to `Total` and are not meant to: one pull
|
|
768
|
-
is conflicting, failing *and* a draft is counted once in each of
|
|
769
|
-
columns, and once under `Human` or `Auto`. Only `Human` + `Auto`
|
|
770
|
-
the collected total. They are ordered worst-first — a conflict
|
|
771
|
-
rebase, a failing check may only need a re-run,
|
|
772
|
-
|
|
773
|
-
all.
|
|
885
|
+
`Conflict`, `Fail`, `Review`, `Copilot` and `Draft` **overlap** each other and
|
|
886
|
+
the author split, so they do not sum to `Total` and are not meant to: one pull
|
|
887
|
+
request that is conflicting, failing *and* a draft is counted once in each of
|
|
888
|
+
those three columns, and once under `Human` or `Auto`. Only `Human` + `Auto`
|
|
889
|
+
reconciles with the collected total. They are ordered worst-first — a conflict
|
|
890
|
+
needs a human to rebase, a failing check may only need a re-run, requested
|
|
891
|
+
changes need the author to act, unresolved automated feedback needs somebody but
|
|
892
|
+
does not hold the merge button down, and a draft is not blocked at all.
|
|
893
|
+
|
|
894
|
+
`Review` and `Copilot` sit together inside the blocker group, and deliberately
|
|
895
|
+
not beside `Human`: that column names who **raised** a pull request, whereas
|
|
896
|
+
these two name who is **waiting on** it. The grouping is what keeps those two
|
|
897
|
+
readings of "human" apart.
|
|
898
|
+
|
|
899
|
+
#### Requested changes
|
|
900
|
+
|
|
901
|
+
`Review` counts pull requests where **a person** has asked for changes and not
|
|
902
|
+
withdrawn it.
|
|
903
|
+
|
|
904
|
+
Two fields answer that, each covering the other's blind spot. `reviewDecision` is
|
|
905
|
+
GitHub's own verdict, computed over every review and accounting for dismissals,
|
|
906
|
+
so it is **exact at any review count** — but it names nobody, and a GitHub App
|
|
907
|
+
holding pull-request write permission can request changes exactly as a person
|
|
908
|
+
can. `latestOpinionatedReviews` names the reviewers, but is a bounded window of
|
|
909
|
+
five (one review per reviewer, so five reviewers rather than five reviews).
|
|
910
|
+
|
|
911
|
+
So the decision **gates** and the window **attributes**. Anything other than
|
|
912
|
+
`CHANGES_REQUESTED` is a definite zero whatever the window holds, and only once
|
|
913
|
+
GitHub says changes are outstanding does the reviewer's identity matter — which
|
|
914
|
+
keeps the cheap exact answer for almost every pull request and pays the window's
|
|
915
|
+
uncertainty on the few where it changes the reading. Automated reviewers are
|
|
916
|
+
recognised by the same rule as the `Auto` column.
|
|
917
|
+
|
|
918
|
+
Only `CHANGES_REQUESTED` gates. **`REVIEW_REQUIRED` is deliberately excluded**:
|
|
919
|
+
it reports that a branch rule demands a review, not that anybody objected, so on
|
|
920
|
+
an organisation that requires review by default it would mark nearly every human
|
|
921
|
+
pull request and distinguish none of them. The rule is written as an allow-list
|
|
922
|
+
of the one blocking state rather than as "anything that is not `APPROVED`", so a
|
|
923
|
+
state GitHub adds later arrives uncounted rather than pre-counted as a blocker.
|
|
924
|
+
|
|
925
|
+
Where a request for changes cannot be attributed — the reviews were unreadable,
|
|
926
|
+
the author is gone, or the window held only automated requests without covering
|
|
927
|
+
every reviewer — the pull request is left **uncounted rather than credited to a
|
|
928
|
+
person**, and the table says so in its description.
|
|
774
929
|
|
|
775
930
|
#### Unresolved Copilot feedback
|
|
776
931
|
|
|
777
|
-
`Copilot` counts the pull requests **waiting on
|
|
778
|
-
review thread counts when it was opened by GitHub's automated code
|
|
779
|
-
`copilot-pull-request-reviewer` bot) and nobody has resolved it.
|
|
780
|
-
identified from each thread's **opening** comment, since later
|
|
781
|
-
usually the human answering the review.
|
|
932
|
+
`Copilot` counts the pull requests **waiting on somebody to answer an automated
|
|
933
|
+
review**. A review thread counts when it was opened by GitHub's automated code
|
|
934
|
+
reviewer (the `copilot-pull-request-reviewer` bot) and nobody has resolved it.
|
|
935
|
+
The reviewer is identified from each thread's **opening** comment, since later
|
|
936
|
+
replies are usually the human answering the review.
|
|
782
937
|
|
|
783
938
|
An **outdated** thread still counts: GitHub marks a thread outdated when the
|
|
784
939
|
code beneath it changes, but that does not resolve it, so the feedback remains
|
|
785
940
|
unanswered.
|
|
786
941
|
|
|
787
|
-
Any non-zero count is coloured **
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
942
|
+
Any non-zero count is coloured **amber**, one step below the red of `Conflict`,
|
|
943
|
+
`Fail` and `Review`. Automated feedback is worth answering, but nobody is
|
|
944
|
+
waiting on it, and there is far more of it — colouring the two alike would let
|
|
945
|
+
the bot's threads mask the rarer case that actually holds a person up. The count
|
|
946
|
+
still feeds the row ranking, so a backlog awaiting review outranks an untouched
|
|
947
|
+
one of the same size.
|
|
791
948
|
|
|
792
949
|
The scan reads the **newest 20 review threads per pull request**, which is the
|
|
793
950
|
single most expensive part of the prefetch (see the cost figures above). The
|
|
@@ -802,8 +959,8 @@ clear — see below.
|
|
|
802
959
|
#### Automation backlog thresholds
|
|
803
960
|
|
|
804
961
|
On the terminal the counts are coloured so the table reads at a glance: `Human`
|
|
805
|
-
and `Ext` **green**, `Conflict`, `Fail` and `
|
|
806
|
-
coloured against two configured thresholds.
|
|
962
|
+
and `Ext` **green**, `Conflict`, `Fail` and `Review` **red**, `Copilot`
|
|
963
|
+
**amber**, and `Auto` coloured against two configured thresholds.
|
|
807
964
|
|
|
808
965
|
Dependabot stops raising pull requests once a repository reaches its
|
|
809
966
|
`open-pull-requests-limit`, so the repository quietly stops receiving dependency
|
|
@@ -1025,7 +1182,7 @@ reports as an App and any unrecognised login carrying the `[bot]` marker — so
|
|
|
1025
1182
|
future bot is classified as automation rather than mistaken for an outside
|
|
1026
1183
|
contributor.
|
|
1027
1184
|
|
|
1028
|
-
`Fail`, `Conflict` and `Copilot` count only **established** states. GitHub
|
|
1185
|
+
`Fail`, `Conflict`, `Review` and `Copilot` count only **established** states. GitHub
|
|
1029
1186
|
computes mergeability lazily and answers `UNKNOWN` until it settles, and reports
|
|
1030
1187
|
no check rollup at all when no checks have run; neither absence is evidence that
|
|
1031
1188
|
a pull request is ready, so neither is counted either way. `Copilot` follows the
|
|
@@ -1039,10 +1196,15 @@ holding any such reading says so in its description: `Copilot` then
|
|
|
1039
1196
|
**undercounts and should be read as a lower bound**, exactly as `Ext` does when
|
|
1040
1197
|
membership cannot be read.
|
|
1041
1198
|
|
|
1199
|
+
`Review` carries a weaker version of the same hedge, and earns it far less
|
|
1200
|
+
often: `reviewDecision` is exact, so only a pull request GitHub *does* report
|
|
1201
|
+
changes requested on can leave the question open, and then only when the
|
|
1202
|
+
opinionated-review window fails to attribute it to anybody.
|
|
1203
|
+
|
|
1042
1204
|
Repositories with no open pull requests are counted in the footer rather than
|
|
1043
1205
|
listed. Rows rank by total open pull requests, then by those failing,
|
|
1044
|
-
conflicting or awaiting
|
|
1045
|
-
overlap)
|
|
1206
|
+
conflicting or awaiting review — automated or human (counted once each, since
|
|
1207
|
+
the columns overlap) — so two repositories with equal backlogs surface the more
|
|
1046
1208
|
stuck one first.
|
|
1047
1209
|
|
|
1048
1210
|
> **Accuracy note.** As with the issues table, `Total` is exact at any size,
|
|
@@ -1369,6 +1531,7 @@ enablement endpoint:
|
|
|
1369
1531
|
| `dependabot_alerts_enabled` | Dependabot vulnerability alerts |
|
|
1370
1532
|
| `dependabot_updates_enabled` | Dependabot security updates (plus alerts) |
|
|
1371
1533
|
| `private_vulnerability_reporting` | Private vulnerability reporting |
|
|
1534
|
+
| `auto_merge` | The repository's "Allow auto-merge" setting |
|
|
1372
1535
|
|
|
1373
1536
|
Qualitative findings (Scorecard, zizmor, open Dependabot alerts, cooldown,
|
|
1374
1537
|
release freshness/mutability) are reported but not auto-remediated. Remediation
|