2011-03-16 01:45:10 +00:00
|
|
|
# Deploying Libraries
|
|
|
|
|
|
|
|
Getting your library into [Clojars](http://clojars.org) is fairly
|
|
|
|
straightforward as is documented near the end of
|
2013-01-20 04:39:43 +00:00
|
|
|
[the Leiningen tutorial](https://github.com/technomancy/leiningen/blob/stable/doc/TUTORIAL.md).
|
2012-10-10 17:04:30 +00:00
|
|
|
However, deploying elsewhere is not always that straightforward.
|
2011-05-13 15:15:54 +00:00
|
|
|
|
2011-03-16 01:45:10 +00:00
|
|
|
## Private Repositories
|
|
|
|
|
|
|
|
There may be times when you want to make a library available to your
|
|
|
|
team without making it public. This is best done by setting up a
|
2012-08-11 01:51:43 +00:00
|
|
|
private repository. The simplest kind of private repository is a web
|
|
|
|
server pointed at a directory full of static files. You can use a
|
2012-08-23 19:10:01 +00:00
|
|
|
`file:///` URL in your `:repositories` to deploy that way if the
|
2012-08-11 01:51:43 +00:00
|
|
|
directory is local to the machine on which Leiningen is running.
|
|
|
|
[Amazon S3](http://aws.amazon.com/s3/) buckets are another simple
|
|
|
|
choice; you can deploy to S3 buckets using
|
|
|
|
[S3 wagon private](https://github.com/technomancy/s3-wagon-private).
|
2012-06-27 23:06:48 +00:00
|
|
|
|
|
|
|
Alternatively you can run a private repository on your own server.
|
|
|
|
Both [Archiva](http://archiva.apache.org/) and
|
|
|
|
[Nexus](http://nexus.sonatype.org/) provide this as well as proxying
|
|
|
|
to other repositories, so you can set `:omit-default-repositories` in
|
|
|
|
project.clj, and dependency downloads will speed up by quite a bit
|
2011-03-16 01:45:10 +00:00
|
|
|
with only one server to check.
|
|
|
|
|
2012-04-18 05:14:46 +00:00
|
|
|
The private server will need to be added to the `:repositories`
|
2011-03-16 01:45:10 +00:00
|
|
|
listing in project.clj. Archiva and Nexus offer separate repositories
|
|
|
|
for snapshots and releases, so you'll want two entries for them:
|
|
|
|
|
2011-11-11 20:16:52 +00:00
|
|
|
```clj
|
2012-08-23 19:10:01 +00:00
|
|
|
:repositories [["snapshots" "http://blueant.com/archiva/snapshots"]
|
|
|
|
["releases" "http://blueant.com/archiva/internal"]]
|
2011-11-11 20:16:52 +00:00
|
|
|
```
|
2011-03-16 01:45:10 +00:00
|
|
|
|
2011-09-16 01:29:18 +00:00
|
|
|
If you are are deploying to a repository that is _only_ used for deployment
|
|
|
|
and never for dependency resolution, then it should be specified in a
|
|
|
|
`:deploy-repositories` slot instead of included in the more general-purpose
|
|
|
|
`:repositories` map; the former is checked by `lein deploy` before the latter.
|
2011-10-25 08:37:59 +00:00
|
|
|
Deployment-only repositories useful across a number of locally developed
|
2012-05-31 03:24:54 +00:00
|
|
|
projects may also be specified in the `:user` profile in `~/.lein/profiles.clj`:
|
2011-10-25 08:37:59 +00:00
|
|
|
|
2011-11-11 20:16:52 +00:00
|
|
|
```clj
|
2012-08-23 19:10:01 +00:00
|
|
|
{:user {:deploy-repositories [["internal" "http://blueant.com/archiva/internal"]]}}
|
2011-11-11 20:16:52 +00:00
|
|
|
```
|
2011-09-16 01:29:18 +00:00
|
|
|
|
2012-06-27 23:06:48 +00:00
|
|
|
## Authentication
|
2011-09-16 01:29:18 +00:00
|
|
|
|
2012-06-10 21:55:49 +00:00
|
|
|
Deploying and reading from private repositories needs authentication
|
|
|
|
credentials. Check your repository's documentation for details, but
|
2012-06-27 23:06:48 +00:00
|
|
|
you'll usually need to provide a `:username` and `:password` or
|
2012-06-10 21:55:49 +00:00
|
|
|
`:passphrase`. Leiningen will prompt you for a password if you haven't
|
|
|
|
set up credentials, but it's convenient to set it so you don't have to
|
|
|
|
re-enter it every time you want to deploy. You will need
|
2013-03-18 19:51:43 +00:00
|
|
|
[gpg](http://www.gnupg.org/) installed and a key pair configured. If
|
|
|
|
you need help with either of those, see the
|
|
|
|
[GPG guide](https://github.com/technomancy/leiningen/blob/stable/doc/GPG.md).
|
2012-05-31 03:24:54 +00:00
|
|
|
|
2012-10-10 17:04:30 +00:00
|
|
|
### GPG
|
|
|
|
|
2012-10-05 10:26:50 +00:00
|
|
|
If you specify a `:creds :gpg` entry in one of your `:repositories` settings
|
|
|
|
maps, Leiningen will decrypt `~/.lein/credentials.clj.gpg` and use that to find
|
|
|
|
the proper credentials for the given repository.
|
2012-06-27 23:06:48 +00:00
|
|
|
|
|
|
|
```clj
|
2012-08-23 19:10:01 +00:00
|
|
|
:repositories [["releases" {:url "http://blueant.com/archiva/internal"
|
2012-10-05 10:26:50 +00:00
|
|
|
:creds :gpg}]]
|
2012-06-27 23:06:48 +00:00
|
|
|
```
|
|
|
|
|
2012-05-31 03:24:54 +00:00
|
|
|
First write your credentials map to `~/.lein/credentials.clj` like so:
|
2011-03-16 01:45:10 +00:00
|
|
|
|
2011-11-11 20:16:52 +00:00
|
|
|
```clj
|
2012-06-27 23:06:48 +00:00
|
|
|
{#"blueant" {:password "locative1"}
|
|
|
|
#"https://clojars.org/repo"
|
2012-05-31 03:24:54 +00:00
|
|
|
{:username "milgrim" :password "locative1"}
|
|
|
|
"s3p://s3-repo-bucket/releases"
|
2012-06-27 23:06:48 +00:00
|
|
|
{:username "AKIAIN..." :passphrase "1TChrGK4s..."}}
|
2011-11-11 20:16:52 +00:00
|
|
|
```
|
2012-05-31 03:24:54 +00:00
|
|
|
Then encrypt it with `gpg`:
|
|
|
|
|
|
|
|
$ gpg --default-recipient-self -e \
|
|
|
|
~/.lein/credentials.clj > ~/.lein/credentials.clj.gpg
|
|
|
|
|
|
|
|
Remember to delete the plaintext `credentials.clj` once you've
|
2012-06-01 03:58:15 +00:00
|
|
|
encrypted it. Due to a bug in `gpg` you currently need to use
|
|
|
|
`gpg-agent` and have already unlocked your key before Leiningen
|
|
|
|
launches, but with `gpg-agent` you only have to enter your passphrase
|
2013-06-13 00:05:12 +00:00
|
|
|
periodically; it will keep it cached for a given period.
|
2011-03-16 01:45:10 +00:00
|
|
|
|
2012-10-10 17:04:30 +00:00
|
|
|
### Full-disk Encryption
|
|
|
|
|
|
|
|
If you use full-disk encryption, it may be safe to store your
|
|
|
|
credentials without using GPG. In this case, you can create an `:auth`
|
|
|
|
profile containing a `:repository-auth` key mapping URL regexes to
|
|
|
|
credentials. Your `~/.lein/profiles.clj` file would look something
|
|
|
|
like this:
|
|
|
|
|
|
|
|
```clj
|
|
|
|
{:user {...}
|
|
|
|
:auth {:repository-auth {#"blueant" {:username "milgrim"
|
|
|
|
:password "locative1"}}}}
|
|
|
|
```
|
|
|
|
|
|
|
|
### Credentials in the Environment
|
|
|
|
|
2012-06-27 23:06:48 +00:00
|
|
|
Unattended builds can specify `:env` instead of `:gpg` in the
|
|
|
|
repository specification to have credentials looked up in the
|
|
|
|
environment. For example, specifying `:password :env` will cause
|
|
|
|
Leiningen to look up `(System/getenv "LEIN_PASSWORD")` for that value.
|
2012-10-05 10:26:50 +00:00
|
|
|
You can control which environment variable is looked up for each value
|
|
|
|
by using a namespaced keyword, like so:
|
|
|
|
|
|
|
|
```clj
|
|
|
|
:repositories [["releases" {:url "http://blueant.com/archiva/internal"
|
|
|
|
:username :env/archiva_username
|
|
|
|
:passphrase :env/archiva_passphrase}]]
|
|
|
|
```
|
|
|
|
|
|
|
|
Finally, you can opt to load credentials from the environment _or_ GPG credentials
|
|
|
|
by using a vector of `:gpg` and `:env/*` values to define the priority of each:
|
|
|
|
|
|
|
|
```clj
|
|
|
|
:repositories [["releases" {:url "http://blueant.com/archiva/internal"
|
|
|
|
:username [:gpg :env/archiva_username]
|
|
|
|
:passphrase [:gpg :env/archiva_passphrase]}]]
|
|
|
|
```
|
|
|
|
|
|
|
|
In this example, both `:username` and `:password` will be looked up in
|
|
|
|
`~/.lein/credentials.clj.gpg` first, and only if a value is not available there will
|
|
|
|
the `ARCHIVA_*` env vars be checked. This allows you to avoid creating profiles
|
|
|
|
just to use different credential sources in e.g. a local development environment
|
|
|
|
vs. a centralized build environment.
|
2012-06-27 23:06:48 +00:00
|
|
|
|
|
|
|
## Deployment
|
2011-09-16 01:29:18 +00:00
|
|
|
|
2011-03-16 01:45:10 +00:00
|
|
|
Once you've set up a private repository and configured project.clj
|
|
|
|
appropriately, you can deploy to it:
|
|
|
|
|
2012-05-31 03:24:54 +00:00
|
|
|
$ lein deploy [repository-name]
|
2011-03-16 01:45:10 +00:00
|
|
|
|
2012-08-16 11:12:55 +00:00
|
|
|
If the project's current version is a `SNAPSHOT`, it will default to
|
2012-05-31 03:24:54 +00:00
|
|
|
deploying to the `snapshots` repository; otherwise it will default to
|
|
|
|
`releases`.
|
2012-08-16 11:12:55 +00:00
|
|
|
|
|
|
|
## Deploying to Maven Central
|
|
|
|
|
|
|
|
Deploying your libraries and other artifacts to [Maven
|
|
|
|
Central](http://search.maven.org/) is often desirable. Most tools that
|
|
|
|
use the Maven repository format (including Leiningen, Gradle, sbt, and
|
|
|
|
Maven itself) include Maven Central or one of its mirrors as a default
|
|
|
|
repository for resolving project dependencies. So, deploying your
|
|
|
|
libraries to Maven Central offers the widest distribution, especially if
|
|
|
|
your users are likely to be in languages other than Clojure.
|
|
|
|
|
|
|
|
Thankfully, Leiningen can deploy your libraries to Maven Central, with
|
|
|
|
a few additional bits of configuration. All of the guidance about
|
|
|
|
deploying to private repositories laid out above applies; but, here's a
|
|
|
|
step-by-step recipe from start to finish:
|
|
|
|
|
|
|
|
1. Register an account and groupId on `oss.sonatype.org`; refer to
|
|
|
|
[this](https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide)
|
|
|
|
for details on how to get registered (you can ignore most of the info on
|
|
|
|
that page regarding configuring Maven and/or ant, since we'll not be
|
|
|
|
touching those tools). Note that all artifacts you deploy to OSS will
|
|
|
|
need to use the groupId(s) you choose, so your project coordinates
|
|
|
|
should be set up to match; e.g.:
|
|
|
|
```clojure
|
|
|
|
(defproject your.group.id/projectname "x.y.z" ...)
|
|
|
|
```
|
|
|
|
|
|
|
|
2. Add your credentials for `oss.sonatype.org` to your
|
|
|
|
`~/.lein/credentials.clj.gpg` file. Something like this will do:
|
|
|
|
```clojure
|
|
|
|
{#"https://oss.sonatype.org/.*"
|
|
|
|
{:username "username" :password "password"}}
|
|
|
|
```
|
|
|
|
Refer to the instructions earlier on this page for how to encrypt a
|
|
|
|
plain-text `credentials.clj` using GPG.
|
|
|
|
|
|
|
|
3. Add the OSS deployment repository endpoints to your project.clj, e.g.:
|
|
|
|
```clojure
|
2012-08-23 19:10:01 +00:00
|
|
|
:deploy-repositories [["releases" {:url "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
|
|
|
|
:creds :gpg}
|
|
|
|
"snapshots" {:url "https://oss.sonatype.org/content/repositories/snapshots/"
|
|
|
|
:creds :gpg}]]
|
2012-08-16 11:12:55 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
4. Conform to OSS' requirements for uploaded artifacts' `pom.xml` files;
|
|
|
|
all you need to do is make sure the following slots are populated
|
|
|
|
properly in your `project.clj`:
|
|
|
|
```clojure
|
|
|
|
:description
|
|
|
|
:url
|
|
|
|
:license
|
|
|
|
:scm
|
|
|
|
:pom-addition
|
|
|
|
```
|
|
|
|
Examples of OSS-acceptable values for these entries can be seen in this
|
|
|
|
[`project.clj`
|
|
|
|
file](https://github.com/cemerick/piggieback/blob/master/project.clj).
|
|
|
|
Note that all of them should be appropriate for *your* project; blind
|
|
|
|
copy/paste is not appropriate here.
|
|
|
|
|
|
|
|
5. Run `lein deploy`. Leiningen will push all of the files it would
|
|
|
|
otherwise send to Clojars or your other private repository to the proper
|
|
|
|
OSS repository (either releases or snapshots depending on whether your
|
|
|
|
project's version number has `-SNAPSHOT` in it or not).
|
|
|
|
|
|
|
|
6. If you're deploying a release, log in to `oss.sonatype.org`, and
|
|
|
|
close and release/promote your staged repository. (This manual step
|
|
|
|
will eventually be automated through the use of a plugin.) The release
|
|
|
|
will show up in OSS' releases repository immediately, and sync to Maven
|
|
|
|
Central on the next cycle (~ 1-4 hours usually).
|
|
|
|
|