CircleCI 2.0 enables us to setup a flexible Docker environment and advanced caching mechanism to make your build faster. In order to make use of this new platform, I tried migrate our projects to CircleCI 2.0. But I had several pitfalls during this migration. So I’m going to clarify some points to be noted for those who are considering migration to CircleCI 2.0.
Caching by checksum
You can specify the artifact to be cached by the key you give. For example, if you want to save maven local repository as cache, you can write like this:
build:
steps:
- save_cache:
paths:
- ~/.m2
key: my-cache-${CIRCLE_SHA1}
- restore_cache:
key: my-cache-${CIRCLE_SHA1}
But it does not make use of caching mechanism fully because CircleCI cannot a restore cache due to using $CIRCLE_SHA1
. $CIRCLE_SHA1
is a commit hash that is changed in every build, which means we cannot use the cache saved this time in next time. We found it was necessary to use more robust value as cache key.
In this case, we know we can keep using the same cache unless the version of packages on which the my project depends is chaged. This version is specified in pom.xml
. So it means we can keep using the same package unless pom.xml
is not changed. We can achieve by writing like this:
build:
steps:
- save_cache:
paths:
- ~/.m2
key: my-cache-\{\{ checksum "pom.xml" \}\}
- restore_cache:
key: my-cache-\{\{ checksum "pom.xml" \}\}
Please ignore back slashes. Markdown does not work as expected. :( It looks like Jinja template. The detail is described here.
PATH environment variable
Environment variables can be set like this:
build:
environment:
- ENV_VAR1: VALUE1
- ENV_VAR2: VALUE2
- ENV_VAR3: VALUE3
But you should not set PATH
environment variable here. It says:
You currently cannot evaluate a variable when setting another one, so the fix is to set it to the string that $PATH evals to at that point. You can just docker run -it imagename:version echo $PATH.
So if you set PATH: $PATH:/some/to/path
, $PATH
is not evaluatated properly. It’s necessary to set in steps
.
Environment variable scope
$PATH
environment variable can be set in steps
section.
build:
steps:
- run:
name: Step 1
command: |
echo 'export PATH="$PATH:/path/to/somewhere"' >> ~/.bash_profile
source ~/.bash_profile
But this environment variable is valid only in this step. In short, it is not took over next step unless you write explicitly.
build:
steps:
- run:
name: Step 1
command: |
echo 'export PATH="$PATH:/path/to/somewhere"' >> ~/.bash_profile
source ~/.bash_profile
- run:
name: Step 2
command: |
echo $PATH # No /path/to/somewhere
We need to take care of the point too.
Reference
- CircleCI 2.0
- Caching
- [Using Environment Variables]https://circleci.com/docs/2.0/env-vars/