Skip to content

Validate knowledge in CI ​

The pre-commit hook checks what each person commits. A CI job catches everything else: commits made with --no-verify, machines without kontext, teams that commit with jj (which runs no git hooks), entries whose paths stopped matching after a refactoring, and entries the change left behind.

kontext ci ​

sh
kontext ci [--base <rev>] [--format text|markdown] [--strict]

It runs two checks:

  1. kontext check over every entry: missing titles, unknown kinds, duplicate ids, malformed review_by or checked dates, high-confidence secrets (errors), and warnings such as a paths pattern that matches no file;
  2. drift over the committed range base..HEAD: active entries whose paths cover files the range changed, while their own file was not edited, retired or confirmed in it.

--base defaults to the merge base of HEAD with the remote's default branch (origin/HEAD, else origin/main, else origin/master). In a pull request that is where the branch started. The job needs that history: check out with fetch-depth: 0. In a shallow clone the base falls back to HEAD (base_source: fallback-none), the range is empty, the report says so, and --strict exits 3.

Exit statusWhen
1check found errors
2--strict and drift listed an entry
0otherwise; without --strict drift is a warning

--format markdown writes a report for a GitHub job summary or a pull request comment: the check summary, its findings, and a table of the drifted entries with the changed files and commits.

GitHub Actions ​

yaml
# .github/workflows/knowledge.yml
name: knowledge
on:
  pull_request:

jobs:
  kontext:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0            # drift needs the default branch's history
      - name: Install kontext
        run: curl -fsSL https://raw.githubusercontent.com/SemanS/kontext/main/scripts/install.sh | KONTEXT_VERSION=v0.4.0 sh
      - name: Check knowledge and list drift
        run: ~/.local/bin/kontext ci --base "origin/${{ github.base_ref }}" --format markdown | tee -a "$GITHUB_STEP_SUMMARY"
        shell: bash               # pipefail: the job fails when kontext ci does

The summary appears on the run's page. Add --strict to make drift fail the job, once the team is used to confirming entries: a reviewer then sees each listed entry confirmed (a one-line checked change), edited, superseded or retired in the same pull request.

To post the report as a pull request comment instead, write it to a file (kontext ci --format markdown > kontext.md) and hand it to a commenting action of your choice.

Other CI systems ​

Any runner with git works:

sh
curl -fsSL https://raw.githubusercontent.com/SemanS/kontext/main/scripts/install.sh | KONTEXT_VERSION=v0.4.0 sh
~/.local/bin/kontext ci --base origin/main

kontext check alone (exit status 1 on errors) is enough when you want validation without drift. For a structured result, kontext drift --base <rev> --head HEAD --json prints the entries.drift result.

What the installer checks ​

scripts/install.sh resolves latest to the newest release tag, downloads the archive for the platform and checks it against the release's SHA256SUMS (older releases: the binary against its manifest's sha256). It then runs kontext --version before installing. Each failure stops the script with its cause and installs nothing:

  • the download failed (network, rate limit): retry; nothing is built from an unreleased branch;
  • the release has no archive for this platform, or no checksum to verify it against;
  • the checksum does not match;
  • the binary cannot run here, usually a glibc older than the one it was built against (the release summary prints each Linux binary's glibc floor).

--from-source (or KONTEXT_FROM_SOURCE=1) builds the same tag with cargo instead:

sh
curl -fsSL https://raw.githubusercontent.com/SemanS/kontext/main/scripts/install.sh | KONTEXT_VERSION=v0.9.1 sh -s -- --from-source

How kontext checks itself ​

kontext's own repository runs the gates this guide recommends, in .github/workflows/ci.yml:

JobWhat
testcargo test --locked on Linux and macOS; the jj smoke test runs where jj is installed
msrv, fmt and clippyreads rust-version from Cargo.toml, runs cargo check --locked --all-targets, cargo fmt --check and clippy -D warnings on that toolchain
clippy (latest stable)the same lints on the newest stable; an early warning that does not block
windowscargo test --locked --no-run
evaluation setcargo test --test eval; the report is the job summary and an artifact
kontext ci on .aipull requests: kontext ci over the project's own knowledge, with fetch-depth: 0
docs build, docs en/sk paritypull requests: npm run docs:build without deploying; docs/en and docs/sk hold the same files
cargo denylicenses, bans and sources block; advisories are reported

Actions are pinned by commit SHA. A release tag must equal the version in Cargo.toml; the tests run again before any binary is built, and only the publish job may write the release.

Before tagging, scripts/release-check.sh builds the candidate and shows what it changes for its readers:

sh
PEER_DIR=~/src/peer KONTEXT_PREV=~/.local/bin/kontext KONTEXT_STORES=~/src/shop:~/src/lib scripts/release-check.sh

With PEER_DIR, it runs Peer's three integration suites against the candidate (skipped without it). For each store in KONTEXT_STORES, it reads every entry through entries.list and entries.get with the previous binary and the candidate, and prints per entry what differs in status, verification.kind, verification.verified, since.commits and the governing paths, with totals.

Useful additions ​

  • kontext log --json produces a machine-readable decision timeline, e.g. for a docs site.
  • kontext check also scans knowledge for secrets; set secrets.scan = "staged" locally if you want the hook to scan every staged file.

Released under the MIT or Apache-2.0 license.