Loving CircleCI 2.0 so far, but we’re noticing some extra build time when we want to complete tests at an early step and not continue performing steps (an early success).
Scenario: We have a monorepo and we build 10+ dockerfiles in parallel. However, if the directory with the dockerfile isn’t different than the one in master (i.e. git diff origin/master path/to/service is empty) we don’t have to test and can complete the test early. See the following circle.yaml
We don’t want to unnecessarily run the three steps after the check-for-difference step. I think we could do this with build dependencies, but we might have to checkout multiple times (maybe not that bad of a cost?). Is there a way to “exit early with success”?
I have a similar workflow that builds multiple Docker images from a monorepo. The solution I’ve come up with is to wrap that logic in a shell script which exits 0 if either the image is built or its not built because the relevant files did not change based on git diff.
The approach was to create a logical_changes.sh which parses the git refs in CIRCLE_COMPARE_URL to determine the appropriate git diff ref1 ref2 --name-only command to run. Then, for each logical change, which equates to a need to build a Docker image, that script exports values like CI_IMAGE_A_CHANGED or CI_IMAGE_B_CHANGED.
FInally, I have shell scripts for each docker build which source logical_changes.sh, test the value of the relevant CI_IMAGE_*_CHANGED then either exit 0 early or run the docker build.
Each Docker build in my workflow ends up looking something like:
Thanks for the tip @trumant, that approach makes a lot of sense and would definitely bring down our build time. The downside seems to be we have to run setup_remote_docker, and we also don’t get to see/profile the different steps in the circleci ui. That said I think I’ll use it in the mean time-
I wonder if this is a feature the circleci team might consider adding, I like your idea of some kind of when query, though I’m not sure how much control logic is appropriate in the config file- or how control logic would best be represented in the config.
Naive example of how a basic early success could be implemented in the config:
I would like to see this feature too. My company already has some code to figure out whether to skip a build if current branch has no changes related to this build. I just need a way to tell Circle CI to skip the rest of the build after this step yield a flag or something like that.
I’m not aware of a native skip feature, but would the git diff approach above be OK for you? That doesn’t skip the step from a CircleCI recording perspective, but you can elect not to run your tests based on whether there is a change in a repo sub-branch.
Although build servers cannot store state information, you could use the cache system to record the last known hash of a repo, which will help you determine whether to do tests or to skip them, perhaps in a shell script.