State the filer's contract with the plan where it is read, name the step an outage fails, and mark an unfixed vulnerability by name
This commit is contained in:
@@ -78,7 +78,8 @@ jobs:
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- run: docker build --no-cache-filter vulnerabilities --target vulnerability-report --output "$RUNNER_TEMP/vulnerabilities" .
|
||||
- name: Fetch govulncheck's report from vuln.go.dev
|
||||
run: docker build --no-cache-filter vulnerabilities --target vulnerability-report --output "$RUNNER_TEMP/vulnerabilities" .
|
||||
- name: File each one in todo.md
|
||||
id: file
|
||||
run: python3 release-tooling/file_vulnerabilities.py "$RUNNER_TEMP/vulnerabilities/report.json" todo.md
|
||||
|
||||
@@ -21,6 +21,7 @@ COPY --from=vulnerabilities /report.json /
|
||||
|
||||
FROM python:3.14.8-slim AS release-tooling
|
||||
COPY release-tooling/ /release-tooling/
|
||||
# The filer's test files an item into the plan itself.
|
||||
COPY todo.md /todo.md
|
||||
RUN python3 -m unittest discover -s /release-tooling -p '*_test.py' && touch /tested
|
||||
|
||||
|
||||
@@ -1225,9 +1225,10 @@ A known vulnerability in the Go version the gate builds with, or in a module fej
|
||||
requires, holds the release and no merge. CI checks on every pull request, every push to
|
||||
`main`, and daily. On `main` and in the daily run, CI files each vulnerability as a
|
||||
`security` item atop the next release in `todo.md`, through a pull request from the branch
|
||||
`vulnerabilities` unless one is open; each item names the version to raise to. A failed run
|
||||
that names no vulnerability means vuln.go.dev did not answer: rerun it. When GitHub pauses
|
||||
the daily run after 60 days with no activity, re-enable it under Actions. The same check:
|
||||
`vulnerabilities` unless one is open; each item names the version to raise to. When the
|
||||
step "Fetch govulncheck's report from vuln.go.dev" fails, vuln.go.dev did not answer:
|
||||
rerun it. When GitHub pauses the daily run after 60 days with no activity, re-enable it
|
||||
under Actions. The same check:
|
||||
|
||||
```sh
|
||||
docker compose run --rm vulncheck
|
||||
|
||||
@@ -3,6 +3,16 @@
|
||||
|
||||
Usage: file_vulnerabilities.py <govulncheck -format json report> <todo.md>
|
||||
Exits 1 while any vulnerability is known, filed now or before, and 0 on a clean report.
|
||||
|
||||
The item is written the way ~/.claude/bin/rank_todo.py writes one, which CI cannot run:
|
||||
todo.md's `Next ID = N` gives its ID, the release of the plan's top row (the next release)
|
||||
gives its release, and its Score is todo.md's `Score = …` formula over the scores below and
|
||||
the weight todo.md's goal table gives goal 1.1. The test that files into the repository's
|
||||
own todo.md fails the gate when the plan's shape drifts from what this script reads.
|
||||
|
||||
A security item scores R, S and C 1, since the fix is a version bump, and A and G 8, since a
|
||||
known vulnerability in the binaries works against README goal 1.1: installing fejkdata the
|
||||
way one installs other tools, which image scanners then flag.
|
||||
"""
|
||||
|
||||
import ast
|
||||
@@ -23,6 +33,7 @@ class Module:
|
||||
path: str
|
||||
found_in: str
|
||||
fixed: list[str] = field(default_factory=list)
|
||||
unfixed: bool = False
|
||||
osvs: dict[str, dict] = field(default_factory=dict)
|
||||
|
||||
@property
|
||||
@@ -59,7 +70,10 @@ def vulnerable_modules(report: str) -> list[Module]:
|
||||
frame = finding["trace"][0]
|
||||
module = modules.setdefault(frame["module"], Module(frame["module"], frame["version"]))
|
||||
module.osvs[finding["osv"]] = osvs[finding["osv"]]
|
||||
module.fixed.append(finding.get("fixed_version", ""))
|
||||
if "fixed_version" in finding:
|
||||
module.fixed.append(finding["fixed_version"])
|
||||
else:
|
||||
module.unfixed = True
|
||||
return sorted(modules.values(), key=lambda m: (m.path != "stdlib", m.path))
|
||||
|
||||
|
||||
@@ -68,6 +82,7 @@ def version_key(version: str):
|
||||
|
||||
|
||||
def evaluate(node, values):
|
||||
"""The value of todo.md's score formula: numbers, letters, unary minus and + - * /."""
|
||||
match node:
|
||||
case ast.Constant(value=value):
|
||||
return value
|
||||
@@ -93,7 +108,7 @@ def score(todo: str) -> str:
|
||||
|
||||
|
||||
def tagline(module: Module) -> str:
|
||||
if "" in module.fixed:
|
||||
if module.unfixed:
|
||||
return f"Ship no release while fejkdata carries {module.carried}, some of whose known vulnerabilities no version fixes yet."
|
||||
fixed = module.version(max(module.fixed, key=version_key))
|
||||
if module.path == "stdlib":
|
||||
|
||||
Reference in New Issue
Block a user