Clojure deps.edn Repositories
This section provides comprehensive documentation for configuring and using Clojure deps.edn (tools.deps) repositories with CloudRepo.
Overview
Clojure CLI and deps.edn represent the modern approach to dependency management in Clojure. Introduced as part of the official Clojure toolchain, tools.deps provides a lightweight, declarative system for managing dependencies directly from Maven repositories, Git repositories, and local projects.
What is deps.edn?
deps.edn is a configuration file that declares:
Dependencies: Libraries your project needs
Paths: Source and resource directories
Aliases: Optional configurations for different contexts (dev, test, build)
Repositories: Maven repositories to fetch dependencies from
Unlike Leiningen, which is a full build tool, deps.edn focuses solely on dependency management and classpath construction, following the Unix philosophy of doing one thing well.
Key Differences from Leiningen
Feature |
deps.edn / tools.deps |
Leiningen |
---|---|---|
Philosophy |
Minimal, composable tools |
Comprehensive build tool |
Configuration |
EDN format (deps.edn) |
Clojure format (project.clj) |
Build Tasks |
Via tools (tools.build) |
Built-in task system |
Dependency Resolution |
Maven + Git + Local |
Primarily Maven |
JAR Creation |
Requires additional tools |
Built-in uberjar support |
Why Private Maven Repositories for Clojure?
Clojure teams need private repositories to:
Share Internal Libraries: Distribute proprietary Clojure/ClojureScript libraries across teams
Control Dependencies: Manage approved versions of both Clojure and Java libraries
Integrate with Java Ecosystem: Clojure runs on the JVM and seamlessly uses Java libraries
Cache Dependencies: Improve build performance and reliability
Ensure Reproducible Builds: Guarantee consistent dependency resolution
CloudRepo provides fully managed Maven repositories that work seamlessly with deps.edn, eliminating infrastructure overhead while providing enterprise-grade security.
Prerequisites
Before configuring deps.edn with CloudRepo, ensure you have:
Clojure CLI Installed: Version 1.11.0 or later
CloudRepo Repository: A Maven-type repository created in the CloudRepo Admin Portal
Repository User: A dedicated user with appropriate permissions
If you haven’t completed these steps, please refer to:
Important
Admin users cannot directly access repositories. Always create dedicated repository users for artifact access.
Note
CloudRepo repositories use the following URL format:
https://[organization-id].mycloudrepo.io/repositories/[repository-id]
deps.edn Configuration
Basic Repository Setup
Configure CloudRepo in your deps.edn
file:
1{:deps {org.clojure/clojure {:mvn/version "1.11.1"}
2 ;; Your private library from CloudRepo
3 com.yourcompany/internal-lib {:mvn/version "1.0.0"}}
4
5 :paths ["src" "resources"]
6
7 :mvn/repos {"cloudrepo" {:url "https://your-org.mycloudrepo.io/repositories/your-repo"}
8 "central" {:url "https://repo1.maven.org/maven2/"}
9 "clojars" {:url "https://repo.clojars.org/"}}}
Authentication Configuration
Clojure CLI uses Maven’s settings.xml for repository authentication. Create or update ~/.m2/settings.xml
:
1<?xml version="1.0" encoding="UTF-8"?>
2<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
5 https://maven.apache.org/xsd/settings-1.0.0.xsd">
6 <servers>
7 <server>
8 <id>cloudrepo</id>
9 <username>your-username</username>
10 <password>your-password</password>
11 </server>
12 </servers>
13</settings>
Warning
Never commit credentials to version control. Use environment variables for CI/CD environments.
Environment Variable Configuration
For better security, use environment variables in settings.xml
:
1<?xml version="1.0" encoding="UTF-8"?>
2<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
5 https://maven.apache.org/xsd/settings-1.0.0.xsd">
6 <servers>
7 <server>
8 <id>cloudrepo</id>
9 <username>${env.CLOUDREPO_USERNAME}</username>
10 <password>${env.CLOUDREPO_PASSWORD}</password>
11 </server>
12 </servers>
13</settings>
Set environment variables:
1# Linux/macOS
2export CLOUDREPO_USERNAME="your-username"
3export CLOUDREPO_PASSWORD="your-password"
4
5# Windows
6set CLOUDREPO_USERNAME=your-username
7set CLOUDREPO_PASSWORD=your-password
Multiple Repository Configuration
Configure multiple CloudRepo repositories for different artifact types:
1{:deps {org.clojure/clojure {:mvn/version "1.11.1"}
2 com.yourcompany/core-lib {:mvn/version "2.1.0"}
3 com.yourcompany/utils {:mvn/version "1.3.0"}}
4
5 :paths ["src" "resources"]
6
7 :mvn/repos {"cloudrepo-releases" {:url "https://your-org.mycloudrepo.io/repositories/releases"}
8 "cloudrepo-snapshots" {:url "https://your-org.mycloudrepo.io/repositories/snapshots"}
9 "central" {:url "https://repo1.maven.org/maven2/"}
10 "clojars" {:url "https://repo.clojars.org/"}}}
Add corresponding entries in settings.xml
:
1<servers>
2 <server>
3 <id>cloudrepo-releases</id>
4 <username>${env.CLOUDREPO_USERNAME}</username>
5 <password>${env.CLOUDREPO_PASSWORD}</password>
6 </server>
7 <server>
8 <id>cloudrepo-snapshots</id>
9 <username>${env.CLOUDREPO_USERNAME}</username>
10 <password>${env.CLOUDREPO_PASSWORD}</password>
11 </server>
12</servers>
Publishing Clojure Libraries
deps-deploy Setup
deps-deploy is the standard tool for deploying artifacts from deps.edn projects:
1{:deps {org.clojure/clojure {:mvn/version "1.11.1"}}
2
3 :paths ["src" "resources"]
4
5 :aliases {:deploy {:extra-deps {slipset/deps-deploy {:mvn/version "0.2.2"}}
6 :exec-fn deps-deploy.deps-deploy/deploy
7 :exec-args {:installer :remote
8 :sign-releases? false
9 :repository {"cloudrepo"
10 {:url "https://your-org.mycloudrepo.io/repositories/your-repo"
11 :username :env/cloudrepo_username
12 :password :env/cloudrepo_password}}
13 :artifact "target/your-library.jar"}}}}
Deploy your library:
1# Set credentials
2export CLOUDREPO_USERNAME="your-username"
3export CLOUDREPO_PASSWORD="your-password"
4
5# Deploy the artifact
6clojure -X:deploy
Using tools.build for JAR Creation
tools.build provides programmatic JAR creation:
1(ns build
2 (:require [clojure.tools.build.api :as b]
3 [deps-deploy.deps-deploy :as dd]))
4
5(def lib 'com.yourcompany/your-library)
6(def version (format "1.0.%s" (b/git-count-revs nil)))
7(def class-dir "target/classes")
8(def jar-file (format "target/%s-%s.jar" (name lib) version))
9
10;; Clean target directory
11(defn clean [_]
12 (b/delete {:path "target"}))
13
14;; Create JAR file
15(defn jar [_]
16 (clean nil)
17 (b/write-pom {:class-dir class-dir
18 :lib lib
19 :version version
20 :basis (b/create-basis {:project "deps.edn"})
21 :src-dirs ["src"]
22 :scm {:url "https://github.com/yourcompany/your-library"
23 :connection "scm:git:git://github.com/yourcompany/your-library.git"
24 :developerConnection "scm:git:ssh://git@github.com/yourcompany/your-library.git"
25 :tag (str "v" version)}})
26 (b/copy-dir {:src-dirs ["src" "resources"]
27 :target-dir class-dir})
28 (b/jar {:class-dir class-dir
29 :jar-file jar-file}))
30
31;; Deploy to CloudRepo
32(defn deploy [_]
33 (jar nil)
34 (dd/deploy {:installer :remote
35 :artifact (b/resolve-path jar-file)
36 :repository {"cloudrepo"
37 {:url "https://your-org.mycloudrepo.io/repositories/your-repo"
38 :username (System/getenv "CLOUDREPO_USERNAME")
39 :password (System/getenv "CLOUDREPO_PASSWORD")}}}))
Add the build alias to deps.edn
:
1{:deps {org.clojure/clojure {:mvn/version "1.11.1"}}
2
3 :paths ["src" "resources"]
4
5 :aliases {:build {:deps {io.github.clojure/tools.build {:mvn/version "0.9.6"}
6 slipset/deps-deploy {:mvn/version "0.2.2"}}
7 :ns-default build}}}
Build and deploy:
1# Build JAR
2clojure -T:build jar
3
4# Deploy to CloudRepo
5clojure -T:build deploy
POM Generation and Customization
Customize your POM file for better metadata:
1(defn create-pom [_]
2 (b/write-pom {:class-dir class-dir
3 :lib lib
4 :version version
5 :basis (b/create-basis {:project "deps.edn"})
6 :scm {:url "https://github.com/yourcompany/your-library"
7 :connection "scm:git:git://github.com/yourcompany/your-library.git"
8 :developerConnection "scm:git:ssh://git@github.com/yourcompany/your-library.git"
9 :tag (str "v" version)}
10 :pom-data [[:description "Your library description"]
11 [:url "https://github.com/yourcompany/your-library"]
12 [:licenses
13 [:license
14 [:name "Eclipse Public License"]
15 [:url "http://www.eclipse.org/legal/epl-v10.html"]]]
16 [:developers
17 [:developer
18 [:name "Your Name"]
19 [:email "you@yourcompany.com"]]]
20 [:organization
21 [:name "Your Company"]
22 [:url "https://yourcompany.com"]]]}))
Version Management
Implement flexible version management:
1(ns build
2 (:require [clojure.tools.build.api :as b]
3 [clojure.string :as str]))
4
5;; Strategy 1: Read from file
6(def version (str/trim (slurp "VERSION")))
7
8;; Strategy 2: Git-based versioning
9(def version (format "1.0.%s" (b/git-count-revs nil)))
10
11;; Strategy 3: Timestamp-based for SNAPSHOTs
12(def version (format "1.0.0-%s-SNAPSHOT"
13 (.format (java.time.LocalDateTime/now)
14 (java.time.format.DateTimeFormatter/ofPattern "yyyyMMddHHmmss"))))
15
16;; Strategy 4: Environment variable
17(def version (or (System/getenv "VERSION") "1.0.0-SNAPSHOT"))
Publishing Sources and Documentation
Include source JARs and documentation:
1(defn jar-all [_]
2 (clean nil)
3 ;; Main JAR
4 (b/write-pom {:class-dir class-dir
5 :lib lib
6 :version version
7 :basis (b/create-basis {:project "deps.edn"})})
8 (b/copy-dir {:src-dirs ["src" "resources"]
9 :target-dir class-dir})
10 (b/jar {:class-dir class-dir
11 :jar-file jar-file})
12
13 ;; Sources JAR
14 (b/jar {:class-dir "src"
15 :jar-file (format "target/%s-%s-sources.jar" (name lib) version)})
16
17 ;; Javadoc JAR (for Clojure API docs)
18 (b/javadoc {:src-dirs ["src"]
19 :class-dir class-dir
20 :javadoc-dir "target/javadoc"
21 :lib lib
22 :version version})
23 (b/jar {:class-dir "target/javadoc"
24 :jar-file (format "target/%s-%s-javadoc.jar" (name lib) version)}))
25
26(defn deploy-all [_]
27 (jar-all nil)
28 ;; Deploy all artifacts
29 (doseq [artifact ["" "-sources" "-javadoc"]]
30 (dd/deploy {:installer :remote
31 :artifact (b/resolve-path
32 (format "target/%s-%s%s.jar" (name lib) version artifact))
33 :repository {"cloudrepo"
34 {:url "https://your-org.mycloudrepo.io/repositories/your-repo"
35 :username (System/getenv "CLOUDREPO_USERNAME")
36 :password (System/getenv "CLOUDREPO_PASSWORD")}}})))
Consuming Dependencies
Adding Private Dependencies
Reference your private libraries from CloudRepo:
1{:deps {;; Public dependencies
2 org.clojure/clojure {:mvn/version "1.11.1"}
3 ring/ring-core {:mvn/version "1.10.0"}
4
5 ;; Private dependencies from CloudRepo
6 com.yourcompany/auth-lib {:mvn/version "2.1.0"}
7 com.yourcompany/data-processor {:mvn/version "3.0.0"}
8 com.yourcompany/api-client {:mvn/version "1.5.2"}}
9
10 :paths ["src" "resources"]
11
12 :mvn/repos {"cloudrepo" {:url "https://your-org.mycloudrepo.io/repositories/your-repo"}
13 "central" {:url "https://repo1.maven.org/maven2/"}
14 "clojars" {:url "https://repo.clojars.org/"}}}
Mixing Repository Sources
Combine CloudRepo with other repository sources:
1{:deps {;; From Maven Central
2 org.clojure/clojure {:mvn/version "1.11.1"}
3
4 ;; From Clojars
5 metosin/reitit {:mvn/version "0.6.0"}
6
7 ;; From CloudRepo
8 com.yourcompany/core {:mvn/version "1.0.0"}
9
10 ;; From Git
11 com.yourcompany/experimental {:git/url "https://github.com/yourcompany/experimental"
12 :git/sha "abc123"}
13
14 ;; Local development
15 com.yourcompany/local-lib {:local/root "../local-lib"}}
16
17 :paths ["src" "resources"]
18
19 :mvn/repos {"cloudrepo" {:url "https://your-org.mycloudrepo.io/repositories/your-repo"}
20 "central" {:url "https://repo1.maven.org/maven2/"}
21 "clojars" {:url "https://repo.clojars.org/"}}}
Dependency Aliases and Profiles
Use aliases for different dependency sets:
1{:deps {org.clojure/clojure {:mvn/version "1.11.1"}
2 com.yourcompany/core {:mvn/version "1.0.0"}}
3
4 :paths ["src" "resources"]
5
6 :aliases {:dev {:extra-deps {nrepl/nrepl {:mvn/version "1.0.0"}
7 cider/cider-nrepl {:mvn/version "0.30.0"}
8 com.yourcompany/dev-tools {:mvn/version "2.0.0"}}
9 :extra-paths ["dev" "test"]}
10
11 :test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.87.1366"}
12 com.yourcompany/test-fixtures {:mvn/version "1.0.0"}}
13 :extra-paths ["test"]}
14
15 :prod {:override-deps {com.yourcompany/core {:mvn/version "1.0.0-RELEASE"}}
16 :jvm-opts ["-Xmx2g" "-Xms2g"]}
17
18 :staging {:override-deps {com.yourcompany/core {:mvn/version "1.0.0-RC1"}}
19 :mvn/repos {"cloudrepo-staging"
20 {:url "https://your-org.mycloudrepo.io/repositories/staging"}}}}
21
22 :mvn/repos {"cloudrepo" {:url "https://your-org.mycloudrepo.io/repositories/your-repo"}
23 "central" {:url "https://repo1.maven.org/maven2/"}
24 "clojars" {:url "https://repo.clojars.org/"}}}
Run with specific aliases:
1# Development REPL
2clojure -A:dev
3
4# Run tests
5clojure -A:test -m kaocha.runner
6
7# Production build
8clojure -A:prod -T:build jar
Advanced Topics
Monorepo Support
Structure for Clojure monorepos with CloudRepo:
1{:deps {}
2
3 :paths []
4
5 :aliases {:lib-a {:extra-deps {com.yourcompany/lib-a {:local/root "libs/lib-a"}}}
6 :lib-b {:extra-deps {com.yourcompany/lib-b {:local/root "libs/lib-b"}}}
7 :app {:extra-deps {com.yourcompany/app {:local/root "apps/main-app"}}}
8
9 :deploy-all {:exec-fn monorepo.deploy/deploy-all
10 :exec-args {:libs ["lib-a" "lib-b"]
11 :repository {:url "https://your-org.mycloudrepo.io/repositories/your-repo"
12 :username :env/cloudrepo_username
13 :password :env/cloudrepo_password}}}}
14
15 :mvn/repos {"cloudrepo" {:url "https://your-org.mycloudrepo.io/repositories/your-repo"}
16 "central" {:url "https://repo1.maven.org/maven2/"}}}
1{:deps {org.clojure/clojure {:mvn/version "1.11.1"}
2 ;; Internal dependency from CloudRepo
3 com.yourcompany/lib-core {:mvn/version "1.0.0"}}
4
5 :paths ["src" "resources"]}
Tools and Aliases Management
Centralize tool configurations:
1{:aliases {:outdated {:extra-deps {com.github.liquidz/antq {:mvn/version "2.5.1144"}}
2 :main-opts ["-m" "antq.core"]}
3
4 :deps-ancient {:extra-deps {deps-ancient/deps-ancient {:mvn/version "0.1.0"}}
5 :main-opts ["-m" "deps-ancient.deps-ancient"]}
6
7 :deploy {:extra-deps {slipset/deps-deploy {:mvn/version "0.2.2"}}
8 :exec-fn deps-deploy.deps-deploy/deploy}
9
10 :build {:deps {io.github.clojure/tools.build {:mvn/version "0.9.6"}}
11 :ns-default build}
12
13 :cloudrepo {:mvn/repos {"cloudrepo-releases"
14 {:url "https://your-org.mycloudrepo.io/repositories/releases"}
15 "cloudrepo-snapshots"
16 {:url "https://your-org.mycloudrepo.io/repositories/snapshots"}}}}}
Caching Strategies
Optimize dependency caching:
1# GitHub Actions example
2- name: Cache Clojure dependencies
3 uses: actions/cache@v3
4 with:
5 path: |
6 ~/.m2/repository
7 ~/.gitlibs
8 ~/.clojure/.cpcache
9 key: ${{ runner.os }}-clojure-${{ hashFiles('**/deps.edn') }}
10 restore-keys: |
11 ${{ runner.os }}-clojure-
12
13# Pre-download dependencies
14- name: Download dependencies
15 run: |
16 clojure -P
17 clojure -P -A:dev:test:build
Multi-Module Projects
Configure multi-module projects with shared dependencies:
1{:deps {}
2
3 :aliases {:modules {:extra-paths ["module-a/src" "module-b/src" "module-c/src"]
4 :extra-deps {com.yourcompany/module-a {:local/root "module-a"}
5 com.yourcompany/module-b {:local/root "module-b"}
6 com.yourcompany/module-c {:local/root "module-c"}}}
7
8 :deploy-modules {:exec-fn deploy.multi/deploy-all
9 :exec-args {:modules ["module-a" "module-b" "module-c"]
10 :repository {:url "https://your-org.mycloudrepo.io/repositories/your-repo"
11 :username :env/cloudrepo_username
12 :password :env/cloudrepo_password}}}}
13
14 :mvn/repos {"cloudrepo" {:url "https://your-org.mycloudrepo.io/repositories/your-repo"}}}
ClojureScript Libraries
Publish and consume ClojureScript libraries:
1{:deps {org.clojure/clojure {:mvn/version "1.11.1"}
2 org.clojure/clojurescript {:mvn/version "1.11.60"}
3 thheller/shadow-cljs {:mvn/version "2.25.0"}}
4
5 :paths ["src/clj" "src/cljs" "resources"]
6
7 :aliases {:cljs {:extra-deps {com.yourcompany/cljs-utils {:mvn/version "1.0.0"
8 :exclusions [org.clojure/clojurescript]}}}
9
10 :build-cljs {:exec-fn build/build-cljs
11 :exec-args {:optimizations :advanced
12 :output-to "target/main.js"
13 :source-map true}}}
14
15 :mvn/repos {"cloudrepo" {:url "https://your-org.mycloudrepo.io/repositories/your-repo"}
16 "central" {:url "https://repo1.maven.org/maven2/"}
17 "clojars" {:url "https://repo.clojars.org/"}}}
CI/CD Integration
GitHub Actions
Complete GitHub Actions workflow:
1name: Deploy to CloudRepo
2
3on:
4 push:
5 tags:
6 - 'v*'
7
8jobs:
9 deploy:
10 runs-on: ubuntu-latest
11
12 steps:
13 - uses: actions/checkout@v3
14
15 - name: Install Clojure
16 uses: DeLaGuardo/setup-clojure@12.1
17 with:
18 cli: 1.11.1.1435
19
20 - name: Cache dependencies
21 uses: actions/cache@v3
22 with:
23 path: |
24 ~/.m2/repository
25 ~/.gitlibs
26 key: ${{ runner.os }}-clojure-${{ hashFiles('**/deps.edn') }}
27
28 - name: Run tests
29 run: clojure -A:test -M:runner
30
31 - name: Build JAR
32 run: clojure -T:build jar
33
34 - name: Deploy to CloudRepo
35 env:
36 CLOUDREPO_USERNAME: ${{ secrets.CLOUDREPO_USERNAME }}
37 CLOUDREPO_PASSWORD: ${{ secrets.CLOUDREPO_PASSWORD }}
38 run: clojure -T:build deploy
GitLab CI
1stages:
2 - test
3 - build
4 - deploy
5
6variables:
7 MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository"
8
9cache:
10 paths:
11 - .m2/repository/
12 - .cpcache/
13
14test:
15 stage: test
16 image: clojure:temurin-21-tools-deps
17 script:
18 - clojure -A:test -M:runner
19
20build:
21 stage: build
22 image: clojure:temurin-21-tools-deps
23 script:
24 - clojure -T:build jar
25 artifacts:
26 paths:
27 - target/
28
29deploy:
30 stage: deploy
31 image: clojure:temurin-21-tools-deps
32 script:
33 - clojure -T:build deploy
34 environment:
35 name: production
36 only:
37 - tags
38 variables:
39 CLOUDREPO_USERNAME: $CLOUDREPO_USERNAME
40 CLOUDREPO_PASSWORD: $CLOUDREPO_PASSWORD
Jenkins Pipeline
1pipeline {
2 agent any
3
4 environment {
5 CLOUDREPO_USERNAME = credentials('cloudrepo-username')
6 CLOUDREPO_PASSWORD = credentials('cloudrepo-password')
7 }
8
9 stages {
10 stage('Checkout') {
11 steps {
12 checkout scm
13 }
14 }
15
16 stage('Test') {
17 steps {
18 sh 'clojure -A:test -M:runner'
19 }
20 }
21
22 stage('Build') {
23 steps {
24 sh 'clojure -T:build jar'
25 }
26 }
27
28 stage('Deploy') {
29 when {
30 tag pattern: "v\\d+\\.\\d+\\.\\d+", comparator: "REGEXP"
31 }
32 steps {
33 sh 'clojure -T:build deploy'
34 }
35 }
36 }
37
38 post {
39 always {
40 cleanWs()
41 }
42 }
43}
CircleCI
1version: 2.1
2
3executors:
4 clojure:
5 docker:
6 - image: cimg/clojure:1.11.1
7
8jobs:
9 test:
10 executor: clojure
11 steps:
12 - checkout
13 - restore_cache:
14 keys:
15 - v1-deps-{{ checksum "deps.edn" }}
16 - v1-deps-
17 - run:
18 name: Download dependencies
19 command: clojure -P && clojure -P -A:test
20 - save_cache:
21 key: v1-deps-{{ checksum "deps.edn" }}
22 paths:
23 - ~/.m2
24 - ~/.gitlibs
25 - run:
26 name: Run tests
27 command: clojure -A:test -M:runner
28
29 deploy:
30 executor: clojure
31 steps:
32 - checkout
33 - restore_cache:
34 keys:
35 - v1-deps-{{ checksum "deps.edn" }}
36 - run:
37 name: Build and Deploy
38 command: |
39 clojure -T:build jar
40 clojure -T:build deploy
41
42workflows:
43 version: 2
44 test-and-deploy:
45 jobs:
46 - test
47 - deploy:
48 requires:
49 - test
50 filters:
51 tags:
52 only: /^v.*/
53 branches:
54 ignore: /.*/
Troubleshooting
Common Issues and Solutions
Authentication Failures
Problem: 401 Unauthorized errors when accessing CloudRepo
Solution:
Verify credentials in
~/.m2/settings.xml
:cat ~/.m2/settings.xml | grep -A 3 cloudrepo
Ensure server ID matches repository ID in deps.edn
Check environment variables are set:
echo $CLOUDREPO_USERNAME echo $CLOUDREPO_PASSWORD
Verify user has correct repository permissions in CloudRepo Admin Portal
Dependency Resolution Failures
Problem: Dependencies from CloudRepo not found
Solution:
Check repository URL format:
;; Correct {:mvn/repos {"cloudrepo" {:url "https://your-org.mycloudrepo.io/repositories/your-repo"}}} ;; Incorrect - missing /repositories/ {:mvn/repos {"cloudrepo" {:url "https://your-org.mycloudrepo.io/your-repo"}}}
Verify artifact exists in repository:
curl -u username:password https://your-org.mycloudrepo.io/repositories/your-repo/com/yourcompany/your-lib/maven-metadata.xml
Clear local cache:
rm -rf ~/.m2/repository/com/yourcompany/your-lib clojure -Sforce -Stree
SSL Certificate Issues
Problem: SSL handshake failures
Solution:
For self-signed certificates (not recommended for production):
# Add to JAVA_TOOL_OPTIONS
export JAVA_TOOL_OPTIONS="-Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true"
For proper certificate installation:
# Import certificate to Java truststore
keytool -import -trustcacerts -keystore $JAVA_HOME/lib/security/cacerts \
-storepass changeit -alias cloudrepo \
-file cloudrepo-certificate.crt
Deployment Failures
Problem: Artifacts fail to deploy
Solution:
Check write permissions for user
Verify artifact doesn’t already exist (for releases)
Enable verbose logging:
;; In build.clj (require '[clojure.pprint :refer [pprint]]) (defn deploy-verbose [_] (let [result (dd/deploy {:installer :remote :artifact jar-file :repository repo-config})] (pprint result)))
Check file size limits in CloudRepo settings
Snapshot vs Release Confusion
Problem: SNAPSHOT versions treated as releases or vice versa
Solution:
Configure separate repositories:
{:mvn/repos {"cloudrepo-releases" {:url "https://your-org.mycloudrepo.io/repositories/releases"}
"cloudrepo-snapshots" {:url "https://your-org.mycloudrepo.io/repositories/snapshots"}}}
Use version detection in build:
(defn deploy [_]
(let [snapshot? (str/ends-with? version "SNAPSHOT")
repo-url (if snapshot?
"https://your-org.mycloudrepo.io/repositories/snapshots"
"https://your-org.mycloudrepo.io/repositories/releases")]
(dd/deploy {:installer :remote
:artifact jar-file
:repository {"cloudrepo" {:url repo-url
:username (System/getenv "CLOUDREPO_USERNAME")
:password (System/getenv "CLOUDREPO_PASSWORD")}}})))
Debugging Tips
Enable Verbose Output
# Show dependency tree
clojure -Stree
# Force re-resolution
clojure -Sforce -Stree
# Verbose Maven output
clojure -Sdeps '{:mvn/local-repo ".m2-debug"}' -Sverbose
Check Effective Configuration
# Show computed classpath
clojure -Spath
# Show basis (merged deps.edn)
clojure -X:deps tree
Test Repository Access
# Test authentication
curl -u username:password https://your-org.mycloudrepo.io/repositories/your-repo/
# Download specific artifact
curl -u username:password -O \
https://your-org.mycloudrepo.io/repositories/your-repo/com/yourcompany/your-lib/1.0.0/your-lib-1.0.0.jar
Summary
This guide covered the complete integration of Clojure deps.edn projects with CloudRepo:
Configuration: Set up deps.edn and authentication via settings.xml
Publishing: Deploy libraries using deps-deploy and tools.build
Consuming: Use private dependencies alongside public repositories
Advanced Topics: Monorepos, ClojureScript, and multi-module projects
CI/CD: Automate builds and deployments across popular platforms
Troubleshooting: Resolve common issues with authentication, SSL, and deployments
CloudRepo provides a seamless, managed solution for hosting private Clojure artifacts, eliminating infrastructure overhead while providing enterprise-grade security and reliability. With proper configuration, your Clojure projects can leverage CloudRepo’s cost-effective repository management alongside the simplicity and power of deps.edn.