netviz GitHub

netviz review

netviz review writes up a change to the network the way a reviewer would want it: what changed, what that broke that was not already broken, and the change drawn. It is netviz plan, netviz diff and netviz validate reduced to one Markdown document.

The document is the body of a pull-request comment — that is what it was built for, and docs/ci.md has the action and the workflow that post it. But it is a command like any other, so the review of a branch can be read before it is pushed:

$ netviz --inventory inventory review --from origin/main

netviz review writes nothing to the inventory and never talks to a device.

Contents


Synopsis

netviz [GLOBAL OPTIONS] review [OPTIONS]

Where the two sides come from

--from is required, because a review is a comparison and there is no sensible default for "before". Both sides are read exactly as netviz plan reads them: a path that exists as a directory is a folder, anything else is handed to git and exported read-only.

Invocation Before After
review --from origin/main the git ref the working tree
review --from HEAD the last commit the working tree
review --from a --to b folder a folder b

Two cases that would be a mistake anywhere else are not mistakes here:

What the document says

A verdict line, so that a reader who reads nothing else has been told whether to look further:

### ❌ netviz — 3 elements change, 1 new error introduced

A table of what changed, grouped by kind. Three cables and a switch is the shape of a change; the same list sorted by action buries the one switch among the thirty cables.

Kind Added Changed Renamed Removed
cable 3 - - 1
switch - 1 - -

The elements themselves follow in a collapsed block, one row each, bounded by --max-changes and saying how many it left out.

The findings this change introduced, each with its rule linked to the write-up in validation-rules.md and its location linked to the line — when --repository-url and --head-sha say where the lines are. Everything that is not new is one sentence: how many were fixed, how many were left alone.

The drawing. See below.

Only new problems fail it

Both states are validated, and what the document reports is the difference. An inventory carrying three legacy warnings is reviewed green on the first change that touches it; the fourth warning, added by that change, is reported.

Identity is the fingerprint netviz validate -F sarif puts on each result — the rule, the file, the element, the pointer and the message, and deliberately not the line — so inserting a document above a broken one does not report everything below it as newly introduced, and the review agrees with GitHub's code-scanning alert list about which problem is new.

--strict and --disable are applied to both sides. Grading them differently would report a rule silenced in this very change as a wave of fixes.

The drawing

netviz review draws nothing itself. It embeds a small Mermaid summary of the changeset — the changed elements, boxed by namespace, coloured by action — which renders natively in a GitHub comment, and it links whatever netviz diff has already written:

$ netviz -i inventory diff --from origin/main -f svg -o diff.svg
$ netviz -i inventory diff --from origin/main -f png -o diff.png
$ netviz -i inventory review --from origin/main --diagram diff.svg --diagram diff.png \
      --artifact-url "$RUN_URL#artifacts" --artifact-name netviz-review

--diagram takes [LABEL=]PATH; the label defaults to the suffix, upper-cased. A rendering given with --diagram alone is linked, through --artifact-url. One given with --diagram-url is embedded as an <img>.

The distinction is GitHub's, not netviz's: a comment body is sanitised, so an inline <svg> element is stripped and an <img src="data:..."> is refused by the image proxy. Only a URL a browser can fetch — a published page, an object store — can be embedded, and a run artifact is a zip behind an authenticated endpoint. That is why the Mermaid summary is there: it is the one drawing that always appears.

The side documents

Three optional files, so that the run which produced the comment also produced everything else a pipeline wants, from the same load and the same validation:

Flag What it writes
--plan-out The changeset, byte-identical to netviz plan --json. Not written when the head does not load.
--sarif-out The head's findings as SARIF, for github/codeql-action/upload-sarif.
--summary-out The verdict and the counts, for a workflow step that gates on them.

--summary-out is what a shell should read; nothing should parse the comment.

{
  "schemaVersion": 1,
  "tool": {"name": "netviz", "version": "0.0.3"},
  "verdict": "failed",
  "broken": false,
  "changed": true,
  "changes": 3,
  "new": {"error": 1, "warning": 1, "info": 1, "total": 3},
  "fixed": 0,
  "carried": 2,
  "baseAbsent": false
}

verdict is one of passed (nothing new is wrong), warned (new warnings or infos, no new errors), failed (new errors) or broken (the head state does not load).

When the head does not load

There is no changeset and no diagram, and the document says so instead of reporting a change nobody made — a document that was rejected is absent from the inventory, so diffing against it would read as a deletion. The findings table still lists every rejected document, which is what a reviewer needs in exactly that case. The verdict is broken, and --fail-on exits 1 for it whatever else it was set to, short of never.

Options

Flag Value Default Meaning
--from REF|DIR The state before the change: a git ref (origin/main) or a folder. This is the baseline every finding is measured against, so a problem it already had is not reported as one this change introduced.
--to REF|DIR The state after the change. Defaults to the inventory as it is on disk.
-o, --output FILE Write the comment body here instead of to stdout.
--plan-out FILE Also write the changeset as JSON, the document 'netviz plan --json' writes.
--summary-out FILE Also write the verdict and the counts as a small JSON document, so a workflow can gate on them without reading the comment's prose.
--sarif-out FILE Also write the head state's diagnostics as SARIF, for a code-scanning upload. It is the same validation the comment reports, so the two cannot disagree.
--diagram [LABEL=]PATH A rendering of the visual diff to link, as 'netviz diff -o' wrote it. The label defaults to the suffix, upper-cased. Repeatable.
--diagram-url [LABEL=]URL Where a rendering is published, if it is somewhere a browser can fetch it. Those are embedded in the comment; a --diagram with no URL is only linked. Repeatable.
--artifact-url URL Where the whole bundle can be downloaded -- in CI, the run that produced it.
--artifact-name NAME What that bundle is called, for the link text.
--repository-url URL Base URL of the repository, https://github.com/owner/repo. With --head-sha it turns every finding into a permalink to the line it is anchored at.
--head-sha SHA Commit the head state is, so the links are permalinks rather than branch links.
--title TEXT netviz Heading of the comment, and the key of its sticky marker. Two inventories reviewed in one repository need two titles, or they will overwrite each other's comment.
--strict off Promote every warning to an error, on both sides of the comparison.
--disable RULE Silence a rule by id, on both sides. Repeatable.
--no-renames off Report every rename as a deletion beside a creation rather than as one move.
--max-changes N 40 How many elements the changeset table names before it says how many are left.
--max-findings N 25 The same, for the table of new findings.
--fail-on [new-errors|new-findings|changes|never] new-errors What exits 1. 'new-errors' is the one a pull-request check should use: an error the base already had is not this change's to fix, and gating on it would mean no repository with a legacy finding could ever adopt the check.

Exit codes

Code When
0 The review was written, and --fail-on is satisfied.
1 --fail-on says so — by default, the change introduced an error the base did not have, or the head state does not load. Also: a ref that cannot be read.
2 Usage: no --from, or an empty --diagram.

The document is written before the exit code is decided, so a workflow that uploads it always has something to upload.

See also