Fork me on GitHub
#boot
<
2018-02-13
>
kenny00:02:21

Is there a way to configure Boot's :repositories via the command line? We use a private Maven repository (http://deps.co 🙂 ) and we don't hard code the environment variables in our build.boot files. This means everyone has a profile.boot with configure-repositories! set up on their machines (as written here: https://github.com/boot-clj/boot/wiki/Repository-Credentials-and-Deploying#environment). This creates a problem for running builds on the CI because the CI needs access to that private Maven repository. It'd be easiest to simply set the repositories via the command line. Right now the only option I'm seeing is to create a whole new Docker image that includes a profile.boot in it with the configure-repositories! call. How is everyone else solving this problem? Do you all go the custom Docker image route?

danielcompton00:02:01

@kenny can you give a sample of what you have currently? Is there a :repositories key with URL in the build.boot?

danielcompton00:02:04

If you have your build.boot pulling env vars then you can provide them via CI, that's the most common pattern for this kind of thing

kenny00:02:09

Each build.boot has this:

:repositories #(conj % ["private" {:url "my_url"}])
And this in the profile.boot:
(configure-repositories!
  (fn [{:keys [url] :as repo-map}]
    (->> (condp re-find url
           #"my_url"
           {:username (System/getenv "DEPS_API_KEY")
            :password (System/getenv "DEPS_API_SECRET")}
           #".*" nil)
         (merge repo-map))))

kenny00:02:35

The problem is that we aren't hard coding the environment variables for each repository.

kenny00:02:56

It's configured differently for each developer.

danielcompton00:02:14

Could you put that configure-repositories! call in the build.boot?

kenny00:02:17

Not as part of the actual code checked in. That would defeat the purpose of doing it this way. I suppose I could technically add it as the first line in the build.boot when the CI is building. That seems a bit nasty though.

danielcompton00:02:42

What is the benefit of keeping that configure-repositories call separate from the build.boot?

kenny00:02:11

Forces other developers to use the same env vars you wrote in the build.boot.

danielcompton00:02:45

Oh, so you mean one developer might have their env vars stored as DEPS_API_KEY and another might have it as PRIVATE_MAVEN_REPO_KEY?

danielcompton00:02:05

Ah, now I see what you meant about dynamic env vars

seancorfield00:02:53

I think for repeatability I would just mandate "This is what the env vars shall be named" and everyone should just deal with it.

kenny01:02:28

I don't see how repeatability is an issue here. It really becomes an issue when you are working for multiple companies.

kenny01:02:11

How the developer logs into the repository is independent from actually downloading the artifacts.

kenny01:02:54

I suppose one option is to create a "bootstrap" task that simply writes the profile.boot to BOOT_HOME. That task would need to be available publicly.

danielcompton01:02:51

Could you include a task in the build.boot to specify the repository?

danielcompton01:02:55

So it would look something like

danielcompton01:02:48

boot configure-repositories! :url "" :username ${CI_USERNAME} :password ${CI_PASSWORD} test

seancorfield01:02:59

@kenny Wouldn't you have a separate build.boot for each client's projects and therefore each project could have specific env vars? Perhaps I'm just not clear why individual developers would use different env vars for the same project...

kenny01:02:55

If you have two projects that both use the env var DEPS_API_KEY then that won't work.

kenny01:02:52

You could use direnv to scope the env vars but in a more complex scenario the projects may need to interact with each other, sharing Maven repositories. This means you'd need to rename the environment var to be more specific, which you can totally do that (i.e. MYCOMPANY_DEPS_API_KEY). Except now you are requiring everyone else to change their setup. I don't see a reason to mandate that change when logging in and downloading artifacts are two entirely independent tasks.

seancorfield03:02:47

@kenny I was suggesting maybe naming the vars to match the project or the client -- hence making them unique. Unique global naming...

kenny03:02:34

@seancorfield That's another possibility except that makes CI configuration a pain. You would then need to ensure all your projects on the CI have the unique env var configured. There isn't any easy way to do this on most CI systems. Circle CI makes it easy to configure global env vars for a whole organization (via Contexts) which in turn makes it easy to rotate those keys.

seancorfield03:02:58

Ah, gotcha. I can see how you'd end up with a lot of env vars defined on CI...

dominicm09:02:46

So, could you do something like (when (getenv "CI_KEY") (configure...)) which is somewhat CI specific. OR use java system properties, which can be specified at the cli