Skip to content

allez audit

Check, offline, that parameter.yml rewrites every environment-specific id. The audit reads the item files and parameter files of every sub-folder, for every environment the root allez.yml declares, and names each id no rule rewrites. It makes no Fabric call, so it runs on a laptop or as a pull request check with no credentials.

Only the items a deploy would publish are scanned: the publish filters and item_types_in_scope in each dag node's config.yml apply (publish filters). An item a filter excludes is never reported.

Usage

allez audit [OPTIONS] [PATH]

Arguments

Argument Description
PATH Solution root (fabric/) or a single workspace sub-folder. Default: .

Options

Option Description
--env, -e <name> Check one environment. Default: every environment the root allez.yml declares. An undeclared name is a load error.
--ignore <guid> An id that is the same in every environment, so it is skipped. Repeatable.
--strict A rule that matches nothing fails the audit too.
--junit-xml <path> Write JUnit XML with one testcase per scanned file, for PublishTestResults@2.

Findings

Finding Fails the audit Meaning
uncovered yes A GUID in the file of a published item that no rule rewrites. It deploys as committed into every environment.
env-gap yes A rule rewrites it, but has no replace_value for that environment and no _ALL_. fabric-cicd leaves the committed value in place.
dead-rule with --strict A rule that matches nothing any visit publishes. Usually an item was renamed, removed or excluded by a publish filter.
order no A rule or token that resolves before the thing it names is published, on a deploy into empty workspaces. fabric-cicd does not fail when a $items lookup finds nothing: it logs, skips the rule and publishes the committed value.

Every finding names the file and the line. On an Azure Pipelines agent each one is also a logissue annotation, so it shows on the run summary linked to the file.

Examples

allez audit fabric                       # every environment
allez audit fabric --env prod            # one
allez audit fabric --ignore 3f2a9c1e-…   # this id is the same everywhere
allez audit fabric --strict              # dead rules fail too
allez audit fabric --junit-xml out.xml   # for the Tests tab

The output is one block per sub-folder: how many ids were scanned and how many skipped as Fabric's own bookkeeping, the environments checked, then each finding. The last line says whether the audit passed and counts each finding kind.

The order check

The order check assumes every workspace starts empty, as on the first deploy into a new environment. A $allez.<sub-folder>.$items… token resolves before its own node publishes, so the node that publishes that sub-folder must come earlier in the dag; a token that names an item in its own sub-folder is the common mistake. fabric-cicd also publishes one item type at a time, so a $items rule on a type that publishes before the item it names resolves to nothing. A workspace that already holds the item resolves fine, which is why order is a warning.

Accepting a finding

Some findings are the design. A connection or a reference lakehouse that every environment shares is uncovered, and a feature workspace that reads prod's files on purpose warns order every run. Record that in the sub-folder's own allez.yml, with the reason:

fabric/allez-data/allez.yml
audit:
  accept:
    - kind: uncovered
      file: Notebook.Notebook/notebook-content.py
      value: 5d1c3a7e-2b4f-4e8a-9c6d-0f1e2a3b4c5d
      reason: the shared reference-data workspace is the same in every environment

An order entry can be scoped to the environments where it is the design, with environments: [feature, dev].

Key Required What it matches
kind yes uncovered, env-gap, dead-rule or order.
value yes What the finding names, as the audit prints it: the id, the find_value, or the replacement or token. Case doesn't matter.
file no The file the finding is in, relative to the sub-folder. Leave it out to match the value in any file of the sub-folder.
environments no For env-gap and order only: the environments it's accepted in. Leave it out for all of them.
reason yes Why it's the design. It's printed with the finding.

An accepted finding is still printed, dimmed, with its reason. It doesn't count in the summary, fail the run, annotate the pipeline log or appear in the editor's Problems panel. An entry that no longer matches any finding warns unused-accept on its own line, and fails the run with --strict, so the list can't go stale quietly. A bad entry (an unknown kind, no reason, an environment the root doesn't declare) fails every verb at load, naming the file and the key.

In the pipeline

Run it as a required check on pull requests into main, with --junit-xml and PublishTestResults@2 so each file shows on the run's Tests tab. It needs no service connection. The example's validate.yml does this.

Behaviour

  • Offline. No fab call, no credential, no file written except the JUnit file you ask for.
  • Exit code. Non-zero on uncovered or env-gap, and on dead-rule or unused-accept with --strict. order never fails it. An accepted finding never does.
  • Static. It proves a rule matches an id, not that the replacement is right, so a reviewer should still read parameter.yml changes.
  • A rule covers what it captures. An is_regex rule covers its capture group, not the whole match. A OneLake URL holds a workspace id and an item id on one line, so a rule that captures one leaves the other uncovered.
  • key_value_replace is approximate. allez does not evaluate the find_key JSONPath; the path's last key on the id's line counts as a match, so a wrong path can pass here and do nothing at publish.
  • Fabric's own ids are skipped and counted. .platform logical ids, references to an item in the same sub-folder, TMDL lineageTags and similar bookkeeping. The count is printed, so "nothing to check" is never mistaken for "nothing looked at".
  • The same findings in the editor. The VS Code extension shows them in the Problems panel at the file and line each one names, through allez document.