Skip to main content

Module ci

Module ci 

Source
Expand description

The checks that just ci runs for a diff.

§Design

just ci runs only the checks that the diff of the branch can break (01M3WNMKB6PAP6J0QXX4A684HH). hygiene ci [BASE] finds each file that differs from the merge base of HEAD and BASE (the default is origin/main): committed, not committed, and not tracked. Then choose gives the recipe of the justfile to run:

RecipeChecksWhen
ci-textbook, reqs, wrap, versionsEach changed file is text.
ci-fullEach check.Each other case.

A file is text (is_text) when it is in docs/ or design/, or when it is a .md file outside crates/. A .md file in crates/ is not text: tests read them.

When git cannot compare with BASE, or when no file differs, the recipe is ci-full. hygiene ci prints the recipe to stdout and one line for the person to stderr: the set, and why. The Gate on GitHub runs the checks of just ci-full as jobs at the same time (01M3WNN7VQJKN5MJH7JN50VF4D, 01M513W2K3HNRWPQTQNBQPT8MZ). See crate::part.

§The check of an author: just check

The Gate on GitHub runs each check of just ci-full: the one full run of each pushed commit (01M49HAZ5BZYGAR9PGC089RM3F). Before a push, an author runs just check (01M49HAZA5K08XW2JQ11TG87JP): the fast checks (fmt-check, lint, doc, book, reqs, wrap, versions) and the tests of the crates that the diff touches. hygiene crates [BASE] prints the arguments of cargo test for these crates (tests), and one line for the person to stderr. A text file needs a test here: the tests read the book, CLAUDE.md and the requirements.

flowchart LR
    D["the changed files"] --> T{"each file"}
    T -- "in crates/NAME/" --> C["NAME, and each crate<br/>that depends on it"]
    T -- "each other file,<br/>also text" --> W["--workspace"]

§One run at a time in a worktree

Two runs in one worktree share its target. Each waits for the cargo lock of the other, and the load and the time double. So just ci and just ci-full first source crates/hygiene/ci-lock.sh and call ci_lock (01M43DKYVAX0TJ2F5YYGYFSZ4G). The check is shell, not this crate: cargo run of a second run waits for the build lock of the first run, so it cannot stop at once.

flowchart TD
    S["just ci"] --> E{"RIFF_CI_LOCK set?<br/>(the holder started this run)"}
    E -- yes --> R["run the checks"]
    E -- no --> C{"create target/.riff-ci.lock<br/>(fails when it exists)"}
    C -- created --> H["hold it: pid, start time;<br/>remove it at the exit"] --> R
    C -- exists --> L{"does its pid run,<br/>with the same start time?"}
    L -- yes --> X["one line, exit 1"]
    L -- no --> D["remove the old lock"] --> C

The pid and the start time of ps -o lstart= name one process, so a new process with the same pid does not hold the lock. The lock is in the target of the worktree, so runs in two worktrees go on.

use hygiene::ci::{choose, Checks};

let text = ["design/reviews/x.md".to_owned()];
let choice = choose("origin/main", Some(&text));
assert_eq!(choice.checks, Checks::Text);
assert_eq!(choice.checks.recipe(), "ci-text");

let code = ["docs/src/waves.md".to_owned(), "justfile".to_owned()];
let choice = choose("origin/main", Some(&code));
assert_eq!(choice.checks, Checks::Full);
assert_eq!(
    choice.to_string(),
    "just ci runs each check: justfile is not a text file"
);

Structs§

Choice
The set that just ci runs, and why.
Member
A crate of the workspace, as cargo metadata --no-deps gives it.
TestChoice
The tests that just check runs, and why.

Enums§

Checks
A set of checks: a recipe of the justfile.
Tests
The tests that just check runs.

Functions§

choose
The set for the files changed that differ from the merge base with base. None says that git cannot compare with base.
is_text
True when no code check can fail from a change of the file path. path is relative to the top of the repository.
tests
The tests for the files changed that differ from the merge base with base (01M49HAZA5K08XW2JQ11TG87JP): the tests of each crate with a changed file, and of each crate that depends on one of them, also through another crate. Each file outside the crates, for example Cargo.lock, the justfile or a page of the book, needs the tests of each crate: a test can read it. None says that git cannot compare with base: then each crate.