util: retry GNU tar setup downloads

The GNU tar CI job depends on git.savannah.gnu.org, which can fail
transiently during clone or submodule setup. Retry those network-dependent
setup steps with exponential backoff before failing the job.

Keep cleanup scoped to failed clone attempts, fail early if path_GNU already
points at a non-git directory, and tighten the helper script with pipefail and
shellcheck-clean quoting.
This commit is contained in:
Kevin Burke
2026-05-18 08:43:02 -07:00
parent 2cc665e2d3
commit b4865dab24
+85 -7
View File
@@ -1,21 +1,99 @@
#!/usr/bin/env bash
set -e
set -euo pipefail
ME="${0}"
ME_dir="$(dirname -- "$("${READLINK:-readlink}" -fm -- "${ME}")")"
REPO_main_dir="$(dirname -- "${ME_dir}")"
: ${PROFILE:=debug} # default profile
: "${PROFILE:=debug}" # default profile
export PROFILE
path_UUTILS=${path_UUTILS:-${REPO_main_dir}}
path_GNU="${path_GNU:-${path_UUTILS}/../gnu}"
retry_attempts() {
local attempts="${GNU_TAR_SETUP_ATTEMPTS:-3}"
local delay="${GNU_TAR_SETUP_RETRY_DELAY:-30}"
local description="${1}"
shift
local attempt=1
local status=0
if [[ ! "${attempts}" =~ ^[1-9][0-9]*$ ]]; then
echo "GNU_TAR_SETUP_ATTEMPTS must be a positive integer, got: ${attempts}" >&2
return 1
fi
if [[ ! "${delay}" =~ ^[1-9][0-9]*$ ]]; then
echo "GNU_TAR_SETUP_RETRY_DELAY must be a positive integer, got: ${delay}" >&2
return 1
fi
while (( attempt <= attempts )); do
if "$@"; then
return 0
else
status=$?
fi
if (( attempt == attempts )); then
echo "Failed to ${description} after ${attempts} attempts." >&2
return "${status}"
fi
echo "Failed to ${description} (attempt ${attempt}/${attempts}); retrying in ${delay}s..." >&2
sleep "${delay}"
attempt=$(( attempt + 1 ))
delay=$(( delay * 2 ))
done
}
clone_gnu_tar() {
local attempts="${GNU_TAR_SETUP_ATTEMPTS:-3}"
local delay="${GNU_TAR_SETUP_RETRY_DELAY:-30}"
local attempt=1
local status=0
if [[ ! "${attempts}" =~ ^[1-9][0-9]*$ ]]; then
echo "GNU_TAR_SETUP_ATTEMPTS must be a positive integer, got: ${attempts}" >&2
return 1
fi
if [[ ! "${delay}" =~ ^[1-9][0-9]*$ ]]; then
echo "GNU_TAR_SETUP_RETRY_DELAY must be a positive integer, got: ${delay}" >&2
return 1
fi
if [[ -e "${path_GNU}" ]]; then
echo "Cannot clone GNU tar: ${path_GNU} exists but is not a git checkout." >&2
return 1
fi
while (( attempt <= attempts )); do
if git clone --recurse-submodules https://git.savannah.gnu.org/git/tar.git "${path_GNU}"; then
return 0
else
status=$?
fi
if (( attempt == attempts )); then
echo "Failed to clone GNU tar after ${attempts} attempts." >&2
return "${status}"
fi
echo "Failed to clone GNU tar (attempt ${attempt}/${attempts}); retrying in ${delay}s..." >&2
rm -rf -- "${path_GNU}"
sleep "${delay}"
attempt=$(( attempt + 1 ))
delay=$(( delay * 2 ))
done
}
echo "Building uutils tar..."
cd "${path_UUTILS}"
cargo build --profile="${PROFILE}" --bin tarapp
if [[ ! -z "$CARGO_TARGET_DIR" ]]; then
if [[ -n "${CARGO_TARGET_DIR:-}" ]]; then
UU_BUILD_DIR="${CARGO_TARGET_DIR}/${PROFILE}"
else
UU_BUILD_DIR="${path_UUTILS}/target/${PROFILE}"
@@ -28,11 +106,11 @@ echo "Created symlink ${UU_BUILD_DIR}/tar -> tarapp"
# Clone GNU tar if needed
if test ! -d "${path_GNU}/.git"; then
echo "Cloning GNU tar..."
git clone --recurse-submodules https://git.savannah.gnu.org/git/tar.git "${path_GNU}"
clone_gnu_tar
cd "${path_GNU}"
git checkout v1.35
git submodule update --init --recursive
retry_attempts "update GNU tar submodules" git submodule update --init --recursive
# Bootstrap requires gnulib and generates the configure script
./bootstrap --skip-po
fi
@@ -46,4 +124,4 @@ if [ ! -f Makefile ]; then
fi
echo "Building GNU tar (for test suite)..."
make -j$(nproc)
make -j"$(nproc)"