#!/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 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 # 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 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_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 ;; *) echo "install-ci-tools: unknown tool: $tool" >&2 exit 1 ;; esac done printf '%s\n' "$BIN_DIR"