Problem: All build steps MUST run without error prior to final success. No skipping or configurably ignoring some errors in CircleCI built-in commands is available


#1

We’ve recently integrated a new use case in our system.

Before:
We used a marker file to identify whether we should skip the tests for this run, based on our own rules.
Build steps that are to be skipped implement something like [ -f .skip_tests ] && exit 0 to skip executing the real work.

The change:
We added caching of an artifact post-build using save_cache. We want to pull it in on future builds, so save_cache is appropriate here.

Problem 1:
What broke:
save_cache only works if the file to save actually exists.

Our workaround (didn’t actually work as well - see problem 2):

- save_cache:
    key: our_key_here-{{ checksum "/path/to/artifact.json" }}
    paths:
      - /path/to/artifact.json
      - /path/to/always_existing_file

In short, include a file that always exists in the save_cache command, just to ensure that save_cache will succeed.

Problem 2:
What broke:
If specificed in steps, save_cache must always run prior to a build being green in total. With our workaround as noted in problem 1, we would successfully generate a cache without the actual artifact file we cared about, just the single marker file. Future builds would restore_cache, look confused, then turn red.

Our final (working!) workaround:

- restore_cache:
    key: our_key_here
- run: (pseudocode) if new file, overwrite file from cache, otherwise leave restored file in place.
- save_cache:
    key: our_key_here-{{ checksum "/path/to/artifact.json" }}
    paths:
      - /path/to/artifact.json

Some suggested solutions:

  1. Add a special command that we can invoke in a run: step to exit the build early with success or a skip step. A variant is a specific exit status that would skip all following build steps (c.f. git bisect). This would be amazing!
  2. Add a pass_on_empty: true flag to save_cache and persist_to_workspace that would just make it not save anything if the cache would be empty, but still appear as green. Default behavior is appropriate as is.

Related to: Skip checkout/save_cache/restore_cache steps?


#2