#!/usr/bin/env bash set -euo pipefail VSCODE_DIR=/opt/vscode PRODUCT_JSON="${VSCODE_DIR}/resources/app/product.json" RELEASES_API='https://update.code.visualstudio.com/api/releases/stable' installed_version() { if [[ ! -f "${PRODUCT_JSON}" ]]; then return 0 fi python3 -c "import json; print(json.load(open('${PRODUCT_JSON}'))['version'])" } latest_version() { curl -fsSL "${RELEASES_API}" | python3 -c 'import json, sys; print(json.load(sys.stdin)[0])' } vscode_arch() { case "$(uname -m)" in x86_64) echo linux-x64 ;; aarch64) echo linux-arm64 ;; *) echo "unsupported architecture: $(uname -m)" >&2 exit 1 ;; esac } needs_upgrade() { local installed="$1" latest="$2" [[ -z "${installed}" ]] && return 0 [[ "${installed}" == "${latest}" ]] && return 1 [[ "$(printf '%s\n' "${installed}" "${latest}" | sort -V | head -n1)" == "${installed}" ]] } installed="$(installed_version || true)" latest="$(latest_version)" if ! needs_upgrade "${installed}" "${latest}"; then if [[ -z "${installed}" ]]; then echo "VS Code is not installed at ${VSCODE_DIR}" else echo "VS Code ${installed} is up to date" fi exit 0 fi echo "Upgrading VS Code: ${installed:-not installed} -> ${latest}" arch="$(vscode_arch)" tmp="$(mktemp -d)" trap 'rm -rf "${tmp}"' EXIT archive="${tmp}/vscode.tar.gz" curl -fsSL "https://update.code.visualstudio.com/${latest}/${arch}/stable" -o "${archive}" tar -xzf "${archive}" -C "${tmp}" extract_dir="$(find "${tmp}" -maxdepth 1 -type d -name 'VSCode-linux-*' -print -quit)" if [[ -z "${extract_dir}" ]]; then echo "failed to find extracted VS Code directory" >&2 exit 1 fi mkdir -p "$(dirname "${VSCODE_DIR}")" if [[ -d "${VSCODE_DIR}" ]]; then rm -rf "${VSCODE_DIR}.old" mv "${VSCODE_DIR}" "${VSCODE_DIR}.old" fi mv "${extract_dir}" "${VSCODE_DIR}" rm -rf "${VSCODE_DIR}.old" echo "VS Code upgraded to ${latest}"