Use the Clojure CLI. Run all commands from the repository root. See tool installation for pinned Java, Clojure CLI, format, lint, and prose tools.
Test suites share the test/ parent directory:
test/runtime/: library and benchmark support tests.test/build/: build and artifact tests.test/release/: release tooling tests.test/tooling/: development tool tests.test/bench/: measurement tests with separate dependency and JVM requirements.Each suite has a separate source path. Select the suite directory explicitly;
The default scry discovery scans all of test/.
Run the runtime tests on Clojure 1.11:
clojure -M:test -m scry.cli --dir test/runtime
Run the tests on Clojure 1.12 and on Clojure 1.13:
clojure -M:test:clj-1.12 -m scry.cli --dir test/runtime
clojure -M:test:clj-1.13 -m scry.cli --dir test/runtime
Start a REPL. The nREPL server writes the port to .nrepl-port:
clojure -M:test:nrepl
Run the tests in the REPL:
(require '[scry.core :as scry])
(scry/run {:dirs ["test/runtime"]})
Run the benchmarks against defrecord (about 6 minutes):
sh dev/bench/timing/run.sh
The launcher prepares a checksum-verified local correction to Criterium
0.5.251-ALPHA before starting the benchmark. It retains the source overlay under
target/ for child JVMs. The correction prevents a zero planning duration; it
does not change raw samples. Direct clojure -M:bench bypasses this preparation
and selects the uncorrected upstream tool.
See performance measurements for the fixed matrix, memory metrics, experimental runtime requirements, and saved evidence.
CI runs on pushes to master and pull requests
against any branch, including forks. All jobs use Ubuntu and read-only repository permissions.
Clojure jobs use Temurin Java 21 and Clojure CLI 1.12.6.1673.
The separate Markdown links job uses Babashka and lychee, not Java or Clojure CLI.
The release workflow calls CI, so a CI failure stops a release.
The code-quality job uses cljfmt 0.16.4 and clj-kondo 2026.04.15.
Run the same non-writing checks locally:
bb clj-fmt:check
bb clj-kondo:lint
bb vale
bb api-docs --check
See quality checks for scopes, generated files, focused
tests, and hook installation. The quality job also uses Vale 3.17.1 and
pre-commit 4.6.0, and runs the focused tooling tests.
Formatting differences, lint warnings, lint errors, prose warnings and errors,
and stale API output fail the job.
The runtime matrix runs the three test commands above; deps.edn owns
the Clojure versions. A separate job runs the build tests and JAR command
below once, with full Git history. A separate job runs the release tests. Performance benchmarks remain manual.
Failed tests upload .scry-results/ as scry-runtime-1.11,
scry-runtime-1.12, scry-runtime-1.13, scry-build, scry-release, or scry-tooling. These artifacts
contain structured failure data. Missing result files produce a warning;
the test failure still fails the job. CI does not publish releases or
configure branch protection.
Build the source-only JAR for org.hugoduncan/closed-record:
clojure -T:build jar
The build writes target/closed-record-<version>.jar and generates the POM
at target/classes/META-INF/maven/org.hugoduncan/closed-record/pom.xml.
The JAR contains runtime source, Maven metadata, and the EPL-2.0 license.
Build tools are not runtime dependencies.
The version is 0.1.<count>, where <count> is the output of
git rev-list --count HEAD. Git and repository history are required;
version lookup failure stops the build. Use a full checkout for a
release-quality build. A shallow checkout can give a smaller count.
Each build removes stale output from target/ before packaging.
Run the separate build tests, including a consumer JVM that loads the JAR:
clojure -M:test:build-test -m scry.cli --dir test/build
Remove build output:
clojure -T:build clean
clean is safe to repeat and does not require Git metadata. Generated
output under target/ is ignored by Git. These build and clean commands do not install or
deploy the artifact; there is no published Clojars release yet.
Run the separate release tooling tests (pure notes and real Git fixtures):
clojure -M:test:release:release-test -m scry.cli --dir test/release
Install Git, Babashka 1.13.225, and lychee 0.24.2. These are development
tools, not library dependencies. The following Bash commands select the pinned
archives for Linux x86-64 or macOS arm64/x86-64, verify SHA-256 checksums,
and install the binaries in $HOME/.local/bin. They require curl and tar;
checksum verification uses shasum (macOS) or sha256sum (Linux).
(
set -euo pipefail
case "$(uname -s)-$(uname -m)" in
Linux-x86_64) bb_platform=linux-amd64-static; lychee_platform=x86_64-unknown-linux-gnu ;;
Darwin-arm64) bb_platform=macos-aarch64; lychee_platform=aarch64-apple-darwin ;;
Darwin-x86_64) bb_platform=macos-amd64; lychee_platform=x86_64-apple-darwin ;;
*) echo "Unsupported platform" >&2; exit 1 ;;
esac
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT
cd "$tmp"
bb_archive="babashka-1.13.225-$bb_platform.tar.gz"
lychee_archive="lychee-$lychee_platform.tar.gz"
bb_base=https://github.com/babashka/babashka/releases/download/v1.13.225
lychee_base=https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2
for url in "$bb_base/$bb_archive" "$lychee_base/$lychee_archive"; do
archive=${url##*/}
curl -fsSL "$url" -o "$archive"
curl -fsSL "$url.sha256" -o "$archive.sha256"
# Babashka supplies only the digest; lychee also supplies the filename.
printf '%s %s\n' "$(awk '{print $1}' "$archive.sha256")" "$archive" > checksum
if command -v sha256sum >/dev/null; then
sha256sum --check checksum
else
shasum -a 256 --check checksum
fi
tar -xzf "$archive"
done
mkdir -p "$HOME/.local/bin"
install -m 755 bb "lychee-$lychee_platform/lychee" "$HOME/.local/bin/"
) || exit $?
export PATH="$HOME/.local/bin:$PATH"
bb --version # babashka v1.13.225
lychee --version # lychee 0.24.2
From the repository root, run:
bb dev/link_check_test.clj
bb lychee:check
The fixture suite uses temporary Git repositories, real tools, and a loopback
HTTP server. The default check needs network access. It checks all Git-tracked
*.md files, including hidden directories and historical tasks. Untracked files
and generated output are not input documents. Relative links use their source
document; root-relative links use the checkout root. Local files, directories,
and Markdown heading fragments are checked. HTTP and HTTPS checks follow
redirects and verify TLS; external fragments, email, and other protocols are
outside scope.
The command runs a local fragment pass and an online pass. Missing tools, invalid configuration, missing targets or headings, and failed web requests produce a nonzero exit. Request timeouts and retries are bounded. Diagnostics identify the source and failed link. Neither pass rewrites documents or writes reports or caches. CI runs the fixtures and the same task once, outside the runtime matrix.
Shared policy is in lychee.toml and dev/link_check.clj. No URL exceptions
are currently needed. If a legitimate URL cannot be checked, add only an exact,
anchored URL exclusion in lychee.toml, with a comment that explains why.
Do not exclude document trees or accept error status codes to make checks pass.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |