Configuration Tips and Tricks
Custom Clone Command¶
By default, Cirrus CI uses a Git client implemented purely in Go to perform a clone of
a single branch with full Git history and no tags. It is possible to control clone depth via CIRRUS_CLONE_DEPTH
environment variable.
Customizing clone behavior is a simple as overriding clone_script
. For example, here an override to use a pre-installed
Git client (if your build environment has it) to do a shallow clone of a single branch:
task:
clone_script: |
if [ -z "$CIRRUS_PR" ]; then
git clone --recursive --branch=$CIRRUS_BRANCH https://x-access-token:${CIRRUS_REPO_CLONE_TOKEN}@github.com/${CIRRUS_REPO_FULL_NAME}.git $CIRRUS_WORKING_DIR
git reset --hard $CIRRUS_CHANGE_IN_REPO
else
git clone --recursive https://x-access-token:${CIRRUS_REPO_CLONE_TOKEN}@github.com/${CIRRUS_REPO_FULL_NAME}.git $CIRRUS_WORKING_DIR
git fetch origin pull/$CIRRUS_PR/head:pull/$CIRRUS_PR
git reset --hard $CIRRUS_CHANGE_IN_REPO
fi
# ...
In addition if you need to use Git tags, set CIRRUS_CLONE_TAGS
environment variable to true
:
You can also use the script below, but note that it requires git
to be present
in the container:
go-git
benefits
Using go-git
made it possible not to require a pre-installed Git from an execution environment. For example,
most of alpine
-based containers don't have Git pre-installed. Because of go-git
you can even use distroless
containers with Cirrus CI, which don't even have an Operating System.
Sharing configuration between tasks¶
You can use YAML aliases to share configuration options between multiple tasks. For example, here is a 2-task build which only runs for "master", PRs and tags, and installs some framework:
# Define a node anywhere in YAML file to create an alias. Make sure the name doesn't clash with an existing keyword.
regular_task_template: ®ULAR_TASK_TEMPLATE
only_if: $CIRRUS_BRANCH == 'master' || $CIRRUS_TAG != '' || $CIRRUS_PR != ''
env:
FRAMEWORK_PATH: "${HOME}/framework"
install_framework_script: curl https://example.com/framework.tar | tar -C "${FRAMEWORK_PATH}" -x
task:
# This operator will insert REGULAR_TASK_TEMPLATE at this point in the task node.
<< : *REGULAR_TASK_TEMPLATE
name: linux
container:
image: alpine:latest
test_script: ls "${FRAMEWORK_PATH}"
task:
<< : *REGULAR_TASK_TEMPLATE
name: osx
macos_instance:
image: catalina-xcode
test_script: ls -w "${FRAMEWORK_PATH}"
Long lines in configuration file¶
If you like your YAML file to fit on your screen, and some commands are just too long, you can split them across multiple lines. YAML supports a variety of options to do that, for example here's how you can split ENCRYPTED values:
env:
GOOGLE_APPLICATION_CREDENTIALS_DATA: "ENCRYPTED\
[3287dbace8346dfbe98347d1954eca923487fd8ea7251983\
cb6d5edabdf6fe5abd711238764cbd6efbde6236abd6f274]"
Setting environment variables from scripts¶
Even through most of the time you can configure environment variables via env
, there are cases when a variable value is obtained only when the task is already running.
Normally you'd use export
for that, but since each script instruction is executed in a separate shell, the exported variables won't propagate to the next instruction.
However, there's a simple solution: just write your variables in a KEY=VALUE
format to the file referenced by the CIRRUS_ENV
environment variable.
Here's a simple example: