Skip to content
docs-bundle okf-loom wiki
GraphIndex

Live studio unavailable. Showing a read-only view. Browse the index.

How-to 3 min read

Validate a bundle in CI

Enforce OKF conformance in CI by picking a validation profile and wiring the strict validate command into GitHub Actions or GitLab CI.

/how-to/validate_in_ci.md civalidategithub-actionsgitlab

Validate a bundle in CI

This guide turns validation into a CI gate that fails a pull request or merge request the moment a concept breaks conformance or a recommended key goes missing.

You already have a bundle on disk and a cloned okf-loom checkout with a working okf command or source-checkout invocation. If you do not, start with Use okf-loom from a clone and Author your first bundle.

Step 1: Pick a validation profile

The validator ships three profiles that remap finding severities for different audiences without changing the wire format.

ProfileWhen to useWhat it does
spec (default)Lightweight gate, spec conformance only.Only type is required; everything else is a warning.
producerProducer-side CI that wants rich metadata enforced.spec plus concept.missing_recommended_keys promoted to ERROR.
looseIngesting incomplete docs that lack type.concept.missing_type downgraded to WARNING.

For a documentation bundle that you fully own, producer is usually the right choice: it keeps titles, descriptions, and timestamps honest.

For a bundle that ingests third-party markdown, loose lets the pipeline land before you backfill type.

--fail-on-broken-links is orthogonal to the profile and promotes link.broken findings to ERROR.

Use it when you want to block a release on dangling links, and leave it off when you treat forward references as not-yet-written knowledge (see Link forms).

Step 3: Verify the exit codes locally

The validator exits 0 for conformant, 1 for conformance failure, and 2 for strict failure.

scripts/okf-loom validate path/to/bundle --strict --profile producer --fail-on-broken-links
echo "exit code: $?"

The exit codes you will see:

CodeMeaning
0Conformant; no errors.
1Conformance failure (a concept is missing type, or frontmatter is unparseable).
2Strict failure (--strict was passed and warnings were promoted to errors).

CI only needs to fail on non-zero, so any of 1 or 2 blocks the pipeline.

Step 4: Wire it into GitHub Actions

Put the bundle path and the validate command in a workflow under .github/workflows/.

# .github/workflows/okf-validate.yml
name: OKF validate
on:
  pull_request:
    paths:
      - 'docs-bundle/**'
      - '.github/workflows/okf-validate.yml'
jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      - name: Validate bundle
        run: |
          scripts/okf-loom validate docs-bundle \
            --strict \
            --profile producer \
            --fail-on-broken-links

The workflow fails the PR on any non-zero exit code; the paths: filter only runs when bundle files actually change.

Step 5: Wire it into GitLab CI

The same command drops into a .gitlab-ci.yml job.

# .gitlab-ci.yml
okf:validate:
  image: python:3.11
  rules:
    - changes:
        - docs-bundle/**/*
        - .gitlab-ci.yml
  script:
    - scripts/okf-loom validate docs-bundle --strict --profile producer --fail-on-broken-links

GitLab treats any non-zero exit from script: as a job failure, so the gate is identical to the GitHub Actions case.

Step 6: Produce JSON for downstream tooling

Pass --format json to emit a machine-readable report that other CI steps can consume.

scripts/okf-loom validate docs-bundle --profile producer --format json > okf-report.json

The JSON object carries the totals and the per-finding rows:

{
  "ok": false,
  "errors": 1,
  "warnings": 3,
  "info": 0,
  "findings": [
    {
      "code": "concept.missing_recommended_keys",
      "severity": "error",
      "concept": "tables/orders",
      "message": "missing recommended key: description"
    }
  ]
}

A common pattern is to upload that file as a CI artifact and surface the per-finding rows in a PR comment.

Step 7: Lock the defaults in okf-loom.config.yaml

You can avoid repeating the profile and broken-link flag in every job by pinning them in the bundle config.

validate:
  default_profile: producer
  fail_on_broken_links: true

With those set, scripts/okf-loom validate docs-bundle --strict honours the bundle's defaults; CI scripts stay short. See okf-loom.config.yaml reference for every key.

End state

You now have a CI gate that:

  • Runs scripts/okf-loom validate on every change to the bundle.
  • Fails the pipeline on conformance errors, missing recommended keys (producer profile), and broken links.
  • Emits a JSON report you can archive or comment onto a PR.

See also

Return to How-to guides.

All fields
timestamp2026-06-29T00:00:00Z