ci: make python setup resilient
All checks were successful
CI/CD Pipeline / Manual Action Help (push) Has been skipped
CI/CD Pipeline / Start Dev Containers in Dokploy (push) Has been skipped
CI/CD Pipeline / Drop and Recreate Dev Database (push) Has been skipped
CI/CD Pipeline / Quality Gate (push) Successful in 8m16s
CI/CD Pipeline / Build and Push Images (push) Successful in 1m36s
CI/CD Pipeline / Internal Notify (push) Successful in 1s
CI/CD Pipeline / Deploy Dev in Dokploy (push) Successful in 1s
All checks were successful
CI/CD Pipeline / Manual Action Help (push) Has been skipped
CI/CD Pipeline / Start Dev Containers in Dokploy (push) Has been skipped
CI/CD Pipeline / Drop and Recreate Dev Database (push) Has been skipped
CI/CD Pipeline / Quality Gate (push) Successful in 8m16s
CI/CD Pipeline / Build and Push Images (push) Successful in 1m36s
CI/CD Pipeline / Internal Notify (push) Successful in 1s
CI/CD Pipeline / Deploy Dev in Dokploy (push) Successful in 1s
This commit is contained in:
@@ -11,11 +11,53 @@ else
|
||||
PYTHON_BIN="python${PYTHON_MAJOR}"
|
||||
fi
|
||||
|
||||
python_matches() {
|
||||
local candidate="$1"
|
||||
[[ -x "${candidate}" ]] || return 1
|
||||
"${candidate}" - "${PYTHON_MAJOR}" "${PYTHON_MINOR:-}" <<'PY'
|
||||
import sys
|
||||
|
||||
expected_major = int(sys.argv[1])
|
||||
expected_minor = sys.argv[2]
|
||||
if sys.version_info.major != expected_major:
|
||||
raise SystemExit(1)
|
||||
if expected_minor and sys.version_info.minor != int(expected_minor):
|
||||
raise SystemExit(1)
|
||||
PY
|
||||
}
|
||||
|
||||
python_has_venv() {
|
||||
local candidate="$1"
|
||||
"${candidate}" -m venv --help >/dev/null 2>&1
|
||||
}
|
||||
|
||||
print_if_usable() {
|
||||
local candidate="$1"
|
||||
if python_matches "${candidate}" && python_has_venv "${candidate}"; then
|
||||
printf '%s\n' "${candidate}"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
if command -v "${PYTHON_BIN}" >/dev/null 2>&1; then
|
||||
command -v "${PYTHON_BIN}"
|
||||
exit 0
|
||||
print_if_usable "$(command -v "${PYTHON_BIN}")"
|
||||
fi
|
||||
|
||||
TOOLCACHE_DIR="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
|
||||
HOME_DIR="${HOME:-/root}"
|
||||
|
||||
shopt -s nullglob
|
||||
# shellcheck disable=SC2140
|
||||
for candidate in \
|
||||
"${TOOLCACHE_DIR}"/Python/"${PYTHON_MAJOR}.${PYTHON_MINOR}"*/x64/bin/python \
|
||||
"${TOOLCACHE_DIR}"/Python/"${PYTHON_MAJOR}.${PYTHON_MINOR}"*/x64/bin/python3 \
|
||||
"${TOOLCACHE_DIR}"/uv-python/cpython-"${PYTHON_MAJOR}.${PYTHON_MINOR}"*/bin/python \
|
||||
"${HOME_DIR}"/.local/share/uv/python/cpython-"${PYTHON_MAJOR}.${PYTHON_MINOR}"*/bin/python \
|
||||
"${HOME_DIR}"/.cache/uv/python/cpython-"${PYTHON_MAJOR}.${PYTHON_MINOR}"*/bin/python; do
|
||||
print_if_usable "${candidate}"
|
||||
done
|
||||
shopt -u nullglob
|
||||
|
||||
APT_RUNNER=()
|
||||
if [[ "$(id -u)" -ne 0 ]]; then
|
||||
APT_RUNNER=(sudo)
|
||||
@@ -23,12 +65,42 @@ fi
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
"${APT_RUNNER[@]}" apt-get update >&2
|
||||
if ! "${APT_RUNNER[@]}" apt-get install -y "${PYTHON_BIN}" "${PYTHON_BIN}-venv" >&2; then
|
||||
"${APT_RUNNER[@]}" apt-get install -y software-properties-common >&2
|
||||
"${APT_RUNNER[@]}" add-apt-repository -y ppa:deadsnakes/ppa >&2
|
||||
"${APT_RUNNER[@]}" apt-get update >&2
|
||||
"${APT_RUNNER[@]}" apt-get install -y "${PYTHON_BIN}" "${PYTHON_BIN}-venv" >&2
|
||||
if "${APT_RUNNER[@]}" apt-get update >&2 \
|
||||
&& "${APT_RUNNER[@]}" apt-get install -y "${PYTHON_BIN}" "${PYTHON_BIN}-venv" >&2; then
|
||||
print_if_usable "$(command -v "${PYTHON_BIN}")"
|
||||
fi
|
||||
|
||||
command -v "${PYTHON_BIN}"
|
||||
install_uv_standalone() {
|
||||
if command -v uv >/dev/null 2>&1; then
|
||||
command -v uv
|
||||
return 0
|
||||
fi
|
||||
|
||||
local uv_dir
|
||||
uv_dir="$(mktemp -d)"
|
||||
local install_url="https://astral.sh/uv/${UV_VERSION:-0.7.2}/install.sh"
|
||||
if ! curl -LsSf "${install_url}" | env UV_INSTALL_DIR="${uv_dir}/bin" sh >&2; then
|
||||
curl -LsSf "https://astral.sh/uv/install.sh" | env UV_INSTALL_DIR="${uv_dir}/bin" sh >&2
|
||||
fi
|
||||
printf '%s\n' "${uv_dir}/bin/uv"
|
||||
}
|
||||
|
||||
UV_BIN="$(install_uv_standalone)"
|
||||
UV_PYTHON_INSTALL_DIR="${TOOLCACHE_DIR:-${HOME_DIR}/.cache}/uv-python" \
|
||||
"${UV_BIN}" python install "${TARGET_VERSION}" --no-progress >&2
|
||||
|
||||
UV_PYTHON_CANDIDATE="$(
|
||||
UV_PYTHON_INSTALL_DIR="${TOOLCACHE_DIR:-${HOME_DIR}/.cache}/uv-python" \
|
||||
"${UV_BIN}" python find "${TARGET_VERSION}" --managed-python
|
||||
)"
|
||||
print_if_usable "${UV_PYTHON_CANDIDATE}"
|
||||
|
||||
if "${APT_RUNNER[@]}" apt-get install -y software-properties-common >&2 \
|
||||
&& "${APT_RUNNER[@]}" add-apt-repository -y ppa:deadsnakes/ppa >&2 \
|
||||
&& "${APT_RUNNER[@]}" apt-get update >&2 \
|
||||
&& "${APT_RUNNER[@]}" apt-get install -y "${PYTHON_BIN}" "${PYTHON_BIN}-venv" >&2; then
|
||||
print_if_usable "$(command -v "${PYTHON_BIN}")"
|
||||
fi
|
||||
|
||||
printf 'Unable to install a usable Python %s with venv support\n' "${TARGET_VERSION}" >&2
|
||||
exit 1
|
||||
|
||||
Reference in New Issue
Block a user