The canonical hive release tasks, delivered as a library.
Point a repository's :build alias here and it inherits the whole release path — no build.clj to copy, and no build.clj to drift:
:build {:deps {io.github.hive-agi/hive-build {:mvn/version "0.1.0"}} :ns-default hive-build.api}
Coordinates come from ./version.edn, the version from ./VERSION:
{:lib io.github.hive-agi/hive-thing :minor 1 :license {:name "MIT" :url "https://opensource.org/licenses/MIT"} :scm-url "https://github.com/hive-agi/hive-thing" :src-dirs ["src"] :publish :clojars ; :clojars | :gitea | :gitea-source | :none :aot/java-opts [] ; optional, AOT compile only :aot/elide-meta [] ; optional, [] disables metadata elision :aot/publishable-sources [] ; optional, entry prefixes whose sources ship :aot/strict-opacity false ; optional, overrides the target's default: ; a PRIVATE target (:gitea) fails a leak, ; a public one only reports it :pom-exclude-deps []} ; optional, dropped from the published pom
An untracked ./local.deps.edn may supply a :provided alias (host sources
that must be on the AOT compile classpath but must NOT enter the pom) and an
:aot/preload namespace vector compiled ahead of this lib's own namespaces.
:publish is the ONLY thing that differs between packages — the task names
are identical everywhere, so one CI workflow drives the whole fleet:
:clojars public source jar -> repo.clojars.org :gitea AOT no-source jar -> private Gitea Maven registry :gitea-source source jar -> private Gitea Maven registry :none builds, never ships
Tasks (invoke with clojure -T:build <task>):
clean delete target/
jar source jar + pom
jar-aot AOT no-source jar (own .class + resources only)
install build + install to ~/.m2 (offline)
kondo sync dependency-exported lint configs, then lint
bump rewrite ./VERSION (:level :patch|:minor|:major)
verify-license report LICENSE / version.edn / SPDX agreement (warns)
audit-opacity report private strings a built jar still carries (warns)
freeze-check refuse a release that breaks ./freeze-policy.edn (fails)
deploy build + publish per :publish (no-op when :none)
Release flow (what CI runs on a push to main that touches src/deps): clojure -T:build bump :level :patch clojure -T:build deploy
The canonical hive release tasks, delivered as a library.
Point a repository's :build alias here and it inherits the whole release
path — no build.clj to copy, and no build.clj to drift:
:build {:deps {io.github.hive-agi/hive-build {:mvn/version "0.1.0"}}
:ns-default hive-build.api}
Coordinates come from ./version.edn, the version from ./VERSION:
{:lib io.github.hive-agi/hive-thing
:minor 1
:license {:name "MIT" :url "https://opensource.org/licenses/MIT"}
:scm-url "https://github.com/hive-agi/hive-thing"
:src-dirs ["src"]
:publish :clojars ; :clojars | :gitea | :gitea-source | :none
:aot/java-opts [] ; optional, AOT compile only
:aot/elide-meta [] ; optional, [] disables metadata elision
:aot/publishable-sources [] ; optional, entry prefixes whose sources ship
:aot/strict-opacity false ; optional, overrides the target's default:
; a PRIVATE target (:gitea) fails a leak,
; a public one only reports it
:pom-exclude-deps []} ; optional, dropped from the published pom
An untracked ./local.deps.edn may supply a `:provided` alias (host sources
that must be on the AOT compile classpath but must NOT enter the pom) and an
`:aot/preload` namespace vector compiled ahead of this lib's own namespaces.
`:publish` is the ONLY thing that differs between packages — the task names
are identical everywhere, so one CI workflow drives the whole fleet:
:clojars public source jar -> repo.clojars.org
:gitea AOT no-source jar -> private Gitea Maven registry
:gitea-source source jar -> private Gitea Maven registry
:none builds, never ships
Tasks (invoke with `clojure -T:build <task>`):
clean delete target/
jar source jar + pom
jar-aot AOT no-source jar (own .class + resources only)
install build + install to ~/.m2 (offline)
kondo sync dependency-exported lint configs, then lint
bump rewrite ./VERSION (:level :patch|:minor|:major)
verify-license report LICENSE / version.edn / SPDX agreement (warns)
audit-opacity report private strings a built jar still carries (warns)
freeze-check refuse a release that breaks ./freeze-policy.edn (fails)
deploy build + publish per :publish (no-op when :none)
Release flow (what CI runs on a push to main that touches src/deps):
clojure -T:build bump :level :patch
clojure -T:build deploy(audit-opacity {:keys [jar strict]})Report which strings this repository's sources declared private that the built jar still carries.
Reads an artifact that already exists: run jar-aot first, or pass :jar to
audit any jar on disk. The audit is the same one jar-aot runs, so a jar
built before the elision pass existed can be measured without rebuilding it.
:jar path to the jar (default: the coordinate under target/) :strict true to throw on a leak (default: report and return)
A clean verdict says the audited strings are absent. It says nothing about the call graph, the numeric constants, or any name.
Report which strings this repository's sources declared private that the built jar still carries. Reads an artifact that already exists: run `jar-aot` first, or pass :jar to audit any jar on disk. The audit is the same one `jar-aot` runs, so a jar built before the elision pass existed can be measured without rebuilding it. :jar path to the jar (default: the coordinate under target/) :strict true to throw on a leak (default: report and return) A clean verdict says the audited strings are absent. It says nothing about the call graph, the numeric constants, or any name.
(bump {:keys [level] :or {level :patch}})Rewrite ./VERSION to the next semantic version and print it.
:level :patch (default) | :minor | :major VERSION is the single source of truth for both the git tag (v{VERSION}) and the Maven coordinate. Does not commit, tag, or deploy.
Rewrite ./VERSION to the next semantic version and print it.
:level :patch (default) | :minor | :major
VERSION is the single source of truth for both the git tag (v{VERSION}) and
the Maven coordinate. Does not commit, tag, or deploy.(deploy opts)Build + publish according to version.edn :publish.
A coordinate already present in the registry is a no-op, not an error: both registries are immutable, so releasing again means bumping VERSION.
Build + publish according to version.edn :publish. A coordinate already present in the registry is a no-op, not an error: both registries are immutable, so releasing again means bumping VERSION.
(freeze-check _)Refuse a release that breaks the repository's freeze policy.
Reads ./freeze-policy.edn (absent = nothing enforced), compares the public
API surface on disk against the surface at the last v* tag, and checks the
age of that tag. Prints the verdict; THROWS on a violation so the release
workflow stops before bump mints a version that can never be retracted.
Escape hatches are per-commit and must be written down: the cadence marker and the break marker named by the policy, in the HEAD commit message.
Returns the verdict map on success.
Refuse a release that breaks the repository's freeze policy. Reads ./freeze-policy.edn (absent = nothing enforced), compares the public API surface on disk against the surface at the last v* tag, and checks the age of that tag. Prints the verdict; THROWS on a violation so the release workflow stops before `bump` mints a version that can never be retracted. Escape hatches are per-commit and must be written down: the cadence marker and the break marker named by the policy, in the HEAD commit message. Returns the verdict map on success.
(install _)Build + install to the local ~/.m2 repository (offline).
Build + install to the local ~/.m2 repository (offline).
(jar _)Build the source jar (pom + copied sources) under target/.
Build the source jar (pom + copied sources) under target/.
(jar-aot _)Build the AOT no-source jar: this lib's own .class files + resources only.
Build the AOT no-source jar: this lib's own .class files + resources only.
(kondo {:keys [aliases paths fail-level]
:or {aliases [:test] fail-level :error}})Sync clj-kondo configs exported by dependencies, then lint.
Any deps.edn or bb.edn dependency shipping resources/clj-kondo.exports/<group>/<artifact>/ has its config + hooks copied into ./.clj-kondo/imports/, which clj-kondo loads automatically. Macro awareness therefore arrives with the dependency instead of being re-authored per repo.
:aliases deps aliases whose classpath is scanned (default [:test]) :paths lint targets (default src + test) :fail-level :error (default) | :warning | nil to report only
Sync clj-kondo configs exported by dependencies, then lint. Any deps.edn or bb.edn dependency shipping resources/clj-kondo.exports/<group>/<artifact>/ has its config + hooks copied into ./.clj-kondo/imports/, which clj-kondo loads automatically. Macro awareness therefore arrives with the dependency instead of being re-authored per repo. :aliases deps aliases whose classpath is scanned (default [:test]) :paths lint targets (default src + test) :fail-level :error (default) | :warning | nil to report only
(verify-license _)Report whether ./LICENSE, version.edn :license and the src SPDX headers agree. Advisory: prints and returns the report, never fails the build.
Report whether ./LICENSE, version.edn :license and the src SPDX headers agree. Advisory: prints and returns the report, never fails the build.
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 |