diff --git a/cleanup.sh b/cleanup.sh index d77b8e1..a17a390 100755 --- a/cleanup.sh +++ b/cleanup.sh @@ -7,8 +7,11 @@ # to cost 21-39 s per job here). JOB_STARTED (pre-job.sh) sweeps up after a # job whose runner was killed before this hook ran. # -# Intentionally not using set -e: individual cleanup failures should not -# prevent other cleanups from running. +# The runner runs this hook under `bash -e`, whatever the shebang says, and a +# non-zero exit fails the job ("Complete runner") even when every step passed. +# A missing directory is normal here (a runner that never ran Gradle has no +# ~/.gradle/caches), so every command ends in `|| true`, `busy` is cleared +# first, and the hook always exits 0. # # KEEP: the slot caches (see preflight-entrypoint.sh) and the work dir, which # lives in the slot (RUNNER_DATA_DIR/slots//work), not under /tmp. @@ -16,34 +19,35 @@ # Empty dir $1 (/tmp), keeping the dir itself. clean_tmp() { - find "$1" -mindepth 1 -maxdepth 1 -exec rm -rf {} + 2>/dev/null + find "$1" -mindepth 1 -maxdepth 1 -exec rm -rf {} + 2>/dev/null || true } cleanup() { local before after echo "[cleanup] Running post-job cleanup..." - before=$(df -h / | awk 'NR==2 {print $4}') + # The job is over: the pruner may trim this slot again. First, so nothing + # below can leave the marker behind (it would make the next job look like a + # crash recovery). + if [ -n "${RUNNER_SLOT_DIR:-}" ]; then rm -f "$RUNNER_SLOT_DIR/busy" || true; fi + before=$(df -h / | awk 'NR==2 {print $4}') || true clean_tmp /tmp # Gradle daemon / journals / locks only. Keep modules-2, build-cache-*, # transforms-*. $HOME covers both the root (default) and RUN_AS_ROOT=false # (/home/runner) runner users. - rm -rf "$HOME"/.gradle/daemon/ "$HOME"/.gradle/caches/journal-* 2>/dev/null + rm -rf "$HOME"/.gradle/daemon/ "$HOME"/.gradle/caches/journal-* 2>/dev/null || true # Shallow on purpose: Gradle's lock files sit at most three levels under # caches/, and a find over the whole (multi-GB) tree is what made this slow. - find "$HOME"/.gradle/caches -maxdepth 3 -name '*.lock' -delete 2>/dev/null + find "$HOME"/.gradle/caches -maxdepth 3 -name '*.lock' -delete 2>/dev/null || true # Runner diagnostic logs - find /actions-runner/_diag -name '*.log' -delete 2>/dev/null + find /actions-runner/_diag -name '*.log' -delete 2>/dev/null || true - # The job is over: the pruner may trim this slot again. - if [ -n "${RUNNER_SLOT_DIR:-}" ]; then rm -f "$RUNNER_SLOT_DIR/busy"; fi - - after=$(df -h / | awk 'NR==2 {print $4}') + after=$(df -h / | awk 'NR==2 {print $4}') || true echo "[cleanup] Post-job cleanup complete. Disk free: ${before} -> ${after}" } # Sourced (tests/): define the functions only. [ "${BASH_SOURCE[0]}" = "$0" ] || return 0 -cleanup +cleanup || true diff --git a/tests/cleanup.sh b/tests/cleanup.sh new file mode 100755 index 0000000..0378f6e --- /dev/null +++ b/tests/cleanup.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# The JOB_COMPLETED hook runs under `bash -e`, as the runner invokes it, and must +# exit 0 and clear the slot's `busy` marker whatever the home looks like: no +# Gradle cache at all (control runners, a runner that never ran Gradle), or a +# Gradle cache with daemon state to drop. A non-zero exit fails the job in +# "Complete runner"; a marker left behind makes every later job look like a +# crash recovery. /tmp is not wiped here: clean_tmp is stubbed out. +# bash tests/cleanup.sh +here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# shellcheck source=tests/harness.sh +source "$here/harness.sh" + +# Run cleanup.sh's main path under bash -e, with clean_tmp stubbed so the real +# /tmp is left alone. +hook() { + local home="$1" slot="$2" + HOME="$home" RUNNER_SLOT_DIR="$slot" bash -e -c ' + source "$1" + clean_tmp() { :; } + cleanup + ' _ "$root/cleanup.sh" >/dev/null 2>&1 +} + +slot="$work/slot" +mkdir -p "$slot" + +home="$work/empty" +mkdir -p "$home" +touch "$slot/busy" +hook "$home" "$slot" || fail "exit $? with no gradle cache" +gone "$slot/busy" + +home="$work/gradle" +mkdir -p "$home/.gradle/daemon/8.10" "$home/.gradle/caches/journal-1" "$home/.gradle/caches/modules-2/files-2.1" +touch "$home/.gradle/caches/modules-2/modules-2.lock" "$home/.gradle/caches/modules-2/files-2.1/keep.jar" +touch "$slot/busy" +hook "$home" "$slot" || fail "exit $? with a gradle cache" +gone "$slot/busy" +gone "$home/.gradle/daemon" +gone "$home/.gradle/caches/journal-1" +gone "$home/.gradle/caches/modules-2/modules-2.lock" +kept "$home/.gradle/caches/modules-2/files-2.1/keep.jar" + +finish "cleanup exits 0 under bash -e and always clears busy"