Skip to content

Commit e213870

Browse files
committed
Cirrus: Improve caching effectiveness
Prior to this commit, the cache maintained for the main branch has grown to over 16gigabytes. Uploading it is causing frequent branch-level CI failures due to being larger than the maximum allowable size by Cirrus. Attempt to fix this by introducing a cache-grooming script and altering the cache-key being used. Content for the grooming script comes mainly from two places: 1. [Cargo documentation](https://doc.rust-lang.org/nightly/cargo/guide/build-cache.html) 2. The rust-cache github action [(typescript) source code](https://github.com/Swatinem/rust-cache/tree/master/src) Signed-off-by: Chris Evich <[email protected]>
1 parent 749ce93 commit e213870

File tree

3 files changed

+75
-6
lines changed

3 files changed

+75
-6
lines changed

.cirrus.yml

+9-6
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,11 @@ build_task:
5454
# Required to be set explicitly since fingerprint_key is also set
5555
reupload_on_changes: true
5656
targets_cache: &targets_cache
57-
# Similar to cargo_cache, but holds the actual compiled artifacts. This must
58-
# be scoped similar to bin_cache to avoid binary pollution across cache
59-
# contexts. For example, two PRs that happen to coincidentally change
60-
# and use cache. Adjust vX if cache schema changes.
57+
# Similar to cargo_cache, but holds the actual compiled dependent artifacts.
58+
# This should be scoped to a hash of the dependency-metadata lock file.
59+
# Cirrus-CI will automatically use separate caches for PRs and branches.
6160
folder: "$CARGO_TARGET_DIR"
62-
fingerprint_key: "targets_v2_${CIRRUS_TAG}${DEST_BRANCH}${CIRRUS_PR}_amd64" # Cache only within same tag, branch, or PR (branch will be 'pull/#')
61+
fingerprint_script: echo -e "targets_v3_${CIRRUS_TAG}${DEST_BRANCH}${CIRRUS_PR}_amd64\n---\n$(<Cargo.lock)\n---\n$(<Cargo.toml)"
6362
reupload_on_changes: true
6463
bin_cache: &bin_cache
6564
# This simply prevents rebuilding bin/netavark for every subsequent task.
@@ -70,6 +69,7 @@ build_task:
7069
reupload_on_changes: true
7170
setup_script: &setup "$SCRIPT_BASE/setup.sh"
7271
main_script: &main "$SCRIPT_BASE/runner.sh $CIRRUS_TASK_NAME"
72+
cache_grooming_script: &groom bash "$SCRIPT_BASE/cache_groom.sh"
7373
upload_caches: [ "cargo", "targets", "bin" ]
7474

7575

@@ -86,7 +86,9 @@ build_aarch64_task:
8686
reupload_on_changes: true
8787
targets_cache: &targets_cache_aarch64
8888
folder: "$CARGO_TARGET_DIR"
89-
fingerprint_key: "targets_v2_${CIRRUS_TAG}${DEST_BRANCH}${CIRRUS_PR}_aarch64" # Cache only within same tag, branch, or PR (branch will be 'pull/#')
89+
# N/B: Should exactly match (except for arch) line from build_task (above).
90+
# (No, there isn't an easy way to not duplicate most of this :()
91+
fingerprint_script: echo -e "targets_v3_${CIRRUS_TAG}${DEST_BRANCH}${CIRRUS_PR}_aarch64\n---\n$(<Cargo.lock)\n---\n$(<Cargo.toml)"
9092
reupload_on_changes: true
9193
bin_cache: &bin_cache_aarch64
9294
# This simply prevents rebuilding bin/netavark for every subsequent task.
@@ -95,6 +97,7 @@ build_aarch64_task:
9597
reupload_on_changes: true
9698
setup_script: *setup
9799
main_script: *main
100+
cache_grooming_script: *groom
98101
upload_caches: [ "cargo", "targets", "bin" ]
99102
# Downstream CI needs the aarch64 binaries from this CI system.
100103
# However, we don't want to confuse architectures.

contrib/cirrus/cache_groom.sh

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/bin/bash
2+
#
3+
# This script is intended to be run from Cirrus-CI to prepare the
4+
# rust targets cache for re-use during subsequent runs. This mainly
5+
# involves removing files and directories which change frequently
6+
# but are cheap/quick to regenerate - i.e. prevent "cache-flapping".
7+
# Any other use of this script is not supported and may cause harm.
8+
9+
set -eo pipefail
10+
11+
source $(dirname ${BASH_SOURCE[0]})/lib.sh
12+
13+
if [[ "$CIRRUS_CI" != true ]]; then
14+
die "Script is not intended for use outside of Cirrus-CI"
15+
fi
16+
17+
req_env_vars CARGO_HOME CARGO_TARGET_DIR CIRRUS_BUILD_ID
18+
cd $CARGO_TARGET_DIR
19+
20+
# Giant-meat-cleaver HACK: Sometimes rust cache simply gets out-of-hand
21+
# large (gigabytes). There isn't a good way to fix this or account for it
22+
# in some intelligent way. Any time the Cirrus-CI build ID is evenly
23+
# divisible by 15 (chosen arbitrarily) clobber the whole thing and make
24+
# the next run entirely re-populate cache.
25+
if ((CIRRUS_BUILD_ID%15==0)); then
26+
msg "It's a cache-clobber run, yay! Forcing the next build to re-populate cache from scratch."
27+
rm -rf ./* ./.??*
28+
touch CACHE_WAS_CLOBBERED
29+
30+
cd $CARGO_HOME
31+
rm -rf ./* ./.??*
32+
touch CACHE_WAS_CLOBBERED
33+
fi
34+
35+
# Ref: https://doc.rust-lang.org/nightly/cargo/guide/build-cache.html
36+
# https://github.com/Swatinem/rust-cache/tree/master/src
37+
for targetname in $(find ./ -type d -maxdepth 0); do
38+
msg "Grooming $CARGO_TARGET_DIR/$targetname..."
39+
cd $CARGO_TARGET_DIR/$targetname
40+
# Any top-level hidden files or directories
41+
showrun rm -rf ./.??*
42+
# Example targets
43+
showrun rm -rf ./target/debug/examples
44+
# Documentation
45+
showrun rm -rf ./target/doc
46+
# Internal to rust build process
47+
showrun rm -rf ./target/debug/deps ./target/debug/incremental ./target/debug/build
48+
done
49+
50+
# Ref: https://doc.rust-lang.org/nightly/cargo/guide/cargo-home.html#caching-the-cargo-home-in-ci
51+
cd $CARGO_HOME
52+
for dirname in $(find ./ -type d -maxdepth 2); do
53+
case "$dirname" in
54+
./bin) ;& # same steps as next item
55+
./registry/index) ;&
56+
./registry/cache) ;&
57+
./git/db) continue ;; # Keep
58+
*) rm -rf $dirname ;; # Remove
59+
esac
60+
done

contrib/cirrus/lib.sh

+6
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ else # set default values - see make_cienv() below
3232
# VM Images are built with this setup
3333
CARGO_HOME="${CARGO_HOME:-/var/cache/cargo}"
3434
source $CARGO_HOME/env
35+
36+
# Make caching more effective - disable incremental compilation,
37+
# so that the Rust compiler doesn't waste time creating the
38+
# additional artifacts required for incremental builds.
39+
# Ref: https://github.com/marketplace/actions/rust-cache#cache-details
40+
CARGO_INCREMENTAL=0
3541
fi
3642

3743
# END Global export of all variables

0 commit comments

Comments
 (0)