Published: 2021-09-04
In Bazel, a successful build should be a quiet build. While build failures
should, of course, print ample information to stderr to aide in troubleshooting,
any custom Bazel code you write should not output progress information to stdout
or stderr. Let Bazel be responsible for overall build progress reporting.
For genrule or bash-based targets, I’ll often implement this by capturing
all output to a log file and only printing the log file if the target fails.
For example:
#!/bin/bash
#
# This is a bash build script that may be invoked in something like
# ctx.actions.run() in a custom bazel rule
set -euo pipefail
# Perform all cleanup
cleanup() {
# Output the build log on failures
if [ "$1" != "0" ]; then
if [[ -v LOG_FILE ]]; then
if [[ -r $LOG_FILE ]]; then
echo "Build log:" 1>&2
cat $LOG_FILE 1>&2
fi
fi
fi
if [[ -v TMP_DIR ]]; then
rm -rf $TMP_DIR
fi
}
trap 'cleanup $?' EXIT
# Ensure all build steps log stdout and stderr to LOG_FILE
TMP_DIR=$(mktemp -d)
LOG_FILE=$TMP_DIR/build.log
# Perform build steps
build_step1 >> $LOG_FILE 2>&1
build_step2 >> $LOG_FILE 2>&1
...