diff options
| author | kj_sh604 | 2026-05-19 20:20:06 -0400 |
|---|---|---|
| committer | kj_sh604 | 2026-05-19 20:20:06 -0400 |
| commit | df6b874be8695e87c50f65b7da2667fc726f1a6c (patch) | |
| tree | 28b743926e245438a2c9fca8891bff6f4e521c0b | |
initial: first POSIX iterations
| -rwxr-xr-x | build-code-server.sh | 136 | ||||
| -rwxr-xr-x | code-server-wrapper.sh | 22 |
2 files changed, 158 insertions, 0 deletions
diff --git a/build-code-server.sh b/build-code-server.sh new file mode 100755 index 0000000..60d904b --- /dev/null +++ b/build-code-server.sh @@ -0,0 +1,136 @@ +#!/bin/sh + +# build-code-server.sh +# downloads the official code-server release and packages it as a portable AppImage. +# the resulting AppImage bundles everything and requires no system installation. + +# usage: +# sh build-code-server.sh +# PKGVER=4.420.0 sh build-code-server.sh # override version +# +# running the output AppImage: +# regular: ./code-server-VERSION-ARCH.AppImage [args] +# docker: APPIMAGE_EXTRACT_AND_RUN=1 ./code-server-VERSION-ARCH.AppImage [args] + +set -e + +PKGVER="${PKGVER:-4.118.0}" +PKGNAME="code-server" +GITHUB_URL="https://github.com/coder/code-server" + +# - check required tools +for _cmd in curl tar; do + if ! command -v "$_cmd" > /dev/null 2>&1; then + printf 'error: required tool not found: %s\n' "$_cmd" >&2 + exit 1 + fi +done + +# - detect host architecture +UNAME_ARCH="$(uname -m)" +case "$UNAME_ARCH" in + x86_64) + RELEASE_ARCH="amd64" + ;; + aarch64) + RELEASE_ARCH="arm64" + ;; + *) + printf 'error: unsupported architecture: %s\n' "$UNAME_ARCH" >&2 + exit 1 + ;; +esac + +RELEASE_NAME="${PKGNAME}-${PKGVER}-linux-${RELEASE_ARCH}" +TARBALL="${RELEASE_NAME}.tar.gz" +TARBALL_URL="${GITHUB_URL}/releases/download/v${PKGVER}/${TARBALL}" +APPIMAGETOOL_URL="https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-${UNAME_ARCH}.AppImage" + +# - icon urls: try versioned tag, fall back to main branch +ICON_URL="https://raw.githubusercontent.com/coder/code-server/v${PKGVER}/src/browser/media/pwa-icon-512.png" +ICON_FALLBACK_URL="https://raw.githubusercontent.com/coder/code-server/main/src/browser/media/pwa-icon-512.png" + +OUTPUT_DIR="$(pwd)" +WORKDIR="$(mktemp -d)" +APPDIR="${WORKDIR}/AppDir" + +# - always clean up temp workdir on exit +cleanup() { + rm -rf "$WORKDIR" +} +trap cleanup EXIT INT TERM + +printf '==> setting up build directory...\n' +mkdir -p \ + "${APPDIR}/usr/lib" \ + "${APPDIR}/usr/bin" \ + "${APPDIR}/usr/share/icons/hicolor/512x512/apps" + +cd "$WORKDIR" + +# - download the official pre-built release tarball (same source as PKGBUILD) +printf '==> downloading code-server v%s (%s)...\n' "$PKGVER" "$RELEASE_ARCH" +curl -fL --progress-bar -o "$TARBALL" "$TARBALL_URL" + +printf '==> extracting tarball...\n' +tar -xzf "$TARBALL" + +printf '==> populating AppDir...\n' +cp -a "${RELEASE_NAME}" "${APPDIR}/usr/lib/${PKGNAME}" + +# - AppRun is the entrypoint; resolves paths relative to the AppImage mount +cat > "${APPDIR}/AppRun" << 'APPRUN_EOF' +#!/bin/sh +# apprun - entrypoint for code-server AppImage +SELF="$(readlink -f "$0")" +HERE="$(dirname "$SELF")" +export PATH="${HERE}/usr/bin:${PATH}" +exec "${HERE}/usr/lib/code-server/bin/code-server" "$@" +APPRUN_EOF +chmod +x "${APPDIR}/AppRun" + +# - .desktop file is required by the AppImage spec +cat > "${APPDIR}/${PKGNAME}.desktop" << DESKTOP_EOF +[Desktop Entry] +Name=code-server +Comment=VS Code in the browser +Exec=code-server +Icon=code-server +Type=Application +Categories=Development;IDE; +DESKTOP_EOF + +# - fetch icon; fall back to main branch if the versioned tag path differs +printf '==> downloading icon...\n' +if ! curl -fsSL -o "${APPDIR}/usr/share/icons/hicolor/512x512/apps/${PKGNAME}.png" "$ICON_URL"; then + printf ' versioned icon not found, trying main branch...\n' + curl -fL --progress-bar \ + -o "${APPDIR}/usr/share/icons/hicolor/512x512/apps/${PKGNAME}.png" \ + "$ICON_FALLBACK_URL" +fi + +# - appimage spec also requires the icon at the AppDir root +cp "${APPDIR}/usr/share/icons/hicolor/512x512/apps/${PKGNAME}.png" \ + "${APPDIR}/${PKGNAME}.png" + +# - download appimagetool (itself an AppImage; APPIMAGE_EXTRACT_AND_RUN avoids FUSE dependency) +printf '==> downloading appimagetool (%s)...\n' "$UNAME_ARCH" +curl -fL --progress-bar -o "${WORKDIR}/appimagetool" "$APPIMAGETOOL_URL" +chmod +x "${WORKDIR}/appimagetool" + +# - build the AppImage +# - APPIMAGE_EXTRACT_AND_RUN=1 lets appimagetool run without FUSE (required in Docker) +# - ARCH must be set so appimagetool embeds the correct ELF architecture tag +OUTPUT="${OUTPUT_DIR}/${PKGNAME}-${PKGVER}-${UNAME_ARCH}.AppImage" +printf '==> building AppImage...\n' +ARCH="$UNAME_ARCH" APPIMAGE_EXTRACT_AND_RUN=1 \ + "${WORKDIR}/appimagetool" --comp gzip \ + "${APPDIR}" "${OUTPUT}" + +chmod +x "${OUTPUT}" + +printf '\n==> done!\n' +printf ' output: %s\n\n' "$OUTPUT" +printf 'usage:\n' +printf ' regular system: ./%s-%s-%s.AppImage\n' "$PKGNAME" "$PKGVER" "$UNAME_ARCH" +printf ' docker/no-fuse: APPIMAGE_EXTRACT_AND_RUN=1 ./%s-%s-%s.AppImage\n' "$PKGNAME" "$PKGVER" "$UNAME_ARCH" diff --git a/code-server-wrapper.sh b/code-server-wrapper.sh new file mode 100755 index 0000000..612d2ab --- /dev/null +++ b/code-server-wrapper.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +APPIMAGE_DIR="/opt/code-server-appimage" + +# - find the AppImage; fail clearly if missing or ambiguous +_match="$(find "$APPIMAGE_DIR" -maxdepth 1 -name 'code-server-*.AppImage' 2>/dev/null)" +_count="$(printf '%s\n' "$_match" | grep -c 'AppImage' 2>/dev/null || echo 0)" + +if [ "$_count" -eq 0 ]; then + printf 'error: no code-server AppImage found in %s\n' "$APPIMAGE_DIR" >&2 + exit 1 +fi + +if [ "$_count" -gt 1 ]; then + printf 'error: multiple AppImages found in %s - keep only one:\n' "$APPIMAGE_DIR" >&2 + printf '%s\n' "$_match" >&2 + exit 1 +fi + +APPIMAGE="$_match" +export APPIMAGE_EXTRACT_AND_RUN=1 +exec "$APPIMAGE" "$@" |
