#!/usr/bin/env bash # GitLab's current Linux runner uses the Shell executor, so job-level `image:` # declarations do not provide their advertised SDKs. Source this file from a # job to install a pinned, checksum-verified toolchain inside CI_PROJECT_DIR. set -euo pipefail mode="${1:-}" if [[ -z "$mode" ]]; then echo 'bootstrap-linux-toolchain: mode is required (dotnet|deno|android)' >&2 return 64 2>/dev/null || exit 64 fi : "${CI_PROJECT_DIR:?CI_PROJECT_DIR is required}" tools_root="$CI_PROJECT_DIR/.ci-tools" mkdir -p "$tools_root" download_verified() { local url="$1" local expected_checksum="$2" local destination="$3" curl --fail --silent --show-error --location "$url" --output "$destination" case "${#expected_checksum}" in 64) printf '%s %s\n' "$expected_checksum" "$destination" | sha256sum --check --status ;; 128) printf '%s %s\n' "$expected_checksum" "$destination" | sha512sum --check --status ;; *) echo 'bootstrap-linux-toolchain: unsupported checksum length' >&2 return 65 ;; esac } bootstrap_dotnet() { export DOTNET_ROOT="$tools_root/dotnet-sdk-10.0.302" if [[ ! -x "$DOTNET_ROOT/dotnet" ]]; then local archive archive="$(mktemp "${TMPDIR:-/tmp}/d3ro-dotnet.XXXXXX.tar.gz")" download_verified \ 'https://builds.dotnet.microsoft.com/dotnet/Sdk/10.0.302/dotnet-sdk-10.0.302-linux-x64.tar.gz' \ '10069bec8783596484a610332f090d562802a41b9b40e3327a5a5688b572e10c296ae300f940d40461f23c157ed1b0843c2f8e6b3f20d8d8d9d83432d8143bac' \ "$archive" mkdir -p "$DOTNET_ROOT" tar --extract --gzip --file "$archive" --directory "$DOTNET_ROOT" rm -f "$archive" fi export DOTNET_CLI_TELEMETRY_OPTOUT=1 export DOTNET_NOLOGO=1 export PATH="$DOTNET_ROOT:$PATH" [[ "$(dotnet --version)" == '10.0.302' ]] } bootstrap_deno() { local deno_root="$tools_root/deno-2.8.1" if [[ ! -x "$deno_root/deno" ]]; then local archive archive="$(mktemp "${TMPDIR:-/tmp}/d3ro-deno.XXXXXX.zip")" download_verified \ 'https://github.com/denoland/deno/releases/download/v2.8.1/deno-x86_64-unknown-linux-gnu.zip' \ '2d7bb6195226ac832e0bf7109a115f0af65ee69ac797a4bbde5b27a06cc242d9' \ "$archive" mkdir -p "$deno_root" unzip -q "$archive" -d "$deno_root" rm -f "$archive" fi export PATH="$deno_root:$PATH" local deno_version deno_version="$(deno --version)" [[ "$deno_version" == deno\ 2.8.1* ]] } bootstrap_android() { export JAVA_HOME="$tools_root/microsoft-jdk-17.0.20.1" if [[ ! -x "$JAVA_HOME/bin/java" ]]; then local jdk_archive jdk_archive="$(mktemp "${TMPDIR:-/tmp}/d3ro-jdk.XXXXXX.tar.gz")" download_verified \ 'https://download.visualstudio.microsoft.com/download/pr/a9672056-0a4d-425d-8488-f481ee56319c/5897054114dd5c0acab8489cd815dad9/microsoft-jdk-17.0.20.1-linux-x64.tar.gz' \ 'd00e5b04e9726b63d915706c7049e5297c9f40239ce8a12fcc68b7267fa91ad2' \ "$jdk_archive" mkdir -p "$JAVA_HOME" tar --extract --gzip --file "$jdk_archive" --directory "$JAVA_HOME" --strip-components=1 rm -f "$jdk_archive" fi export PATH="$JAVA_HOME/bin:$PATH" local java_version java_version="$(java -version 2>&1)" [[ "$java_version" == *'17.0.20.1'* ]] export ANDROID_HOME="$tools_root/android-sdk" export ANDROID_SDK_ROOT="$ANDROID_HOME" local sdkmanager_path="$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" if [[ ! -x "$sdkmanager_path" ]]; then local cli_archive cli_stage cli_archive="$(mktemp "${TMPDIR:-/tmp}/d3ro-android-cli.XXXXXX.zip")" cli_stage="$(mktemp -d "${TMPDIR:-/tmp}/d3ro-android-cli.XXXXXX")" download_verified \ 'https://dl.google.com/android/repository/commandlinetools-linux-15859902_latest.zip' \ '4e4c464f145a7512b57d088ac6c278c03c9eea610886b35a5e0804e74eedf583' \ "$cli_archive" unzip -q "$cli_archive" -d "$cli_stage" mkdir -p "$ANDROID_HOME/cmdline-tools" mv "$cli_stage/cmdline-tools" "$ANDROID_HOME/cmdline-tools/latest" rmdir "$cli_stage" rm -f "$cli_archive" fi export PATH="$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH" sdkmanager --version >/dev/null if [[ ! -f "$ANDROID_HOME/platforms/android-36/android.jar" \ || ! -x "$ANDROID_HOME/build-tools/36.0.0/aapt2" \ || ! -x "$ANDROID_HOME/platform-tools/adb" ]]; then set +o pipefail yes | sdkmanager --licenses >/dev/null local license_status=$? set -o pipefail [[ "$license_status" -eq 0 ]] sdkmanager 'platform-tools' 'platforms;android-36' 'build-tools;36.0.0' >/dev/null fi [[ -f "$ANDROID_HOME/platforms/android-36/android.jar" ]] [[ -x "$ANDROID_HOME/build-tools/36.0.0/aapt2" ]] [[ -x "$ANDROID_HOME/platform-tools/adb" ]] } case "$mode" in dotnet) bootstrap_dotnet ;; deno) bootstrap_deno ;; android) bootstrap_android ;; *) echo "bootstrap-linux-toolchain: unsupported mode: $mode" >&2 return 64 2>/dev/null || exit 64 ;; esac