github-security-report 0.21.1__tar.gz → 0.22.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.
Files changed (120) hide show
  1. {github_security_report-0.21.1 → github_security_report-0.22.0}/PKG-INFO +12 -2
  2. {github_security_report-0.21.1 → github_security_report-0.22.0}/README.md +11 -1
  3. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/_version.py +2 -2
  4. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/collect/workflow_runs.py +1 -0
  5. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/config/blocks.py +1 -0
  6. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/config/models.py +3 -0
  7. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/config/schema.py +5 -0
  8. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/malware.py +2 -2
  9. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/workflow_runs/tables.py +11 -2
  10. {github_security_report-0.21.1 → github_security_report-0.22.0}/.gitignore +0 -0
  11. {github_security_report-0.21.1 → github_security_report-0.22.0}/LICENSE +0 -0
  12. {github_security_report-0.21.1 → github_security_report-0.22.0}/LICENSES/Apache-2.0.txt +0 -0
  13. {github_security_report-0.21.1 → github_security_report-0.22.0}/pyproject.toml +0 -0
  14. {github_security_report-0.21.1 → github_security_report-0.22.0}/scripts/README.md +0 -0
  15. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/__init__.py +0 -0
  16. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/authors.py +0 -0
  17. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/categories/__init__.py +0 -0
  18. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/categories/keys.py +0 -0
  19. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/categories/signals.py +0 -0
  20. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/categories/tables.py +0 -0
  21. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/classify.py +0 -0
  22. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/cli/__init__.py +0 -0
  23. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/cli/__main__.py +0 -0
  24. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/cli/app.py +0 -0
  25. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/cli/boundary.py +0 -0
  26. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/cli/modes.py +0 -0
  27. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/cli/options.py +0 -0
  28. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/cli/outputs.py +0 -0
  29. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/cli/progress.py +0 -0
  30. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/cli/publish.py +0 -0
  31. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/cli/remediation.py +0 -0
  32. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/cli/serialise.py +0 -0
  33. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/cli/summary.py +0 -0
  34. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/__init__.py +0 -0
  35. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/accounting.py +0 -0
  36. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/alerts.py +0 -0
  37. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/analyses.py +0 -0
  38. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/batch_errors.py +0 -0
  39. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/codeql_parsers.py +0 -0
  40. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/copilot.py +0 -0
  41. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/endpoints.py +0 -0
  42. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/errors.py +0 -0
  43. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/events.py +0 -0
  44. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/failures.py +0 -0
  45. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/org_reads.py +0 -0
  46. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/paging.py +0 -0
  47. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/parsers.py +0 -0
  48. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/queries.py +0 -0
  49. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/reads.py +0 -0
  50. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/repo_parser.py +0 -0
  51. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/reviews.py +0 -0
  52. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/transport.py +0 -0
  53. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/workflow_runs.py +0 -0
  54. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/client/writes.py +0 -0
  55. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/code_quality.py +0 -0
  56. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/codeql/__init__.py +0 -0
  57. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/codeql/cleanup.py +0 -0
  58. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/codeql/facts.py +0 -0
  59. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/codeql/tables.py +0 -0
  60. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/collect/__init__.py +0 -0
  61. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/collect/codeql.py +0 -0
  62. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/collect/context.py +0 -0
  63. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/collect/extras.py +0 -0
  64. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/collect/graph.py +0 -0
  65. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/collect/org.py +0 -0
  66. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/collect/protocols.py +0 -0
  67. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/collect/repo.py +0 -0
  68. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/collect/run_sync.py +0 -0
  69. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/collect/scoping.py +0 -0
  70. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/config/__init__.py +0 -0
  71. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/config/loader.py +0 -0
  72. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/config/order.py +0 -0
  73. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/gating.py +0 -0
  74. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/gitctx.py +0 -0
  75. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/issue_presentation.py +0 -0
  76. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/issues.py +0 -0
  77. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/layout.py +0 -0
  78. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/models.py +0 -0
  79. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/ordering.py +0 -0
  80. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/posture/__init__.py +0 -0
  81. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/posture/enablement.py +0 -0
  82. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/posture/facts.py +0 -0
  83. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/posture/quality.py +0 -0
  84. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/posture/releases.py +0 -0
  85. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/pulls/__init__.py +0 -0
  86. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/pulls/columns.py +0 -0
  87. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/pulls/counting.py +0 -0
  88. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/pulls/presentation.py +0 -0
  89. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/pulls/table.py +0 -0
  90. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/py.typed +0 -0
  91. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/ranking.py +0 -0
  92. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/remediate/__init__.py +0 -0
  93. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/remediate/codeql.py +0 -0
  94. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/remediate/model.py +0 -0
  95. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/render/__init__.py +0 -0
  96. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/render/html.py +0 -0
  97. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/render/markdown.py +0 -0
  98. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/render/slack.py +0 -0
  99. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/render/slack_limits.py +0 -0
  100. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/render/slack_text.py +0 -0
  101. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/render/terminal.py +0 -0
  102. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/render/terminal_notices.py +0 -0
  103. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/report/__init__.py +0 -0
  104. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/report/aggregate.py +0 -0
  105. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/report/display.py +0 -0
  106. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/report/signals.py +0 -0
  107. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/report/tables.py +0 -0
  108. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/rulesets.py +0 -0
  109. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/runner.py +0 -0
  110. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/scope.py +0 -0
  111. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/secret_patterns.py +0 -0
  112. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/severity.py +0 -0
  113. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/summary.py +0 -0
  114. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/templates/index.html.j2 +0 -0
  115. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/templates/report.html.j2 +0 -0
  116. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/workflow_runs/__init__.py +0 -0
  117. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/workflow_runs/aggregate.py +0 -0
  118. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/workflow_runs/models.py +0 -0
  119. {github_security_report-0.21.1 → github_security_report-0.22.0}/src/github_security_report/workflow_runs/store.py +0 -0
  120. {github_security_report-0.21.1 → github_security_report-0.22.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.21.1
3
+ Version: 0.22.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
@@ -209,7 +209,9 @@ tables (org mode):
209
209
  pull request could have caught them. Each row gives **Failed** (runs that
210
210
  concluded `failure`, `startup_failure`, `timed_out` or `action_required`),
211
211
  **Runs** (every concluded run of every workflow in the repository),
212
- **Fail %** (failed over failed *plus passed*, so skips never dilute it),
212
+ **Fail %** (failed over failed *plus passed*, so skips never dilute it;
213
+ on the terminal, red above `workflow_runs.fail_rate_error_threshold`, 5%
214
+ by default, and yellow for any lower non-zero rate),
213
215
  **Skipped** (skipped, cancelled, neutral and stale runs — a cancelled run
214
216
  reached no verdict, and a bulk-merge round cancels hundreds of superseded
215
217
  ones), **Retried** (runs that passed on a later attempt, a direct sign of
@@ -1618,6 +1620,7 @@ like every other `report` key. Every key with its default:
1618
1620
  "collapse_matrix": true,
1619
1621
  "persistent_threshold": 0.9,
1620
1622
  "min_runs": 3,
1623
+ "fail_rate_error_threshold": 0.05,
1621
1624
  "cache": true
1622
1625
  }
1623
1626
  },
