Skip to content

Workbook CI and SARIF

wolfxl-ci turns the existing WolfXL Guard comparison into a CI-native contract. It evaluates one baseline/candidate pair, writes the canonical Guard JSON report, projects findings into SARIF 2.1.0, and exits non-zero for either a regression or an unassessed policy dimension.

wolfxl-ci \
  --before tests/fixtures/baseline.xlsx \
  --after build/candidate.xlsx \
  --policy .wolfxl/guard-policy.json \
  --json-report build/wolfxl-guard.json \
  --sarif-report build/wolfxl-guard.sarif

Omit --policy to use Guard's strict default policy. Report writes are atomic, JSON keys and SARIF results are sorted, and absolute host paths are not emitted. The candidate workbook location in SARIF is repository-relative when possible and falls back to its filename otherwise.

GitHub Actions

Install the exact WolfXL version first, then run wolfxl-ci as a workflow step. The step needs no registry credentials of its own.

permissions:
  contents: read
  security-events: write

steps:
  - uses: actions/checkout@v4

  - name: Install the pinned WolfXL build
    run: python -m pip install --require-hashes -r requirements-wolfxl.txt

  - name: Build candidate workbook
    run: python scripts/build_report.py

  - name: Verify workbook fidelity
    run: >-
      rm -f wolfxl-guard.json wolfxl-guard.sarif &&
      wolfxl-ci
      --before tests/fixtures/baseline.xlsx
      --after build/candidate.xlsx
      --policy .wolfxl/guard-policy.json
      --json-report wolfxl-guard.json
      --sarif-report wolfxl-guard.sarif

  - name: Upload SARIF
    if: always() && hashFiles('wolfxl-guard.sarif') != ''
    uses: github/codeql-action/upload-sarif@v3
    with:
      sarif_file: wolfxl-guard.sarif

  - name: Retain canonical evidence
    if: always() && hashFiles('wolfxl-guard.json') != '' && hashFiles('wolfxl-guard.sarif') != ''
    uses: actions/upload-artifact@v4
    with:
      name: wolfxl-evidence
      path: |
        wolfxl-guard.json
        wolfxl-guard.sarif

Uploading SARIF to GitHub code scanning depends on the repository's GitHub security-plan configuration. Retaining the two report artifacts works without code scanning. The evidence step runs only when both reports exist, so a partial bundle is never retained. Removing old reports before the check runs keeps a failed preflight from uploading stale evidence from an earlier run.

Exit codes

Code Meaning
0 Every assessed policy dimension passed.
1 At least one dimension failed or remained unassessed.
2 Inputs, policy, or output paths were invalid.
3 An unexpected internal error prevented evaluation.

Workbook CI does not assert calculation correctness, rendered appearance, or macro execution unless a separate workflow supplies those proofs. SARIF is a projection of Guard; it is not a second verification engine.