Skip to content

Run it in CI

This page runs three term jobs on every pull request. check fails on a broken reference and annotates the line. write -f vale --check fails when the committed Vale style has fallen behind the set. lint holds the definitions to the house voice. All three read the same manni.config.yaml as a local run.

The recipes run npx, which fetches the published package on demand. The runner needs Node.js 24 or newer, and the steps that run Vale need it on PATH.

Exit codes drive the gate. They are the family’s:

CodeMeaning
0No error-severity finding, or --check found the style up to date.
1At least one error-severity finding the baseline does not hold, or --check found a file that differs.
2The job could not run. No terms, no Vale on PATH, a bad flag or a bad config key. The message goes to stderr, prefixed manni:.

Warnings and notices never fail the job. asymmetric-hierarchy is a warning, and abstract-too-long and unused-term are notices. Every other check rule is an error. term.severity moves any of them; see the rules reference.

-f github produces inline annotations. One workflow command per finding, on the file and line, titled with the rule id:

Terminal window
$ manni term check -f github
::error file=docs/guides/fitting.md,line=3,title=manni%3Aterm/undefined-term::concepts: "PAL" names no entry. "progressive lens" lists it as an alt-label.

lint -f github prints the same shape, under manni:term/prose/<Style.Rule>:

Terminal window
$ manni term lint -f github
::warning file=docs/terms/kubernetes.md,line=7,title=manni%3Aterm/prose/House.Simply::Drop 'Simply'.
::warning file=docs/terms/kubernetes.md,line=11,title=manni%3Aterm/prose/House.Simply::Drop 'just'.
::error file=docs/terms/progressive-lens.md,line=9,title=manni%3Aterm/prose/House.Length::Keep a sentence under 20 words.

json, sarif and junit are there for dashboards, code scanning and the test tab. The CLI reference has each shape.

  1. Declare the docset and Vale’s configuration in manni.config.yaml, so each job runs with no arguments:

    manni.config.yaml
    collections:
    - name: site
    paths:
    - "docs/**/*.md"
    tools:
    vale:
    config: .vale.ini
  2. Commit the generated style. Run manni term write -f vale locally and commit Terms/ under your styles directory, beside .vale.ini.

  3. Add the workflow.

    .github/workflows/terms.yml
    name: Terms
    on:
    pull_request:
    jobs:
    check:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v7
    - uses: actions/setup-node@v6
    with:
    node-version: 24
    # Every concepts: value names an entry, and the set is consistent.
    - run: npx -y @hawkeyexl/manni term check -f github
    vale:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v7
    - uses: actions/setup-node@v6
    with:
    node-version: 24
    # The latest Vale release, onto PATH for both manni jobs below.
    - name: Install Vale
    env:
    GH_TOKEN: ${{ github.token }}
    run: |
    gh release download --repo errata-ai/vale --pattern '*_Linux_64-bit.tar.gz' --output vale.tar.gz
    tar -xzf vale.tar.gz -C "$RUNNER_TEMP" vale
    echo "$RUNNER_TEMP" >> "$GITHUB_PATH"
    - run: vale sync
    # The committed Terms style matches the set.
    - run: npx -y @hawkeyexl/manni term write -f vale --check
    # The definitions hold to the house voice.
    - run: npx -y @hawkeyexl/manni term lint -f github
  4. Open a pull request. A concepts: value that names no entry fails the check job and annotates the line. A term edited without regenerating the style fails the vale job, and its log names each file that would change.

A failing --check prints what differs:

Terminal window
$ manni term write -f vale --check
.vale/styles/Terms/Deprecated.yml would change
$ echo $?
1

The fix is local. Run manni term write -f vale, and commit the result.

A docset whose concepts: values were never checked fails its first run. The baseline lets the check go in without fixing that backlog first.

  1. Record the backlog once. With no baseline file yet, --baseline records every current finding and exits 0:

    Terminal window
    $ manni term check --baseline
    ✓ 1 finding recorded in .manni-term-baseline.json

    Commit .manni-term-baseline.json.

  2. Run the job with the same flag. A finding the file holds is counted as baselined. Only a new one fails:

    Terminal window
    $ manni term check --baseline
    ✓ 2 terms, 3 references, no findings, 1 baselined

    The job line becomes npx -y @hawkeyexl/manni term check -f github --baseline.

  3. Burn the backlog down. Fix findings as pages are touched. Delete the file and run --baseline again to record the smaller backlog.

To compare on every run without the flag, name the file under term::

manni.config.yaml
term:
baseline: .manni-term-baseline.json

With the key set and no file on disk, the run stops with exit 2, and says how to record one.

Open a pull request that adds an alt-label to a guide’s concepts:. Then check that:

  • The check job is red, and the guide carries an annotation titled manni:term/undefined-term that names the entry claiming the alt-label.
  • A pull request that adds a term nothing references stays green, with a manni:term/unused-term notice.
  • A pull request that adds a hidden-label without running write -f vale fails the vale job with Terms/Deprecated.yml would change.