@@ -1659,6 +1662,13 @@ fewer than `min_runs` runs that reached a verdict *insufficient* to say. Both
1659
1662
  judge the same pass-or-fail population that Fail % does, so skips count
1660
1663
  towards neither.
1661
1664
 
1665
+ `fail_rate_error_threshold` colours the per-repository table's **Fail %**
1666
+ on the terminal: a repository failing more than that fraction of its
1667
+ pass-or-fail runs shows red, and any lower non-zero rate shows yellow.
1668
+ Markdown, HTML and Slack carry no cell colour, so the setting leaves them
1669
+ unchanged. It is independent of `persistent_threshold`, which judges
1670
+ single workflows.
1671
+
1662
1672
  `cache` and `cache_dir` govern the **run store**, a SQLite file per
1663
1673
  organisation at
1664
1674
 
@@ -165,7 +165,9 @@ tables (org mode):
165
165
  pull request could have caught them. Each row gives **Failed** (runs that
166
166
  concluded `failure`, `startup_failure`, `timed_out` or `action_required`),
167
167
  **Runs** (every concluded run of every workflow in the repository),
168
- **Fail %** (failed over failed *plus passed*, so skips never dilute it),
168
+ **Fail %** (failed over failed *plus passed*, so skips never dilute it;
169
+ on the terminal, red above `workflow_runs.fail_rate_error_threshold`, 5%
170
+ by default, and yellow for any lower non-zero rate),
169
171
  **Skipped** (skipped, cancelled, neutral and stale runs — a cancelled run
170
172
  reached no verdict, and a bulk-merge round cancels hundreds of superseded
171
173
  ones), **Retried** (runs that passed on a later attempt, a direct sign of
@@ -1574,6 +1576,7 @@ like every other `report` key. Every key with its default:
1574
1576
  "collapse_matrix": true,
1575
1577
  "persistent_threshold": 0.9,
1576
1578
  "min_runs": 3,
1579
+ "fail_rate_error_threshold": 0.05,
1577
1580
  "cache": true
1578
1581
  }
