docs: TrueNAS compatibility matrix and the two-stage release process
The matrix is regenerated daily by CI rather than typed once and forgotten — a support table that quietly goes stale is a false promise to someone deciding whether to trust this with their backups.
This commit is contained in:
+36
-2
@@ -445,8 +445,37 @@ source. It does not mean a human ran a backup on it — that is the
|
||||
"""
|
||||
|
||||
|
||||
#: The README's matrix lives between these. CI regenerates it daily, so a table
|
||||
#: claiming the patch works on a TrueNAS that iX has since changed cannot survive
|
||||
#: for longer than a day -- a stale support matrix is not a stale doc, it is a lie
|
||||
#: to somebody deciding whether to trust this with their backups.
|
||||
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
README = os.path.join(ROOT_DIR, "README.md")
|
||||
BEGIN = "<!-- BEGIN COMPAT MATRIX (generated by tools/compat.py --matrix --markdown) -->"
|
||||
END = "<!-- END COMPAT MATRIX -->"
|
||||
|
||||
|
||||
def update_readme(rows: list[dict], path: str = README) -> bool:
|
||||
"""Rewrite the README's matrix block. True if it changed."""
|
||||
with open(path, encoding="utf-8") as fh:
|
||||
text = fh.read()
|
||||
|
||||
i, j = text.find(BEGIN), text.find(END)
|
||||
if i == -1 or j == -1:
|
||||
raise ValueError(f"{path} has no COMPAT MATRIX markers")
|
||||
|
||||
new = f"{BEGIN}\n{render_markdown(rows).rstrip()}\n{END}"
|
||||
old = text[i:j + len(END)]
|
||||
if old == new:
|
||||
return False
|
||||
|
||||
with open(path, "w", encoding="utf-8") as fh:
|
||||
fh.write(text[:i] + new + text[j + len(END):])
|
||||
return True
|
||||
|
||||
|
||||
def render_markdown(rows: list[dict]) -> str:
|
||||
"""The matrix, for COMPATIBILITY.md and the README."""
|
||||
"""The matrix, for the README."""
|
||||
out = [
|
||||
"| TrueNAS | B2/S3 providers | Nested snapshots | Hardware-verified |",
|
||||
"| --- | --- | --- | --- |",
|
||||
@@ -527,7 +556,9 @@ def main(argv):
|
||||
help="check only this module (repeatable)")
|
||||
ap.add_argument("--json", action="store_true")
|
||||
ap.add_argument("--markdown", action="store_true",
|
||||
help="with --matrix: emit the table for COMPATIBILITY.md")
|
||||
help="with --matrix: emit the table as markdown")
|
||||
ap.add_argument("--update-readme", action="store_true",
|
||||
help="with --matrix: rewrite the README's matrix block in place")
|
||||
args = ap.parse_args(argv[1:])
|
||||
|
||||
if args.matrix:
|
||||
@@ -536,6 +567,9 @@ def main(argv):
|
||||
print(json.dumps(rows, indent=2))
|
||||
elif args.markdown:
|
||||
print(render_markdown(rows))
|
||||
elif args.update_readme:
|
||||
changed = update_readme(rows)
|
||||
print("README.md updated" if changed else "README.md already current")
|
||||
else:
|
||||
print(render_matrix(rows))
|
||||
# A broken UNRELEASED line (master, -BETA, -RC) is a warning, not a build
|
||||
|
||||
Reference in New Issue
Block a user