Skip to content

Instantly share code, notes, and snippets.

@phdoerfler
Last active December 21, 2021 15:50
Show Gist options
  • Save phdoerfler/bf0c9af1bb2f37a6483d6acce0573e7c to your computer and use it in GitHub Desktop.
Save phdoerfler/bf0c9af1bb2f37a6483d6acce0573e7c to your computer and use it in GitHub Desktop.
A script to use with git bisect run, to automatically find a bad revision of a project using sbt
#!/usr/bin/env sh
# requires: GNU timeout
# code 0 if the current source code is good/old
# code between 1 and 127 (inclusive), except 125, if the current source code is bad/new.
# code 125 should be used when the current source code cannot be tested.
# see https://git-scm.com/docs/git-bisect
#
# Use (after you copied this to bisect-test.sh _outside_ your repository):
#
# git reset --hard
# git bisect reset
# git bisect start
# git bisect good <a good revision>
# git bisect bad <a bad revision>
# chmod u+x ../bisect-test.sh
# rm "$HOME/tmp/bisect.log"
# git bisect run ../bisect-test.sh
LOG_FILE="$HOME/tmp/bisect.log"
SBT_CMD="sbt --batch --supershell=never --color=always"
COMMAND_LOAD_BUILD="exit"
COMMAND_COMPILE="compile"
COMMAND_GOOD_BAD="testOnly tests/test_encoder_block.py"
TIMEOUT_LOAD_BUILD="30"
TIMEOUT_COMPILE="60"
TIMEOUT_GOOD_BAD="300"
# Setup
(./install-sbt.sh)
. ./env/bin/activate
. ./.env
export PATH="$(pwd)/target/tools/sbt/bin:$PATH"
export SBT_OPTS="$SBT_OPTS -Xmx512M -Xms512M"
export SBT_OPTS="$SBT_OPTS -Djline.terminal=jline.UnsupportedTerminal"
log() {
echo "\e[7m$1\e[0m" >&2
echo "$1" >> "$LOG_FILE"
}
GL=$(git log -1 --pretty=medium)
log "\nNow evaluating:\n$GL"
narrow_down_cause() {
timeout "$TIMEOUT_LOAD_BUILD" $SBT_CMD "$COMMAND_LOAD_BUILD"
case $? in
124) # the exit code timeout uses to signal that a timeout occurred
log "Ran into timeout loading the build. Telling git to skip."
sleep 1
git reset --hard
exit 125
;;
0)
log "Build loaded OK. Checking if failure was due to a failed compilation…"
narrow_down_cause_compile
;;
*)
log "A problem occurred loading the build. Telling git to skip."
sleep 1
git reset --hard
exit 125
;;
esac
}
narrow_down_cause_compile() {
timeout "$TIMEOUT_COMPILE" $SBT_CMD "$COMMAND_COMPILE"
case $? in
124) # the exit code timeout uses to signal that a timeout occurred
log "Ran into timeout compiling. Telling git to skip."
sleep 1
git reset --hard
exit 125
;;
0)
log "Compile finished OK, failure must have been due to tests. Marking revision as bad."
sleep 1
git reset --hard
exit 1
;;
*)
log "A problem occurred while compiling. Telling git to skip."
sleep 1
git reset --hard
exit 125
;;
esac
}
# Run the command we are actually interested in
timeout "$TIMEOUT_GOOD_BAD" $SBT_CMD "$COMMAND_GOOD_BAD"
case $? in
124) # the exit code timeout uses to signal that a timeout occurred
log "Ran into timeout. Telling git to skip."
git reset --hard
exit 125
;;
0)
log "Marking revision as good."
git reset --hard
exit 0
;;
*)
log "An error occurred, narrowing down the cause."
narrow_down_cause
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment