The panel backend has 25 pytest tests that no workflow has ever run. Making them run needs a throwaway virtualenv, and uv is what builds it in seconds against the pinned requirements-dev.txt. Installing it through install-ci-tools.sh rather than assuming it is on the runner keeps the version in one place, where the other three tools already live, and where the Renovate regex manager can move it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
142 lines
4.0 KiB
Bash
Executable File
142 lines
4.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Installs the pinned CI linters into "$TOOLS_DIR/bin" and echoes that directory
|
|
# on stdout, so callers can do:
|
|
#
|
|
# export PATH="$(bash .gitea/workflows/install-ci-tools.sh kubeconform shellcheck):$PATH"
|
|
#
|
|
# Versions come from tool-versions.env next to this script and are kept fresh by
|
|
# Renovate. Re-running is cheap: an already-installed tool at the pinned version
|
|
# is left alone.
|
|
set -euo pipefail
|
|
|
|
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
# shellcheck source=tool-versions.env
|
|
. "$here/tool-versions.env"
|
|
|
|
TOOLS_DIR="${TOOLS_DIR:-${RUNNER_TEMP:-/tmp}/homelab-tools}"
|
|
BIN_DIR="$TOOLS_DIR/bin"
|
|
mkdir -p "$BIN_DIR"
|
|
|
|
arch="$(uname -m)"
|
|
# Upstream projects disagree on arch spelling: kubeconform and actionlint use
|
|
# Go names (amd64/arm64), shellcheck uses uname names (x86_64/aarch64).
|
|
case "$arch" in
|
|
x86_64 | amd64)
|
|
goarch=amd64
|
|
sharch=x86_64
|
|
;;
|
|
aarch64 | arm64)
|
|
goarch=arm64
|
|
sharch=aarch64
|
|
;;
|
|
*)
|
|
echo "install-ci-tools: unsupported architecture: $arch" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
fetch() {
|
|
# fetch <url> <dest>
|
|
if command -v curl >/dev/null 2>&1; then
|
|
curl -sSLf --retry 3 -o "$2" "$1"
|
|
elif command -v wget >/dev/null 2>&1; then
|
|
wget -q -O "$2" "$1"
|
|
else
|
|
echo "install-ci-tools: neither curl nor wget is available" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# installed_version <command>
|
|
# Prints the version of an already-installed tool, or nothing. Each tool spells
|
|
# its version flag differently, hence the case.
|
|
installed_version() {
|
|
local out
|
|
case "$1" in
|
|
kubeconform) out="$("$1" -v 2>/dev/null | head -1 || true)" ;;
|
|
*) out="$("$1" --version 2>/dev/null | head -1 || true)" ;;
|
|
esac
|
|
printf '%s' "$out"
|
|
}
|
|
|
|
# at_version <command> <expected>
|
|
at_version() {
|
|
case "$(installed_version "$1")" in
|
|
*"$2"*) return 0 ;;
|
|
*) return 1 ;;
|
|
esac
|
|
}
|
|
|
|
install_kubeconform() {
|
|
if at_version kubeconform "v${KUBECONFORM_VERSION}"; then
|
|
return 0
|
|
fi
|
|
local tmp
|
|
tmp="$(mktemp -d)"
|
|
fetch "https://github.com/yannh/kubeconform/releases/download/v${KUBECONFORM_VERSION}/kubeconform-linux-${goarch}.tar.gz" \
|
|
"$tmp/kubeconform.tar.gz"
|
|
tar -xzf "$tmp/kubeconform.tar.gz" -C "$tmp" kubeconform
|
|
install -m 0755 "$tmp/kubeconform" "$BIN_DIR/kubeconform"
|
|
rm -rf "$tmp"
|
|
}
|
|
|
|
install_shellcheck() {
|
|
if at_version shellcheck "${SHELLCHECK_VERSION}"; then
|
|
return 0
|
|
fi
|
|
local tmp
|
|
tmp="$(mktemp -d)"
|
|
fetch "https://github.com/koalaman/shellcheck/releases/download/v${SHELLCHECK_VERSION}/shellcheck-v${SHELLCHECK_VERSION}.linux.${sharch}.tar.xz" \
|
|
"$tmp/shellcheck.tar.xz"
|
|
tar -xJf "$tmp/shellcheck.tar.xz" -C "$tmp" --strip-components=1 "shellcheck-v${SHELLCHECK_VERSION}/shellcheck"
|
|
install -m 0755 "$tmp/shellcheck" "$BIN_DIR/shellcheck"
|
|
rm -rf "$tmp"
|
|
}
|
|
|
|
install_uv() {
|
|
if at_version uv "${UV_VERSION}"; then
|
|
return 0
|
|
fi
|
|
local tmp
|
|
tmp="$(mktemp -d)"
|
|
# uv release tags carry no leading v, unlike every other tool installed here.
|
|
fetch "https://github.com/astral-sh/uv/releases/download/${UV_VERSION}/uv-${sharch}-unknown-linux-gnu.tar.gz" \
|
|
"$tmp/uv.tar.gz"
|
|
tar -xzf "$tmp/uv.tar.gz" -C "$tmp" --strip-components=1 "uv-${sharch}-unknown-linux-gnu/uv"
|
|
install -m 0755 "$tmp/uv" "$BIN_DIR/uv"
|
|
rm -rf "$tmp"
|
|
}
|
|
|
|
install_actionlint() {
|
|
if at_version actionlint "${ACTIONLINT_VERSION}"; then
|
|
return 0
|
|
fi
|
|
local tmp
|
|
tmp="$(mktemp -d)"
|
|
fetch "https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/actionlint_${ACTIONLINT_VERSION}_linux_${goarch}.tar.gz" \
|
|
"$tmp/actionlint.tar.gz"
|
|
tar -xzf "$tmp/actionlint.tar.gz" -C "$tmp" actionlint
|
|
install -m 0755 "$tmp/actionlint" "$BIN_DIR/actionlint"
|
|
rm -rf "$tmp"
|
|
}
|
|
|
|
wanted=("$@")
|
|
if [ "${#wanted[@]}" -eq 0 ]; then
|
|
wanted=(kubeconform shellcheck actionlint)
|
|
fi
|
|
|
|
for tool in "${wanted[@]}"; do
|
|
case "$tool" in
|
|
kubeconform) install_kubeconform ;;
|
|
shellcheck) install_shellcheck ;;
|
|
actionlint) install_actionlint ;;
|
|
uv) install_uv ;;
|
|
*)
|
|
echo "install-ci-tools: unknown tool: $tool" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
printf '%s\n' "$BIN_DIR"
|