I’m trying to see if I can make my dependency installation jobs as fast as possible. I’ve already made some significant improvements to my install_gems
job that runs bundle install
. CircleCI doesn’t have a way to check if a cache exists, so I made another very small cache for this purpose.
- Just download a single file (Gemfile.lock) from GitHub
- Restore the
'bundle-exists-{{ checksum "Gemfile.lock" }}'
cache, which just contains a single empty file calledbundle-exists
- If
bundle-exists
is present, runcircleci-agent step halt; exit 0
- Otherwise, check out the source code, restore the cache, install gems, save the cache, touch
bundle-exists
, and save that “exists” cache as well
This is working really well, but now the main bottleneck is that I need to run this in a heavy Docker image (with build-essential
, other Ruby libraries, etc.) I would like to run this initial cache check in a minimal Alpine Linux image, and then start a full bundle install
job in the larger Docker image if the cache is missing.
So is there any way to conditionally run or skip a job based on the output of a previous job? Or is there a way to programmatically restart a job using a different Docker image?
Here’s my install_gems
job so far:
jobs:
install_gems:
docker:
- image: docspringcom/ci_base:c1e6ba3bb01a
auth:
username: $DOCKERHUB_USERNAME
password: $DOCKERHUB_PASSWORD
steps:
- run:
name: Download Gemfile.lock
command: |
FILE_PATH=Gemfile.lock
URL="https://raw.githubusercontent.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/${CIRCLE_BRANCH}/${FILE_PATH}"
curl -H "Authorization: token ${GITHUB_PERSONAL_ACCESS_TOKEN}" "${URL}" > "${FILE_PATH}"
- restore_cache:
keys: ['bundle-exists-{{ checksum "Gemfile.lock" }}']
- run: |
if [[ -f bundle-exists ]]; then
circleci-agent step halt
exit 0
fi
rm -f *
- checkout
- restore_cache:
keys:
- bundle-{{ checksum "Gemfile.lock" }}
- bundle
- run:
name: Install Gems
command: |
bundle check || bundle install --jobs 4 --retry 3
- save_cache:
key: bundle-{{ checksum "Gemfile.lock" }}
paths:
- vendor/bundle
- run: 'touch bundle-exists'
- save_cache:
key: bundle-exists-{{ checksum "Gemfile.lock" }}
paths: ['bundle-exists']