github-security-report 0.21.1__tar.gz → 0.23.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.21.1 → github_security_report-0.23.0}/PKG-INFO +53 -7
- {github_security_report-0.21.1 → github_security_report-0.23.0}/README.md +52 -6
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/_version.py +2 -2
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/categories/__init__.py +10 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/cli/serialise.py +9 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/collect/extras.py +30 -3
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/collect/workflow_runs.py +1 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/config/blocks.py +28 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/config/models.py +20 -1
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/config/schema.py +18 -2
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/malware.py +2 -2
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/report/aggregate.py +5 -5
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/workflow_runs/tables.py +11 -2
- {github_security_report-0.21.1 → github_security_report-0.23.0}/.gitignore +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/LICENSE +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/LICENSES/Apache-2.0.txt +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/pyproject.toml +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/scripts/README.md +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/__init__.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/authors.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/categories/keys.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/categories/signals.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/categories/tables.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/classify.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/cli/__init__.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/cli/__main__.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/cli/app.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/cli/boundary.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/cli/modes.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/cli/options.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/cli/outputs.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/cli/progress.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/cli/publish.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/cli/remediation.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/cli/summary.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/__init__.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/accounting.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/alerts.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/analyses.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/batch_errors.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/codeql_parsers.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/copilot.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/endpoints.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/errors.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/events.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/failures.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/org_reads.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/paging.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/parsers.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/queries.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/reads.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/repo_parser.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/reviews.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/transport.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/workflow_runs.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/client/writes.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/code_quality.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/codeql/__init__.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/codeql/cleanup.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/codeql/facts.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/codeql/tables.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/collect/__init__.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/collect/codeql.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/collect/context.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/collect/graph.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/collect/org.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/collect/protocols.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/collect/repo.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/collect/run_sync.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/collect/scoping.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/config/__init__.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/config/loader.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/config/order.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/gating.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/gitctx.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/issue_presentation.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/issues.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/layout.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/models.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/ordering.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/posture/__init__.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/posture/enablement.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/posture/facts.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/posture/quality.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/posture/releases.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/pulls/__init__.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/pulls/columns.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/pulls/counting.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/pulls/presentation.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/pulls/table.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/py.typed +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/ranking.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/remediate/__init__.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/remediate/codeql.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/remediate/model.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/render/__init__.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/render/html.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/render/markdown.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/render/slack.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/render/slack_limits.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/render/slack_text.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/render/terminal.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/render/terminal_notices.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/report/__init__.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/report/display.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/report/signals.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/report/tables.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/rulesets.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/runner.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/scope.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/secret_patterns.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/severity.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/summary.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/templates/index.html.j2 +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/templates/report.html.j2 +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/workflow_runs/__init__.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/workflow_runs/aggregate.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/workflow_runs/models.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/workflow_runs/store.py +0 -0
- {github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/workflow_runs/store_codec.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: github-security-report
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.23.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
|
|
@@ -200,7 +200,8 @@ tables (org mode):
|
|
|
200
200
|
enabled count out of the applicable count per language, such as
|
|
201
201
|
`python 30/32 · go 5/5 · javascript-typescript 10/12`. See
|
|
202
202
|
[ADR-0006](docs/adr/0006-github-code-quality.md); hide it with the
|
|
203
|
-
`code_quality` render toggle
|
|
203
|
+
`code_quality` render toggle, or leave fixture repositories out of it alone
|
|
204
|
+
with its `exclude` patterns (see [Per-category exclusions](#per-category-exclusions)).
|
|
204
205
|
- **Workflow Failures** — repositories whose GitHub Actions workflows failed
|
|
205
206
|
in the window, ranked by failed runs. The motivating case is the bulk
|
|
206
207
|
Dependabot merge whose integration tests need credentials, so they run
|
|
@@ -209,7 +210,9 @@ tables (org mode):
|
|
|
209
210
|
pull request could have caught them. Each row gives **Failed** (runs that
|
|
210
211
|
concluded `failure`, `startup_failure`, `timed_out` or `action_required`),
|
|
211
212
|
**Runs** (every concluded run of every workflow in the repository),
|
|
212
|
-
**Fail %** (failed over failed *plus passed*, so skips never dilute it
|
|
213
|
+
**Fail %** (failed over failed *plus passed*, so skips never dilute it;
|
|
214
|
+
on the terminal, red above `workflow_runs.fail_rate_error_threshold`, 5%
|
|
215
|
+
by default, and yellow for any lower non-zero rate),
|
|
213
216
|
**Skipped** (skipped, cancelled, neutral and stale runs — a cancelled run
|
|
214
217
|
reached no verdict, and a bulk-merge round cancels hundreds of superseded
|
|
215
218
|
ones), **Retried** (runs that passed on a later attempt, a direct sign of
|
|
@@ -530,10 +533,11 @@ governs that line on every surface:
|
|
|
530
533
|
|
|
531
534
|
Hiding the line changes nothing else: every count is unaffected, and the report
|
|
532
535
|
header's repository count already leaves excluded repositories out. So a clean
|
|
533
|
-
category reads `All Clean` once no Excluded line qualifies it.
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
536
|
+
category reads `All Clean` once no Excluded line qualifies it. Every category
|
|
537
|
+
reports the organisation's own list unless it excludes repositories of its own
|
|
538
|
+
(see [Per-category exclusions](#per-category-exclusions)), so with
|
|
539
|
+
`conditional-hide` the line survives only beneath such a category. The
|
|
540
|
+
`report.json` artifact always lists the exclusions.
|
|
537
541
|
|
|
538
542
|
Archived and test repositories are excluded from analysis by default. Opt them
|
|
539
543
|
back in with `report.include_archived` / `report.include_test` in the config, or
|
|
@@ -684,6 +688,40 @@ table with qualitative columns has no enabled list to name. These categories
|
|
|
684
688
|
render as a name list rather than a one-column table on every surface. The
|
|
685
689
|
`report.json` artifact is unaffected.
|
|
686
690
|
|
|
691
|
+
### Per-category exclusions
|
|
692
|
+
|
|
693
|
+
A category can leave repositories out that every other category still reports,
|
|
694
|
+
with `report.categories.<key>.exclude`: a list of regular expressions searched
|
|
695
|
+
against the repository name, case-insensitively, so `^test-` drops every
|
|
696
|
+
repository whose name starts with `test-` and `^fixture$` drops exactly
|
|
697
|
+
`fixture`. The motivating case is Code Quality, which is billed per committer:
|
|
698
|
+
an organisation that reports its test repositories (`include_test`) still has
|
|
699
|
+
no reason to pay for scanning them, and wants the section to list only the
|
|
700
|
+
repositories worth switching on:
|
|
701
|
+
|
|
702
|
+
```json
|
|
703
|
+
{
|
|
704
|
+
"report": {
|
|
705
|
+
"include_test": true,
|
|
706
|
+
"categories": {
|
|
707
|
+
"code_quality": { "exclude": ["^test-"] }
|
|
708
|
+
}
|
|
709
|
+
},
|
|
710
|
+
"organizations": [{ "name": "lfreleng-actions" }]
|
|
711
|
+
}
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
An excluded repository is neither a row nor a count in that category, and
|
|
715
|
+
`remediate --category code_quality` never writes to it. It is not dropped
|
|
716
|
+
silently: the category's **Excluded** footer line names it alongside the
|
|
717
|
+
organisation's own `exclude` list, and `report.json` carries the category's full
|
|
718
|
+
list under `category_excluded`. Under `excluded_display: conditional-hide` that
|
|
719
|
+
footer line is exactly the one that stays. An organisation's own `exclude` list
|
|
720
|
+
replaces the inherited one rather than adding to it, as every other
|
|
721
|
+
`categories` key does; a pattern that does not compile is a configuration
|
|
722
|
+
error. `exclude` applies to `code_quality` only; setting it on any other
|
|
723
|
+
category is a configuration error, since no other table yet applies it.
|
|
724
|
+
|
|
687
725
|
### Per-category row ordering
|
|
688
726
|
|
|
689
727
|
Each table ships a sensible default ordering — largest backlog first, stalest
|
|
@@ -1618,6 +1656,7 @@ like every other `report` key. Every key with its default:
|
|
|
1618
1656
|
"collapse_matrix": true,
|
|
1619
1657
|
"persistent_threshold": 0.9,
|
|
1620
1658
|
"min_runs": 3,
|
|
1659
|
+
"fail_rate_error_threshold": 0.05,
|
|
1621
1660
|
"cache": true
|
|
1622
1661
|
}
|
|
1623
1662
|
},
|
|
@@ -1659,6 +1698,13 @@ fewer than `min_runs` runs that reached a verdict *insufficient* to say. Both
|
|
|
1659
1698
|
judge the same pass-or-fail population that Fail % does, so skips count
|
|
1660
1699
|
towards neither.
|
|
1661
1700
|
|
|
1701
|
+
`fail_rate_error_threshold` colours the per-repository table's **Fail %**
|
|
1702
|
+
on the terminal: a repository failing more than that fraction of its
|
|
1703
|
+
pass-or-fail runs shows red, and any lower non-zero rate shows yellow.
|
|
1704
|
+
Markdown, HTML and Slack carry no cell colour, so the setting leaves them
|
|
1705
|
+
unchanged. It is independent of `persistent_threshold`, which judges
|
|
1706
|
+
single workflows.
|
|
1707
|
+
|
|
1662
1708
|
`cache` and `cache_dir` govern the **run store**, a SQLite file per
|
|
1663
1709
|
organisation at
|
|
1664
1710
|
|
|
@@ -156,7 +156,8 @@ tables (org mode):
|
|
|
156
156
|
enabled count out of the applicable count per language, such as
|
|
157
157
|
`python 30/32 · go 5/5 · javascript-typescript 10/12`. See
|
|
158
158
|
[ADR-0006](docs/adr/0006-github-code-quality.md); hide it with the
|
|
159
|
-
`code_quality` render toggle
|
|
159
|
+
`code_quality` render toggle, or leave fixture repositories out of it alone
|
|
160
|
+
with its `exclude` patterns (see [Per-category exclusions](#per-category-exclusions)).
|
|
160
161
|
- **Workflow Failures** — repositories whose GitHub Actions workflows failed
|
|
161
162
|
in the window, ranked by failed runs. The motivating case is the bulk
|
|
162
163
|
Dependabot merge whose integration tests need credentials, so they run
|
|
@@ -165,7 +166,9 @@ tables (org mode):
|
|
|
165
166
|
pull request could have caught them. Each row gives **Failed** (runs that
|
|
166
167
|
concluded `failure`, `startup_failure`, `timed_out` or `action_required`),
|
|
167
168
|
**Runs** (every concluded run of every workflow in the repository),
|
|
168
|
-
**Fail %** (failed over failed *plus passed*, so skips never dilute it
|
|
169
|
+
**Fail %** (failed over failed *plus passed*, so skips never dilute it;
|
|
170
|
+
on the terminal, red above `workflow_runs.fail_rate_error_threshold`, 5%
|
|
171
|
+
by default, and yellow for any lower non-zero rate),
|
|
169
172
|
**Skipped** (skipped, cancelled, neutral and stale runs — a cancelled run
|
|
170
173
|
reached no verdict, and a bulk-merge round cancels hundreds of superseded
|
|
171
174
|
ones), **Retried** (runs that passed on a later attempt, a direct sign of
|
|
@@ -486,10 +489,11 @@ governs that line on every surface:
|
|
|
486
489
|
|
|
487
490
|
Hiding the line changes nothing else: every count is unaffected, and the report
|
|
488
491
|
header's repository count already leaves excluded repositories out. So a clean
|
|
489
|
-
category reads `All Clean` once no Excluded line qualifies it.
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
492
|
+
category reads `All Clean` once no Excluded line qualifies it. Every category
|
|
493
|
+
reports the organisation's own list unless it excludes repositories of its own
|
|
494
|
+
(see [Per-category exclusions](#per-category-exclusions)), so with
|
|
495
|
+
`conditional-hide` the line survives only beneath such a category. The
|
|
496
|
+
`report.json` artifact always lists the exclusions.
|
|
493
497
|
|
|
494
498
|
Archived and test repositories are excluded from analysis by default. Opt them
|
|
495
499
|
back in with `report.include_archived` / `report.include_test` in the config, or
|
|
@@ -640,6 +644,40 @@ table with qualitative columns has no enabled list to name. These categories
|
|
|
640
644
|
render as a name list rather than a one-column table on every surface. The
|
|
641
645
|
`report.json` artifact is unaffected.
|
|
642
646
|
|
|
647
|
+
### Per-category exclusions
|
|
648
|
+
|
|
649
|
+
A category can leave repositories out that every other category still reports,
|
|
650
|
+
with `report.categories.<key>.exclude`: a list of regular expressions searched
|
|
651
|
+
against the repository name, case-insensitively, so `^test-` drops every
|
|
652
|
+
repository whose name starts with `test-` and `^fixture$` drops exactly
|
|
653
|
+
`fixture`. The motivating case is Code Quality, which is billed per committer:
|
|
654
|
+
an organisation that reports its test repositories (`include_test`) still has
|
|
655
|
+
no reason to pay for scanning them, and wants the section to list only the
|
|
656
|
+
repositories worth switching on:
|
|
657
|
+
|
|
658
|
+
```json
|
|
659
|
+
{
|
|
660
|
+
"report": {
|
|
661
|
+
"include_test": true,
|
|
662
|
+
"categories": {
|
|
663
|
+
"code_quality": { "exclude": ["^test-"] }
|
|
664
|
+
}
|
|
665
|
+
},
|
|
666
|
+
"organizations": [{ "name": "lfreleng-actions" }]
|
|
667
|
+
}
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
An excluded repository is neither a row nor a count in that category, and
|
|
671
|
+
`remediate --category code_quality` never writes to it. It is not dropped
|
|
672
|
+
silently: the category's **Excluded** footer line names it alongside the
|
|
673
|
+
organisation's own `exclude` list, and `report.json` carries the category's full
|
|
674
|
+
list under `category_excluded`. Under `excluded_display: conditional-hide` that
|
|
675
|
+
footer line is exactly the one that stays. An organisation's own `exclude` list
|
|
676
|
+
replaces the inherited one rather than adding to it, as every other
|
|
677
|
+
`categories` key does; a pattern that does not compile is a configuration
|
|
678
|
+
error. `exclude` applies to `code_quality` only; setting it on any other
|
|
679
|
+
category is a configuration error, since no other table yet applies it.
|
|
680
|
+
|
|
643
681
|
### Per-category row ordering
|
|
644
682
|
|
|
645
683
|
Each table ships a sensible default ordering — largest backlog first, stalest
|
|
@@ -1574,6 +1612,7 @@ like every other `report` key. Every key with its default:
|
|
|
1574
1612
|
"collapse_matrix": true,
|
|
1575
1613
|
"persistent_threshold": 0.9,
|
|
1576
1614
|
"min_runs": 3,
|
|
1615
|
+
"fail_rate_error_threshold": 0.05,
|
|
1577
1616
|
"cache": true
|
|
1578
1617
|
}
|
|
1579
1618
|
},
|
|
@@ -1615,6 +1654,13 @@ fewer than `min_runs` runs that reached a verdict *insufficient* to say. Both
|
|
|
1615
1654
|
judge the same pass-or-fail population that Fail % does, so skips count
|
|
1616
1655
|
towards neither.
|
|
1617
1656
|
|
|
1657
|
+
`fail_rate_error_threshold` colours the per-repository table's **Fail %**
|
|
1658
|
+
on the terminal: a repository failing more than that fraction of its
|
|
1659
|
+
pass-or-fail runs shows red, and any lower non-zero rate shows yellow.
|
|
1660
|
+
Markdown, HTML and Slack carry no cell colour, so the setting leaves them
|
|
1661
|
+
unchanged. It is independent of `persistent_threshold`, which judges
|
|
1662
|
+
single workflows.
|
|
1663
|
+
|
|
1618
1664
|
`cache` and `cache_dir` govern the **run store**, a SQLite file per
|
|
1619
1665
|
organisation at
|
|
1620
1666
|
|
|
@@ -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.23.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 23, 0)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -24,6 +24,7 @@ from github_security_report.categories.signals import SIGNAL_CATEGORIES
|
|
|
24
24
|
from github_security_report.categories.tables import TABLE_CATEGORIES
|
|
25
25
|
|
|
26
26
|
__all__ = [
|
|
27
|
+
"EXCLUDABLE_CATEGORIES",
|
|
27
28
|
"NESTED_CATEGORIES",
|
|
28
29
|
"REPO_LIST_CATEGORIES",
|
|
29
30
|
"CategoryKey",
|
|
@@ -76,6 +77,15 @@ REPO_LIST_CATEGORIES: frozenset[CategoryKey] = frozenset(
|
|
|
76
77
|
)
|
|
77
78
|
|
|
78
79
|
|
|
80
|
+
# Categories that take an ``exclude`` list of their own, dropping repositories
|
|
81
|
+
# from that one category while every other still reports them. A repository
|
|
82
|
+
# excluded this way is counted on the category's Excluded footer line, so the
|
|
83
|
+
# omission stays visible, and remediation never writes it. Only the categories
|
|
84
|
+
# whose builders apply the list are named: the schema refuses it anywhere else,
|
|
85
|
+
# where it would validate and then do nothing.
|
|
86
|
+
EXCLUDABLE_CATEGORIES: frozenset[CategoryKey] = frozenset({CategoryKey.CODE_QUALITY})
|
|
87
|
+
|
|
88
|
+
|
|
79
89
|
def orderable_categories() -> tuple[CategoryMeta, ...]:
|
|
80
90
|
"""Categories an ordering list may name, in registry order.
|
|
81
91
|
|
|
@@ -83,6 +83,15 @@ def _org_to_dict(org: OrgReport, hidden: Collection[CategoryKey] = ()) -> dict:
|
|
|
83
83
|
"partial": org.partial,
|
|
84
84
|
# Repositories explicitly excluded from analysis (per-org exclude list).
|
|
85
85
|
"excluded": [r.full_name for r in org.excluded_repos],
|
|
86
|
+
# Categories excluding repositories of their own (a category's
|
|
87
|
+
# `exclude` patterns), each with its full list: the organisation's
|
|
88
|
+
# exclusions above plus the category's. Absent categories report the
|
|
89
|
+
# organisation's list alone.
|
|
90
|
+
"category_excluded": {
|
|
91
|
+
key.value: [r.full_name for r in repos]
|
|
92
|
+
for key, repos in org.category_excluded.items()
|
|
93
|
+
if key not in suppressed
|
|
94
|
+
},
|
|
86
95
|
# Every category below, in the order the rendered surfaces drew it.
|
|
87
96
|
# The keyed structure that follows is stable regardless, but a consumer
|
|
88
97
|
# building its own view can reproduce the published layout instead of
|
|
@@ -20,6 +20,7 @@ import asyncio
|
|
|
20
20
|
import logging
|
|
21
21
|
|
|
22
22
|
from github_security_report import codeql, layout, malware, posture
|
|
23
|
+
from github_security_report.categories import CategoryKey
|
|
23
24
|
from github_security_report.code_quality import CodeQualitySetup, applicable_languages
|
|
24
25
|
from github_security_report.collect.codeql import collect_codeql_facts
|
|
25
26
|
from github_security_report.collect.context import (
|
|
@@ -45,7 +46,7 @@ from github_security_report.pulls import (
|
|
|
45
46
|
build_assigned_pull_requests_table,
|
|
46
47
|
build_pull_requests_table,
|
|
47
48
|
)
|
|
48
|
-
from github_security_report.report import OrgReport
|
|
49
|
+
from github_security_report.report import OrgReport, TableSection
|
|
49
50
|
|
|
50
51
|
log = logging.getLogger(__name__)
|
|
51
52
|
|
|
@@ -122,6 +123,31 @@ async def _posture_for_repo(repo: Repo, ctx: OrgCollectContext) -> RepoPosture:
|
|
|
122
123
|
)
|
|
123
124
|
|
|
124
125
|
|
|
126
|
+
def _build_code_quality(
|
|
127
|
+
report: OrgReport, postures: list[RepoPosture], report_cfg: ReportConfig
|
|
128
|
+
) -> tuple[TableSection, dict[str, tuple[str, ...]]]:
|
|
129
|
+
"""The Code Quality table and its remediation plan, less the excluded.
|
|
130
|
+
|
|
131
|
+
A repository the category's own ``exclude`` patterns match is dropped
|
|
132
|
+
before the table is built, so it is neither a row nor a count nor a
|
|
133
|
+
remediation target, and is recorded as excluded for this category alone:
|
|
134
|
+
its footer then lists it alongside the organisation's own exclusions,
|
|
135
|
+
while every other category still reports the repository.
|
|
136
|
+
"""
|
|
137
|
+
kept: list[RepoPosture] = []
|
|
138
|
+
dropped: list[Repo] = []
|
|
139
|
+
for p in postures:
|
|
140
|
+
if report_cfg.category_excludes(CategoryKey.CODE_QUALITY, p.repo.name):
|
|
141
|
+
dropped.append(p.repo)
|
|
142
|
+
else:
|
|
143
|
+
kept.append(p)
|
|
144
|
+
if dropped:
|
|
145
|
+
report.category_excluded[CategoryKey.CODE_QUALITY] = sorted(
|
|
146
|
+
(*report.excluded_repos, *dropped), key=lambda r: r.name
|
|
147
|
+
)
|
|
148
|
+
return posture.build_code_quality_table(kept), posture.code_quality_writes(kept)
|
|
149
|
+
|
|
150
|
+
|
|
125
151
|
async def _attach_author_tables(
|
|
126
152
|
report: OrgReport,
|
|
127
153
|
in_scope: list[Repo],
|
|
@@ -251,8 +277,9 @@ async def attach_extra_tables(
|
|
|
251
277
|
sweep_readable=ctx.sweep_status.get("dependabot") == 200,
|
|
252
278
|
generated_at=report.generated_at,
|
|
253
279
|
)
|
|
254
|
-
report.code_quality =
|
|
255
|
-
|
|
280
|
+
report.code_quality, report.code_quality_writes = _build_code_quality(
|
|
281
|
+
report, postures, report_cfg
|
|
282
|
+
)
|
|
256
283
|
report.codeql_tables = codeql.build_codeql_tables(
|
|
257
284
|
codeql_facts, stale_days=report_cfg.codeql_stale_days
|
|
258
285
|
)
|
|
@@ -11,6 +11,7 @@ with a usable error. Those parsers live here; the top-level loader in
|
|
|
11
11
|
|
|
12
12
|
from __future__ import annotations
|
|
13
13
|
|
|
14
|
+
import re
|
|
14
15
|
from collections.abc import Mapping
|
|
15
16
|
from dataclasses import replace
|
|
16
17
|
from types import MappingProxyType
|
|
@@ -178,6 +179,7 @@ def _workflow_runs_from(data: dict, base: WorkflowRunsConfig) -> WorkflowRunsCon
|
|
|
178
179
|
"collapse_matrix",
|
|
179
180
|
"persistent_threshold",
|
|
180
181
|
"min_runs",
|
|
182
|
+
"fail_rate_error_threshold",
|
|
181
183
|
"cache",
|
|
182
184
|
"cache_dir",
|
|
183
185
|
}
|
|
@@ -226,6 +228,27 @@ def _require_reachable_warning(
|
|
|
226
228
|
)
|
|
227
229
|
|
|
228
230
|
|
|
231
|
+
def _exclude_patterns_from(key: str, raw: list[str]) -> tuple[re.Pattern[str], ...]:
|
|
232
|
+
"""Compile a category's ``exclude`` list, naming the pattern that fails.
|
|
233
|
+
|
|
234
|
+
Compiled once here rather than on every repository, and rejected at load
|
|
235
|
+
time rather than mid-run: a pattern that does not compile would otherwise
|
|
236
|
+
surface only after the whole organisation had been read. An oversized
|
|
237
|
+
repeat count raises ``OverflowError`` and deep nesting ``RecursionError``
|
|
238
|
+
rather than ``re.error``, so those are caught too.
|
|
239
|
+
"""
|
|
240
|
+
patterns: list[re.Pattern[str]] = []
|
|
241
|
+
for text in raw:
|
|
242
|
+
try:
|
|
243
|
+
patterns.append(re.compile(text, re.IGNORECASE))
|
|
244
|
+
except (re.error, OverflowError, RecursionError) as exc:
|
|
245
|
+
raise ConfigError(
|
|
246
|
+
f"report.categories.{key}.exclude pattern {text!r} is not a "
|
|
247
|
+
f"valid regular expression: {exc}"
|
|
248
|
+
) from exc
|
|
249
|
+
return tuple(patterns)
|
|
250
|
+
|
|
251
|
+
|
|
229
252
|
def _categories_from(
|
|
230
253
|
data: dict, base: Mapping[str, CategoryToggle]
|
|
231
254
|
) -> Mapping[str, CategoryToggle]:
|
|
@@ -266,5 +289,10 @@ def _categories_from(
|
|
|
266
289
|
repo_list=(
|
|
267
290
|
RepoList(raw["repo_list"]) if "repo_list" in raw else current.repo_list
|
|
268
291
|
),
|
|
292
|
+
exclude=(
|
|
293
|
+
_exclude_patterns_from(key, raw["exclude"])
|
|
294
|
+
if "exclude" in raw
|
|
295
|
+
else current.exclude
|
|
296
|
+
),
|
|
269
297
|
)
|
|
270
298
|
return MappingProxyType(merged)
|
|
@@ -10,6 +10,7 @@ defaults they fall back to. Construction from raw JSON lives in
|
|
|
10
10
|
from __future__ import annotations
|
|
11
11
|
|
|
12
12
|
import datetime as dt
|
|
13
|
+
import re
|
|
13
14
|
from collections.abc import Mapping
|
|
14
15
|
from dataclasses import dataclass, field
|
|
15
16
|
from types import MappingProxyType
|
|
@@ -94,7 +95,10 @@ class CategoryToggle:
|
|
|
94
95
|
ordering of a generic table with a list of column names; ``None`` keeps the
|
|
95
96
|
ordering the table's builder chose. ``repo_list`` overrides which side of a
|
|
96
97
|
boolean feature category is named (see :class:`RepoList`); ``None`` falls
|
|
97
|
-
back to the report-wide ``repo_list``.
|
|
98
|
+
back to the report-wide ``repo_list``. ``exclude`` drops the repositories
|
|
99
|
+
whose name matches any of its regular expressions from this one category
|
|
100
|
+
(see :data:`~github_security_report.categories.EXCLUDABLE_CATEGORIES`);
|
|
101
|
+
they are reported on its Excluded footer line rather than dropped silently.
|
|
98
102
|
"""
|
|
99
103
|
|
|
100
104
|
enabled: bool = True
|
|
@@ -103,6 +107,7 @@ class CategoryToggle:
|
|
|
103
107
|
top_n: int | None = None
|
|
104
108
|
sort: tuple[str, ...] | None = None
|
|
105
109
|
repo_list: RepoList | None = None
|
|
110
|
+
exclude: tuple[re.Pattern[str], ...] = ()
|
|
106
111
|
|
|
107
112
|
def shows_on(self, output: str) -> bool:
|
|
108
113
|
"""Whether this category renders on ``output`` (cli/slack/markdown/html)."""
|
|
@@ -188,6 +193,9 @@ class WorkflowRunsConfig:
|
|
|
188
193
|
# intermittent. Fewer than ``min_runs`` concluded runs is too few to say.
|
|
189
194
|
persistent_threshold: float = 0.9
|
|
190
195
|
min_runs: int = 3
|
|
196
|
+
# A repository failing more than this share of its runs has its Fail %
|
|
197
|
+
# shown as an error; any lower non-zero rate is a warning.
|
|
198
|
+
fail_rate_error_threshold: float = 0.05
|
|
191
199
|
cache: bool = True
|
|
192
200
|
cache_dir: str | None = None
|
|
193
201
|
|
|
@@ -401,6 +409,17 @@ class ReportConfig:
|
|
|
401
409
|
return toggle.repo_list
|
|
402
410
|
return self.repo_list
|
|
403
411
|
|
|
412
|
+
def category_excludes(self, key: CategoryKey, name: str) -> bool:
|
|
413
|
+
"""Whether category ``key`` drops repository ``name`` by its own list.
|
|
414
|
+
|
|
415
|
+
Patterns are searched rather than fully matched, so ``^test-`` reads
|
|
416
|
+
as the prefix it looks like, and compiled case-insensitively, since
|
|
417
|
+
GitHub repository names are. False for an unconfigured category: only
|
|
418
|
+
the organisation's ``exclude`` list removes a repository everywhere.
|
|
419
|
+
"""
|
|
420
|
+
toggle = self.categories.get(key.value)
|
|
421
|
+
return toggle is not None and any(p.search(name) for p in toggle.exclude)
|
|
422
|
+
|
|
404
423
|
|
|
405
424
|
@dataclass(frozen=True)
|
|
406
425
|
class OrgConfig:
|
|
@@ -9,6 +9,7 @@ weekdays), the error raised on invalid input, and ``CONFIG_SCHEMA`` itself.
|
|
|
9
9
|
from __future__ import annotations
|
|
10
10
|
|
|
11
11
|
from github_security_report.categories import (
|
|
12
|
+
EXCLUDABLE_CATEGORIES,
|
|
12
13
|
REPO_LIST_CATEGORIES,
|
|
13
14
|
CategoryMeta,
|
|
14
15
|
all_categories,
|
|
@@ -81,8 +82,9 @@ def _category_schema(meta: CategoryMeta) -> dict:
|
|
|
81
82
|
"""The schema for one category's block under ``report.categories``.
|
|
82
83
|
|
|
83
84
|
``repo_list`` is offered only to the boolean feature categories, the only
|
|
84
|
-
ones with an enabled list to name
|
|
85
|
-
|
|
85
|
+
ones with an enabled list to name, and ``exclude`` only to the categories
|
|
86
|
+
whose builders apply it: anywhere else either would validate and then do
|
|
87
|
+
nothing, so it is left out and the schema rejects it by name.
|
|
86
88
|
"""
|
|
87
89
|
properties: dict = {
|
|
88
90
|
"enabled": {"type": "boolean"},
|
|
@@ -110,6 +112,15 @@ def _category_schema(meta: CategoryMeta) -> dict:
|
|
|
110
112
|
}
|
|
111
113
|
if meta.key in REPO_LIST_CATEGORIES:
|
|
112
114
|
properties["repo_list"] = {"enum": REPO_LIST_VALUES}
|
|
115
|
+
if meta.key in EXCLUDABLE_CATEGORIES:
|
|
116
|
+
# Regular expressions searched against the repository name, case-
|
|
117
|
+
# insensitively; a match drops the repository from this category only
|
|
118
|
+
# and lists it on the category's Excluded footer line. The loader
|
|
119
|
+
# rejects a pattern that does not compile, which JSON Schema cannot.
|
|
120
|
+
properties["exclude"] = {
|
|
121
|
+
"type": "array",
|
|
122
|
+
"items": {"type": "string", "minLength": 1},
|
|
123
|
+
}
|
|
113
124
|
return {"type": "object", "additionalProperties": False, "properties": properties}
|
|
114
125
|
|
|
115
126
|
|
|
@@ -274,6 +285,11 @@ CONFIG_SCHEMA: dict = {
|
|
|
274
285
|
"maximum": 1,
|
|
275
286
|
},
|
|
276
287
|
"min_runs": {"type": "integer", "minimum": 1},
|
|
288
|
+
"fail_rate_error_threshold": {
|
|
289
|
+
"type": "number",
|
|
290
|
+
"minimum": 0,
|
|
291
|
+
"maximum": 1,
|
|
292
|
+
},
|
|
277
293
|
"cache": {"type": "boolean"},
|
|
278
294
|
"cache_dir": {"type": "string", "minLength": 1},
|
|
279
295
|
},
|
|
@@ -29,8 +29,8 @@ _NUMERIC_COLUMNS = frozenset({4, 5})
|
|
|
29
29
|
# A headline and its detail, split by a newline: each surface sets the detail
|
|
30
30
|
# on a line of its own under the headline (see the summary renderers).
|
|
31
31
|
COVERAGE_NOTE = (
|
|
32
|
-
"
|
|
33
|
-
"
|
|
32
|
+
"Enablement status of malware detection NOT currently available via APIs\n"
|
|
33
|
+
"Coverage unknown; repositories without findings may have the feature off"
|
|
34
34
|
)
|
|
35
35
|
|
|
36
36
|
|
|
@@ -59,11 +59,11 @@ class OrgReport:
|
|
|
59
59
|
# organisation's baseline: every category reports it unless
|
|
60
60
|
# ``category_excluded`` gives that category a list of its own.
|
|
61
61
|
excluded_repos: list[Repo] = field(default_factory=list)
|
|
62
|
-
# Exclusions for a category that differ from the organisation baseline
|
|
63
|
-
#
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
#
|
|
62
|
+
# Exclusions for a category that differ from the organisation baseline:
|
|
63
|
+
# the baseline plus the repositories the category's own ``exclude``
|
|
64
|
+
# patterns dropped (see ``categories.EXCLUDABLE_CATEGORIES``). Absent keys
|
|
65
|
+
# inherit ``excluded_repos``. This is what the conditional-hide footer
|
|
66
|
+
# setting compares against the baseline.
|
|
67
67
|
category_excluded: dict[CategoryKey, list[Repo]] = field(default_factory=dict)
|
|
68
68
|
# Extra Dependabot posture tables rendered as sub-sections beneath the
|
|
69
69
|
# Dependabot signal heading (alerts not enabled, security updates not
|
|
@@ -84,8 +84,13 @@ def _percent(rate: float) -> str:
|
|
|
84
84
|
return f"{round(rate * 100)}%"
|
|
85
85
|
|
|
86
86
|
|
|
87
|
+
# The repository failure rate above which Fail % reads as an error.
|
|
88
|
+
DEFAULT_FAIL_RATE_ERROR_THRESHOLD = 0.05
|
|
89
|
+
|
|
90
|
+
|
|
87
91
|
def _rate_level(rate: float, threshold: float) -> str | None:
|
|
88
|
-
|
|
92
|
+
"""Error strictly above ``threshold``, warning for any lower failure."""
|
|
93
|
+
if rate > threshold:
|
|
89
94
|
return CELL_BAD
|
|
90
95
|
return CELL_WARN if rate > 0 else None
|
|
91
96
|
|
|
@@ -256,6 +261,7 @@ def build_workflow_failure_tables(
|
|
|
256
261
|
options: WindowOptions,
|
|
257
262
|
unknown: frozenset[str] = frozenset(),
|
|
258
263
|
oldest: Mapping[str, dt.datetime | None] | None = None,
|
|
264
|
+
fail_rate_error_threshold: float = DEFAULT_FAIL_RATE_ERROR_THRESHOLD,
|
|
259
265
|
) -> tuple[tuple[TableSection, ...], tuple[TableSection, ...]]:
|
|
260
266
|
"""Both tables for every window, shortest window first.
|
|
261
267
|
|
|
@@ -264,6 +270,9 @@ def build_workflow_failure_tables(
|
|
|
264
270
|
as unreadable rather than as failure-free on every window; ``oldest``
|
|
265
271
|
says how far back each repository's stored history reaches, so a window
|
|
266
272
|
reaching further is noted as truncated in the footer.
|
|
273
|
+
``fail_rate_error_threshold`` is the repository failure rate above which
|
|
274
|
+
the Fail % cell reads as an error rather than a warning; the persistent
|
|
275
|
+
threshold in ``options`` judges only the detail table's Pattern.
|
|
267
276
|
"""
|
|
268
277
|
by_name = {repo.name: repo for repo in in_scope}
|
|
269
278
|
held = list(records)
|
|
@@ -305,7 +314,7 @@ def build_workflow_failure_tables(
|
|
|
305
314
|
category=category_meta(CategoryKey.WORKFLOW_FAILURES),
|
|
306
315
|
columns=REPO_COLUMNS,
|
|
307
316
|
rows=[
|
|
308
|
-
_repo_row(by_name[s.repo], s,
|
|
317
|
+
_repo_row(by_name[s.repo], s, fail_rate_error_threshold)
|
|
309
318
|
for s in failing
|
|
310
319
|
],
|
|
311
320
|
sum_columns=frozenset({1, 2, 4, 5, 6}),
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/gating.py
RENAMED
|
File without changes
|
{github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/gitctx.py
RENAMED
|
File without changes
|
|
File without changes
|
{github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/issues.py
RENAMED
|
File without changes
|
{github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/layout.py
RENAMED
|
File without changes
|
{github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/models.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/runner.py
RENAMED
|
File without changes
|
{github_security_report-0.21.1 → github_security_report-0.23.0}/src/github_security_report/scope.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|