感谢大佬的开源,不过由于本项目暂时不支持自动更新,vscode提示更新后还需到Release页手动检查一下是否存在更新后的server版本,在vscode更新比较快的情况下有点麻烦,所以vibe了下面这个脚本,方便看到vscode提示可以更新后用脚本自动检查server版是否也已更新,并自动下载和安装。
(脚本写的是默认下载x64版本安装包,如果需要不同版本的话可以手动修改一下,下载位置默认是执行此脚本时的PWD)
使用方法:直接使用bash运行此脚本即可,会检查release页的最新版本并让用户选择是否更新。
#!/usr/bin/env bash
set -euo pipefail
REPO="${REPO:-MikeWang000000/vscode-server-centos7}"
INSTALL_DIR="${INSTALL_DIR:-$HOME/.vscode-server}"
DOWNLOAD_DIR="${DOWNLOAD_DIR:-$PWD}"
API_URL="https://api.github.com/repos/${REPO}/releases/latest"
LATEST_URL="https://github.com/${REPO}/releases/latest"
TMP_JSON=""
TMP_TAR=""
usage() {
cat <<'USAGE'
Usage: ./vscode-server-update.sh
Environment variables:
REPO GitHub repo, default: MikeWang000000/vscode-server-centos7
INSTALL_DIR VS Code Server install dir, default: ~/.vscode-server
DOWNLOAD_DIR Tarball download dir, default: current directory
USAGE
}
need_cmd() {
if ! command -v "$1" >/dev/null 2>&1; then
echo "Error: required command not found: $1" >&2
exit 1
fi
}
cleanup() {
if [[ -n "${TMP_JSON:-}" ]]; then
rm -f "$TMP_JSON"
fi
if [[ -n "${TMP_TAR:-}" ]]; then
rm -f "$TMP_TAR"
fi
}
parse_release_with_python() {
python3 - "$1" <<'PY'
import json
import re
import sys
path = sys.argv[1]
with open(path, "r", encoding="utf-8") as f:
release = json.load(f)
assets = release.get("assets", [])
pattern = re.compile(r"^vscode-server_.+_x64\.tar\.gz$")
asset = next((item for item in assets if pattern.match(item.get("name", ""))), None)
if asset is None:
raise SystemExit("no vscode-server_*_x64.tar.gz asset found in latest release")
tag = release.get("tag_name") or ""
version = tag[1:] if tag.startswith("v") else tag
if not version:
name = asset["name"]
match = re.match(r"^vscode-server_(.+)_x64\.tar\.gz$", name)
version = match.group(1) if match else "unknown"
print(version)
print(asset["name"])
print(asset["browser_download_url"])
PY
}
parse_release_with_sed() {
local json_file="$1"
local flat_file version asset_name asset_url
flat_file="$(mktemp)"
sed 's/[{},]/\
/g' "$json_file" > "$flat_file"
version="$(sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"v\{0,1\}\([^"]*\)".*/\1/p' "$flat_file" | head -n 1)"
asset_name="$(sed -n 's/.*"name"[[:space:]]*:[[:space:]]*"\(vscode-server_[^"]*_x64\.tar\.gz\)".*/\1/p' "$flat_file" | head -n 1)"
asset_url="$(sed -n 's#.*"browser_download_url"[[:space:]]*:[[:space:]]*"\([^"]*vscode-server_[^"]*_x64\.tar\.gz\)".*#\1#p' "$flat_file" | head -n 1)"
rm -f "$flat_file"
if [[ -z "${version}" && -n "${asset_name}" ]]; then
version="${asset_name#vscode-server_}"
version="${version%_x64.tar.gz}"
fi
if [[ -z "${version}" || -z "${asset_name}" || -z "${asset_url}" ]]; then
echo "Error: failed to parse latest release metadata from ${API_URL}" >&2
exit 1
fi
printf '%s\n%s\n%s\n' "$version" "$asset_name" "$asset_url"
}
release_from_latest_redirect() {
local effective_url tag version asset_name asset_url
if ! effective_url="$(curl -fsSLI -o /dev/null -w '%{url_effective}' -H 'User-Agent: vscode-server-update.sh' "$LATEST_URL")"; then
echo "Error: failed to access ${LATEST_URL}" >&2
exit 1
fi
tag="${effective_url##*/}"
version="${tag#v}"
if [[ -z "$version" || "$version" == "$effective_url" || "$tag" == "latest" || "$effective_url" != */releases/tag/v* ]]; then
echo "Error: failed to detect latest release tag from ${LATEST_URL}" >&2
exit 1
fi
asset_name="vscode-server_${version}_x64.tar.gz"
asset_url="https://github.com/${REPO}/releases/download/v${version}/${asset_name}"
printf '%s\n%s\n%s\n' "$version" "$asset_name" "$asset_url"
}
fetch_latest_info() {
local tmp_json="$1"
if curl -fsSL -H 'Accept: application/vnd.github+json' -H 'User-Agent: vscode-server-update.sh' "$API_URL" -o "$tmp_json"; then
if command -v python3 >/dev/null 2>&1; then
parse_release_with_python "$tmp_json"
else
parse_release_with_sed "$tmp_json"
fi
return
fi
echo "GitHub API unavailable; falling back to ${LATEST_URL}" >&2
release_from_latest_redirect
}
confirm_update() {
local version="$1"
local answer
printf 'Update to VS Code Server %s? [Y/N] ' "$version"
read -r answer
case "$answer" in
Y|y|YES|Yes|yes)
return 0
;;
*)
return 1
;;
esac
}
main() {
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
usage
exit 0
fi
need_cmd curl
need_cmd tar
need_cmd sed
need_cmd head
local latest_info latest_version asset_name asset_url tarball current_version
TMP_JSON="$(mktemp)"
TMP_TAR=""
trap cleanup EXIT
echo "Fetching latest release metadata from ${API_URL}"
latest_info="$(fetch_latest_info "$TMP_JSON")"
latest_version="$(printf '%s\n' "$latest_info" | sed -n '1p')"
asset_name="$(printf '%s\n' "$latest_info" | sed -n '2p')"
asset_url="$(printf '%s\n' "$latest_info" | sed -n '3p')"
tarball="${DOWNLOAD_DIR%/}/${asset_name}"
echo "Latest version : ${latest_version}"
echo "Package : ${asset_name}"
echo "Download URL : ${asset_url}"
echo "Install dir : ${INSTALL_DIR}"
echo "Download dir : ${DOWNLOAD_DIR}"
if [[ -x "${INSTALL_DIR}/code-latest" ]]; then
current_version="$("${INSTALL_DIR}/code-latest" --version 2>/dev/null | head -n 1 || true)"
if [[ -n "$current_version" ]]; then
echo "Current version: ${current_version}"
fi
fi
if ! confirm_update "$latest_version"; then
echo "Canceled."
exit 0
fi
mkdir -p "$DOWNLOAD_DIR" "$INSTALL_DIR"
TMP_TAR="${tarball}.part.$$"
echo "Downloading ${asset_name}"
curl -fL --retry 3 --retry-delay 2 -o "$TMP_TAR" "$asset_url"
mv -f "$TMP_TAR" "$tarball"
TMP_TAR=""
echo "Extracting to ${INSTALL_DIR}"
tar xzf "$tarball" -C "$INSTALL_DIR" --strip-components 1
if [[ ! -x "${INSTALL_DIR}/code-latest" ]]; then
echo "Error: ${INSTALL_DIR}/code-latest is missing or not executable after extraction" >&2
exit 1
fi
echo "Patching VS Code Server"
"${INSTALL_DIR}/code-latest" --patch-now
echo "Update completed: ${latest_version}"
}
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
main "$@"
fi
感谢大佬的开源,不过由于本项目暂时不支持自动更新,vscode提示更新后还需到Release页手动检查一下是否存在更新后的server版本,在vscode更新比较快的情况下有点麻烦,所以vibe了下面这个脚本,方便看到vscode提示可以更新后用脚本自动检查server版是否也已更新,并自动下载和安装。
(脚本写的是默认下载x64版本安装包,如果需要不同版本的话可以手动修改一下,下载位置默认是执行此脚本时的PWD)
使用方法:直接使用bash运行此脚本即可,会检查release页的最新版本并让用户选择是否更新。