1579
1582
  },
@@ -1615,6 +1618,13 @@ fewer than `min_runs` runs that reached a verdict *insufficient* to say. Both
1615
1618
  judge the same pass-or-fail population that Fail % does, so skips count
1616
1619
  towards neither.
1617
1620
 
1621
+ `fail_rate_error_threshold` colours the per-repository table's **Fail %**
1622
+ on the terminal: a repository failing more than that fraction of its
1623
+ pass-or-fail runs shows red, and any lower non-zero rate shows yellow.
1624
+ Markdown, HTML and Slack carry no cell colour, so the setting leaves them
1625
+ unchanged. It is independent of `persistent_threshold`, which judges
1626
+ single workflows.
1627
+
1618
1628
  `cache` and `cache_dir` govern the **run store**, a SQLite file per
1619
1629
  organisation at
1620
1630
 
@@ -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.21.1'
22
- __version_tuple__ = version_tuple = (0, 21, 1)
21
+ __version__ = version = '0.22.0'
22
+ __version_tuple__ = version_tuple = (0, 22, 0)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -316,5 +316,6 @@ async def attach_workflow_failures(
316
316
  ),
317
317
  unknown=result.unknown,
318
318
  oldest=result.oldest,
319
+ fail_rate_error_threshold=cfg.fail_rate_error_threshold,
319
320
  )
320
321
  )
@@ -178,6 +178,7 @@ def _workflow_runs_from(data: dict, base: WorkflowRunsConfig) -> WorkflowRunsCon
178
178
  "collapse_matrix",
179
179
  "persistent_threshold",
180
180
  "min_runs",
181
+ "fail_rate_error_threshold",
181
182
  "cache",
182
183
  "cache_dir",
183
184
  }
@@ -188,6 +188,9 @@ class WorkflowRunsConfig:
188
188
  # intermittent. Fewer than ``min_runs`` concluded runs is too few to say.
189
189
  persistent_threshold: float = 0.9
190
190
  min_runs: int = 3
191
+ # A repository failing more than this share of its runs has its Fail %
192
+ # shown as an error; any lower non-zero rate is a warning.
193
+ fail_rate_error_threshold: float = 0.05
191
194
  cache: bool = True
192
195
  cache_dir: str | None = None
193
196
 
@@ -274,6 +274,11 @@ CONFIG_SCHEMA: dict = {
274
274
  "maximum": 1,
275
275
  },
276
276
  "min_runs": {"type": "integer", "minimum": 1},
277
+ "fail_rate_error_threshold": {
278
+ "type": "number",
279
+ "minimum": 0,
280
+ "maximum": 1,
281
+ },
277
282
  "cache": {"type": "boolean"},
278
283
  "cache_dir": {"type": "string", "minLength": 1},
279
284
  },
@@ -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
- "Malware alert enablement/status NOT currently available through APIs\n"
33
- "Repositories without findings may have the feature off so coverage unknown"
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
 
@@ -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
- if rate >= threshold:
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, options.persistent_threshold)
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}),