Library and plugin versions must stay aligned; CI runs bash script/verify-monorepo-versions.sh before builds.
Development stays on *-SNAPSHOT coordinates. A non-SNAPSHOT version is the exact stable you ship for that instant (artifacts, tags, docs that pin a release).
Release lifecycle enforces that: the branch must already be ${release_version}-SNAPSHOT, you enter the bare stable to publish (release_version, e.g. 0.7.0) and the bare next dev line (next_dev_version, e.g. 0.8.0); the workflow moves the tree to 0.7.0, publishes, then to 0.8.0-SNAPSHOT.
GITHUB_TOKEN permissions (release lifecycle)Release lifecycle declares permissions: contents: write so jobs that call change-project-versions can push. A caller that only granted contents: read would block the nested job from contents: write: GitHub documents that GITHUB_TOKEN permissions can only be the same or more restrictive in nested workflows (Reusing workflow configurations — nested permissions).
The publish job uses secrets: inherit so publish-clojars receives repository Actions secrets (secrets: inherit, Reuse workflows — passing secrets).
:deploy-repositories + env)leiningen.org deploy documents :username/:password with :env/... on :repositories and notes that :env forms are only discussed there for :repositories. For Leiningen 2.11.2 (pinned in publish-clojars.yml), the deploy task resolves repo settings the same way for :deploy-repositories: repo-for merges deploy repo settings and passes them through classpath/add-repo-auth → user/resolve-credentials, which resolves :env/VAR via System/getenv — see deploy.clj repo-for, classpath.clj add-repo-auth, and user.clj resolve-credential. lein deploy with no repo name uses snapshots vs releases by version (deploy — Deployment).
Each reusable workflow run is a separate runner checkout. Pushing in job A does not move github.sha in the parent run (github.sha is the commit that triggered the workflow). After the first bump pushes, change-project-versions records git rev-parse HEAD and exposes it as workflow output commit_sha (outputs from reusable workflows). Release lifecycle passes that value into publish-clojars (commit_sha) and into the second change-project-versions call (checkout_ref), so publish and the next bump see the exact tree that was pushed.
| Workflow | Role |
|---|---|
| Release lifecycle | One dispatch: repo must be on ${release_version}-SNAPSHOT. Inputs are bare release_version (stable to publish) and bare next_dev_version (next dev line; workflow sets ${next_dev_version}-SNAPSHOT). Composes only Change project versions and Publish to Clojars: bump to release (checkout github.sha) → publish at commit_sha → bump to next snapshot (same commit_sha checkout). |
| Change project versions | Reusable + manual: replace from_version → to_version in both project.clj files and the README install line, verify, regenerate POMs, commit, git tag v<to_version>, push branch and tag. workflow_call requires checkout_ref. workflow_dispatch uses default checkout (inputs: from_version, to_version only). |
| Publish to Clojars | Verify versions, local lein install, then lein deploy for skeptic then lein-skeptic (Leiningen picks snapshots vs releases from each project.clj by version). Credentials come from repository Actions secrets mapped to CLOJARS_* environment variables in the job. workflow_call requires commit_sha (checkout that SHA). workflow_dispatch uses default checkout for a standalone publish of the ref you run the workflow from. |
Snapshot-only deploy (e.g. ship 0.7.0-SNAPSHOT without advancing the release lifecycle): run Publish to Clojars via workflow_dispatch with the repo already on the snapshot coordinates you want.
Under Settings → Security → Secrets and variables → Actions:
| Secret | Used for |
|---|---|
CLOJARS_USERNAME | Clojars username (both deploy steps). |
CLOJARS_SKEPTIC_TOKEN | Deploy token for org.clojars.nomicflux/skeptic (lein deploy in skeptic/). |
CLOJARS_LEIN_SKEPTIC_TOKEN | Deploy token for org.clojars.nomicflux/lein-skeptic (lein deploy in lein-skeptic/). |
Deploy steps read Clojars auth from CLOJARS_* environment variables set from those secrets (see each project.clj :deploy-repositories). If one Clojars token is valid for both artifacts, set the same value on both token secrets.
0.7.0)0.7.0-SNAPSHOT everywhere the coordinated files require (see verify script). Release lifecycle validates that before any bump.release_version 0.7.0, next_dev_version 0.8.0. Requires the three Action secrets in the table above. The first bump pushes the release commit and tag v0.7.0; publish runs against that commit; the second bump moves the tree to 0.8.0-SNAPSHOT and pushes. Branch protection: the default GITHUB_TOKEN must be allowed to push to the branch you run against (often main), or the push steps will fail.v0.7.0 (already pushed by the first bump).Bump versions in skeptic/project.clj and lein-skeptic/project.clj, the install snippet in README.md, then lein pom in skeptic/ and lein-skeptic/. Deploy with lein deploy from each project directory (library first, then plugin) after exporting CLOJARS_USERNAME and the matching token env vars, or use Publish to Clojars (dispatch), which sets those from Actions secrets.
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 |