#!/usr/bin/env bash # Shared helpers for scripts/ci/*.sh. Everything here is plain bash so the same script # runs identically on a developer's machine and on a bare CI runner. set -euo pipefail log() { echo "[$(date -u +'%Y-%m-%dT%H:%M:%SZ')] $*" } fail() { echo "[$(date -u +'%Y-%m-%dT%H:%M:%SZ')] ERROR: $*" >&2 exit 1 } # Repo root, regardless of the caller's cwd. CI_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" # The .NET channel to install when no SDK is found. This has to match the TargetFramework # the projects declare — a git hook runs with a stripped PATH, so "whatever channel is # current" quietly installed .NET 9 for a net10.0 repo and failed the whole build. DOTNET_CHANNEL="${DOTNET_CHANNEL:-10.0}" # Puts a .NET SDK on PATH. Prefers one that is already installed — including the common # per-user and system locations a git hook's PATH does not include — and only downloads # one as a last resort, so a bare runner behaves the same as a dev machine. ensure_dotnet() { if command -v dotnet > /dev/null 2>&1; then return 0 fi local candidate for candidate in "${DOTNET_ROOT:-}" "$CI_ROOT/.dotnet" "$HOME/.dotnet" /usr/share/dotnet /usr/lib/dotnet; do if [[ -n "$candidate" && -x "$candidate/dotnet" ]]; then log "Using the .NET SDK at $candidate" export PATH="$candidate:$PATH" export DOTNET_ROOT="$candidate" return 0 fi done local install_dir="$CI_ROOT/.dotnet" log "dotnet not found; installing the .NET $DOTNET_CHANNEL SDK into $install_dir" curl -fsSL https://dot.net/v1/dotnet-install.sh -o "/tmp/dotnet-install.sh" bash "/tmp/dotnet-install.sh" --channel "$DOTNET_CHANNEL" --install-dir "$install_dir" rm -f "/tmp/dotnet-install.sh" export PATH="$install_dir:$PATH" export DOTNET_ROOT="$install_dir" } ensure_node() { command -v npm > /dev/null 2>&1 || fail "npm not found on PATH; install Node.js to build the web client" }