diff --git a/shell/ci/release/docker-authn.sh b/shell/ci/release/docker-authn.sh index 3fe823c16..8f8267757 100755 --- a/shell/ci/release/docker-authn.sh +++ b/shell/ci/release/docker-authn.sh @@ -29,6 +29,9 @@ source "${LIB_DIR}/mise.sh" # shellcheck source=../../lib/shell.sh source "${LIB_DIR}/shell.sh" +# shellcheck source=../../lib/version.sh +source "${LIB_DIR}/version.sh" + info "Ensuring that 'gh' is installed" ensure_mise_installed diff --git a/shell/ci/testing/setup-devenv.sh b/shell/ci/testing/setup-devenv.sh index 4d2000991..6625e225f 100755 --- a/shell/ci/testing/setup-devenv.sh +++ b/shell/ci/testing/setup-devenv.sh @@ -14,6 +14,8 @@ source "$DIR/../../lib/box.sh" source "$DIR/../../lib/mise.sh" # shellcheck source=../../lib/shell.sh source "$DIR/../../lib/shell.sh" +# shellcheck source=../../lib/version.sh +source "$DIR/../../lib/version.sh" # Arguments PROVISION="${PROVISION:-"false"}" diff --git a/shell/circleci/machine.sh b/shell/circleci/machine.sh index 5a6276760..dafd8d4fe 100755 --- a/shell/circleci/machine.sh +++ b/shell/circleci/machine.sh @@ -22,6 +22,9 @@ source "$LIB_DIR"/mise.sh # shellcheck source=../lib/shell.sh source "$LIB_DIR"/shell.sh +# shellcheck source=../lib/version.sh +source "$LIB_DIR"/version.sh + if [[ $OSTYPE == "darwin"* ]]; then brew install bash docker gnupg gnu-sed # Rosetta is required for awscli installed by mise diff --git a/shell/circleci/setup.sh b/shell/circleci/setup.sh index c00c2f8e8..3daf6c2a2 100755 --- a/shell/circleci/setup.sh +++ b/shell/circleci/setup.sh @@ -24,6 +24,12 @@ source "${LIB_DIR}/mise.sh" # shellcheck source=../lib/shell.sh source "${LIB_DIR}/shell.sh" +# shellcheck source=../lib/version.sh +source "${LIB_DIR}/version.sh" + +info "🔨 Setting up mise 🧑‍🍳" +ensure_mise_installed + if gh_installed; then # shellcheck disable=SC2119 # Why: no extra args needed to pass to ghaccesstoken in this case. @@ -36,9 +42,6 @@ if ! mise_manages_tool_versions; then "$CI_DIR/env/asdf.sh" fi -info "🔨 Setting up mise 🧑‍🍳" -ensure_mise_installed - "$CI_DIR/env/mise.sh" if circleci_pr_is_fork; then diff --git a/shell/fmt.sh b/shell/fmt.sh index 1873dcf87..c58d58e36 100755 --- a/shell/fmt.sh +++ b/shell/fmt.sh @@ -16,6 +16,8 @@ source "$DIR/lib/logging.sh" source "$DIR/lib/mise.sh" # shellcheck source=./lib/shell.sh source "$DIR/lib/shell.sh" +# shellcheck source=./lib/version.sh +source "$DIR/lib/version.sh" # add extra (per project) linters linters=("$DIR/linters"/*.sh) diff --git a/shell/lib/mise.sh b/shell/lib/mise.sh index da7119987..19aa8bebb 100644 --- a/shell/lib/mise.sh +++ b/shell/lib/mise.sh @@ -18,7 +18,16 @@ ensure_mise_installed() { export PATH="$HOME/.local/bin:$PATH" fi - if ! command_exists mise; then + if command_exists mise; then + local minMiseVersion + minMiseVersion="$(mise config get min_version.hard 2>/dev/null || true)" + if [[ -n $minMiseVersion ]] && ! mise_version_compatible "$minMiseVersion"; then + info "Upgrading mise from $(mise_version) to meet minimum version requirement of $minMiseVersion" + install_mise "$minMiseVersion" + + mise --version + fi + else if [[ -n $is_root ]]; then export MISE_INSTALL_PATH=/usr/local/bin/mise fi @@ -57,27 +66,40 @@ ensure_mise_installed() { fi } +# install_mise([version]) +# # Installs mise via the official install script (making sure that it is # signed via GPG). If that fails in CI and the CI worker is running # Ubuntu, install mise via the official apt repository. +# +# If a version is specified, installs that version, otherwise the +# latest version is installed. The apt fallback will always install +# the latest version. install_mise() { + local version="${1:-}" local install_script=/tmp/mise-install.sh if [[ ! -f $install_script || "$(wc -c "$install_script" | awk '{print $1}')" -eq 0 ]]; then if ! retry 5 5 gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x24853ec9f655ce80b48e6c3a8b81c9d17413a06d; then error "Could not import mise GPG release key" - install_mise_via_apt_if_ubuntu_in_ci + install_mise_via_apt_if_ubuntu_in_ci "$version" fi # ensure the install script is signed with the mise release key if ! download_mise_install_script | gpg --decrypt >"$install_script"; then error "Could not download or verify mise install script" - install_mise_via_apt_if_ubuntu_in_ci + install_mise_via_apt_if_ubuntu_in_ci "$version" fi fi + if [[ -n ${MISE_VERSION:-} && -n $version ]]; then + warn "MISE_VERSION is already set to '$MISE_VERSION', it will be overridden to '$version' for the installation process" + fi ( set +e + if [[ -n $version ]]; then + export MISE_VERSION="$version" + fi if ! retry 5 5 sh "$install_script"; then - install_mise_via_apt_if_ubuntu_in_ci + install_mise_via_apt_if_ubuntu_in_ci "$version" fi ) run_mise settings set http_retries 3 @@ -107,8 +129,13 @@ download_mise_install_script() { http_fetch "https://mise.jdx.dev/install.sh.sig" } +# install_mise_via_apt_if_ubuntu_in_ci([version]) +# # Install mise via apt if running in CI on Ubuntu. +# The `version` parameter is only used to warn the user that you can't +# install a custom version via apt. install_mise_via_apt_if_ubuntu_in_ci() { + local version="${1:-}" local distro if ! in_ci_environment; then warn "Falling back to apt installation of mise is only supported in CI environments" @@ -120,6 +147,9 @@ install_mise_via_apt_if_ubuntu_in_ci() { warn "Falling back to apt installation of mise is only supported on Ubuntu" return 1 fi + if [[ -n $version ]]; then + warn "Cannot install specific version of mise, installing latest version instead" + fi warn "Installing mise via apt, mise will be installed to /usr/bin/mise instead" install_mise_via_apt } @@ -384,14 +414,30 @@ devbase_configure_global_tools() { # Requires sourcing version.sh. devbase_install_mise_tools() { # experimental setting needed for Go backend - local miseVersion - miseVersion="$(mise version --json | gojq --raw-output .version | awk '{print $1}')" - if ! has_minimum_version "2025.10.11" "$miseVersion"; then + if ! mise_version_compatible "2025.10.11"; then mise settings set experimental true fi devbase_mise install --yes } +# The current version of mise. +# Does not use JSON+gojq as it's mise-installed and could possibly fail +# if the version is too old for the project mise config. +mise_version() { + "$(find_mise)" version --quiet | tail -n 1 | awk '{print $1}' +} + +# mise_version_compatible(minVersion) +# +# Whether the current mise version is >= the minimum version specified. +# Requires sourcing version.sh. +mise_version_compatible() { + local minVersion miseVersion + minVersion="$1" + miseVersion="$(mise_version)" + has_minimum_version "$minVersion" "$miseVersion" +} + # Installs a given tool via `mise install`, assuming that it's defined # in the local `mise.toml` file and not already installed. mise_install_if_needed() { diff --git a/shell/lib/mise/stub.sh b/shell/lib/mise/stub.sh index d821683c5..963943188 100644 --- a/shell/lib/mise/stub.sh +++ b/shell/lib/mise/stub.sh @@ -15,3 +15,5 @@ source "$DEVBASE_LIB_DIR/logging.sh" source "$DEVBASE_LIB_DIR/mise.sh" # shellcheck source=../shell.sh source "$DEVBASE_LIB_DIR/shell.sh" +# shellcheck source=../version.sh +source "$DEVBASE_LIB_DIR/version.sh" diff --git a/shell/linters.sh b/shell/linters.sh index 9ba54d745..e20b54201 100755 --- a/shell/linters.sh +++ b/shell/linters.sh @@ -15,6 +15,8 @@ source "$DIR/lib/logging.sh" source "$DIR/lib/mise.sh" # shellcheck source=./lib/shell.sh source "$DIR/lib/shell.sh" +# shellcheck source=./lib/version.sh +source "$DIR/lib/version.sh" if [[ -n $SKIP_LINTERS ]] || [[ -n $SKIP_VALIDATE ]]; then info "Skipping linters" diff --git a/shell/mise.sh b/shell/mise.sh index 885aa8d9c..38322270f 100755 --- a/shell/mise.sh +++ b/shell/mise.sh @@ -7,19 +7,13 @@ set -euo pipefail DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" DEVBASE_LIB_DIR="$DIR/lib" -# shellcheck source=./lib/logging.sh -source "$DEVBASE_LIB_DIR/logging.sh" - -# shellcheck source=./lib/mise.sh -source "$DEVBASE_LIB_DIR/mise.sh" - -# shellcheck source=./lib/shell.sh -source "$DEVBASE_LIB_DIR/shell.sh" +# shellcheck source=./lib/mise/stub.sh +source "$DEVBASE_LIB_DIR/mise/stub.sh" ensure_mise_installed 1>&2 misePath="$(find_mise)" -ghToken="$(gh auth token)" +ghToken="$(run_gh auth token)" GITHUB_TOKEN="$ghToken" wait_for_gh_rate_limit MISE_GITHUB_TOKEN="$ghToken" exec "$misePath" "$@" diff --git a/shell/test.sh b/shell/test.sh index 5560bd3b1..abf8351ed 100755 --- a/shell/test.sh +++ b/shell/test.sh @@ -23,6 +23,9 @@ source "$DIR/lib/mise.sh" # shellcheck source=./lib/shell.sh source "$DIR/lib/shell.sh" +# shellcheck source=./lib/version.sh +source "$DIR/lib/version.sh" + # TEST_FLAGS is an array of flags to pass to `go test`. TEST_FLAGS must # be a string value. It will be split on spaces. #