Newer
Older
abysiuscodium / build / build.sh
#!/bin/bash
set -euo pipefail

# AbysiusCodium Build Script
# Builds custom VSCodium binaries with bundled Abysius AI extension

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
BUILD_DIR="${PROJECT_ROOT}/build"
WORK_DIR="${PROJECT_ROOT}/work"
PATCHES_DIR="${PROJECT_ROOT}/patches"
RELEASES_DIR="${PROJECT_ROOT}/releases"

# Versions
MS_VSCODE_TAG="${MS_VSCODE_TAG:-1.121.0}"
NODE_VERSION="${NODE_VERSION:-20.18.0}"

# Branding
APP_NAME="AbysiusCodium"
APP_NAME_SHORT="abysius-codium"

usage() {
    echo "Usage: $0 [options]"
    echo ""
    echo "Options:"
    echo "  -p, --platform <platform>   Target platform (linux|darwin|win32) [default: current]"
    echo "  -a, --arch <arch>           Target architecture (x64|arm64|armhf) [default: x64]"
    echo "  -t, --tag <tag>             VS Code upstream tag [default: ${MS_VSCODE_TAG}]"
    echo "  -c, --clean                 Clean work directory before build"
    echo "  -s, --skip-ext              Skip building the Abysius AI extension"
    echo "  -h, --help                  Show this help"
    exit 0
}

PLATFORM=""
ARCH="x64"
CLEAN=0
SKIP_EXT=0

while [[ $# -gt 0 ]]; do
    case $1 in
        -p|--platform) PLATFORM="$2"; shift 2 ;;
        -a|--arch) ARCH="$2"; shift 2 ;;
        -t|--tag) MS_VSCODE_TAG="$2"; shift 2 ;;
        -c|--clean) CLEAN=1; shift ;;
        -s|--skip-ext) SKIP_EXT=1; shift ;;
        -h|--help) usage ;;
        *) echo "Unknown option: $1"; usage ;;
    esac
done

# Auto-detect platform if not specified
if [[ -z "$PLATFORM" ]]; then
    case "$(uname -s)" in
        Linux*) PLATFORM="linux" ;;
        Darwin*) PLATFORM="darwin" ;;
        MINGW*|MSYS*|CYGWIN*) PLATFORM="win32" ;;
        *) echo "Unsupported platform: $(uname -s)"; exit 1 ;;
    esac
fi

# Ensure work directory exists
mkdir -p "${WORK_DIR}"
mkdir -p "${RELEASES_DIR}"

if [[ $CLEAN -eq 1 ]]; then
    echo "[BUILD] Cleaning work directory..."
    rm -rf "${WORK_DIR:?}"/*
fi

# Step 1: Clone / update vscode repo
echo "[BUILD] Setting up Microsoft vscode source (tag: ${MS_VSCODE_TAG})..."
if [[ ! -d "${WORK_DIR}/vscode" ]]; then
    git clone --depth 1 --branch "${MS_VSCODE_TAG}" https://github.com/microsoft/vscode.git "${WORK_DIR}/vscode"
else
    cd "${WORK_DIR}/vscode"
    git fetch --depth 1 origin "${MS_VSCODE_TAG}"
    git checkout "${MS_VSCODE_TAG}" || {
        echo "[BUILD] Failed to checkout tag ${MS_VSCODE_TAG}, re-cloning..."
        cd "${PROJECT_ROOT}"
        rm -rf "${WORK_DIR}/vscode"
        git clone --depth 1 --branch "${MS_VSCODE_TAG}" https://github.com/microsoft/vscode.git "${WORK_DIR}/vscode"
    }
fi

cd "${WORK_DIR}/vscode"

# Step 2: Apply VSCodium patches
echo "[BUILD] Applying VSCodium de-branding patches..."
if [[ -d "${PATCHES_DIR}" ]]; then
    for patch_file in "${PATCHES_DIR}"/*.patch; do
        if [[ -f "$patch_file" ]]; then
            echo "[BUILD] Applying patch: $(basename "$patch_file")"
            git apply "$patch_file" || {
                echo "[BUILD] WARNING: Failed to apply $(basename "$patch_file"), may already be applied"
            }
        fi
    done
fi

# Step 3: Apply custom Abysius branding patches
echo "[BUILD] Applying Abysius branding..."
cp "${PROJECT_ROOT}/product.json" "${WORK_DIR}/vscode/product.json"

# Step 4: Copy Abysius AI extension into built-in extensions
if [[ $SKIP_EXT -eq 0 ]]; then
    echo "[BUILD] Building Abysius AI extension..."
    cd "${PROJECT_ROOT}/extensions/abysius-ai"
    
    if [[ ! -d "node_modules" ]]; then
		if [[ -f package-lock.json || -f npm-shrinkwrap.json ]]; then
			npm ci
		else
			npm install
		fi
	fi
    
    npm run compile
    
    # Package extension into VSIX
    npx vsce package --no-dependencies -o "${WORK_DIR}/abysius-ai.vsix"
    
    # Install as built-in extension
    mkdir -p "${WORK_DIR}/vscode/extensions/abysius-ai"
    cp -r "${PROJECT_ROOT}/extensions/abysius-ai"/* "${WORK_DIR}/vscode/extensions/abysius-ai/"
    
    echo "[BUILD] Abysius AI extension ready"
fi

# Step 5: License compliance check
if [[ $SKIP_EXT -eq 0 ]]; then
    echo "[BUILD] Running license compliance check..."
    cd "${PROJECT_ROOT}"
    node "${BUILD_DIR}/check-licenses.js" || {
        echo "[BUILD] ERROR: License compliance check failed. Review violations above."
        exit 1
    }
fi

# Step 6: Install dependencies and build
cd "${WORK_DIR}/vscode"

echo "[BUILD] Installing Node dependencies..."
export npm_config_arch="${ARCH}"
export npm_config_target_arch="${ARCH}"

if [[ "$PLATFORM" == "linux" && "$ARCH" == "armhf" ]]; then
    export npm_config_arch="arm"
    export npm_config_target_arch="arm"
fi

# Use system node if matching, otherwise use nvm/fnm
if ! command -v node &>/dev/null || [[ "$(node -v)" != "v${NODE_VERSION}"* ]]; then
    echo "[BUILD] Node ${NODE_VERSION} required. Setting up..."
    if command -v fnm &>/dev/null; then
        eval "$(fnm env)"
        fnm use "${NODE_VERSION}" 2>/dev/null || fnm install "${NODE_VERSION}"
        fnm use "${NODE_VERSION}"
    elif [[ -d "${HOME}/.nvm" ]]; then
        export NVM_DIR="${HOME}/.nvm"
        [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
        nvm use "${NODE_VERSION}" 2>/dev/null || nvm install "${NODE_VERSION}"
    else
        echo "[BUILD] WARNING: Node version mismatch. Install Node ${NODE_VERSION} via nvm/fnm."
    fi
fi

echo "[BUILD] Installing dependencies (this may take a while)..."

echo "[BUILD] Installing dependencies with npm install..."
rm -rf node_modules
npm install

# Step 7: Compile
echo "[BUILD] Compiling VS Code..."
npm run compile

# Step 8: Build release packages
echo "[BUILD] Packaging for ${PLATFORM}-${ARCH}..."

if [[ "$PLATFORM" == "linux" ]]; then
    # Build .tar.gz
    npm run gulp -- "vscode-linux-${ARCH}"
    
    # Build .deb if tools available
    if command -v dpkg-deb &>/dev/null; then
        npm run gulp -- "vscode-linux-${ARCH}-deb"
    fi
    
    # Build .rpm if tools available
    if command -v rpmbuild &>/dev/null; then
        npm run gulp -- "vscode-linux-${ARCH}-rpm"
    fi
    
    # Copy artifacts
    cp "${WORK_DIR}/vscode/.build/linux/${ARCH}/"*.tar.gz "${RELEASES_DIR}/" 2>/dev/null || true
    cp "${WORK_DIR}/vscode/.build/linux/deb/${ARCH}/debian/"*.deb "${RELEASES_DIR}/" 2>/dev/null || true
    cp "${WORK_DIR}/vscode/.build/linux/rpm/${ARCH}/"*.rpm "${RELEASES_DIR}/" 2>/dev/null || true

elif [[ "$PLATFORM" == "darwin" ]]; then
    npm run gulp -- "vscode-darwin-${ARCH}"
    cp -r "${WORK_DIR}/vscode/.build/darwin/${ARCH}/"*.app "${RELEASES_DIR}/" 2>/dev/null || true
    cp "${WORK_DIR}/vscode/.build/darwin/${ARCH}/"*.zip "${RELEASES_DIR}/" 2>/dev/null || true
    cp "${WORK_DIR}/vscode/.build/darwin/${ARCH}/"*.dmg "${RELEASES_DIR}/" 2>/dev/null || true

elif [[ "$PLATFORM" == "win32" ]]; then
    npm run gulp -- "vscode-win32-${ARCH}"
    cp -r "${WORK_DIR}/vscode/.build/win32/${ARCH}/" "${RELEASES_DIR}/${APP_NAME_SHORT}-win32-${ARCH}" 2>/dev/null || true
    cp "${WORK_DIR}/vscode/.build/win32/${ARCH}/system-setup/"*.exe "${RELEASES_DIR}/" 2>/dev/null || true
    cp "${WORK_DIR}/vscode/.build/win32/${ARCH}/user-setup/"*.exe "${RELEASES_DIR}/" 2>/dev/null || true
fi

echo ""
echo "========================================"
echo "  AbysiusCodium Build Complete!"
echo "========================================"
echo ""
echo "Release artifacts available in:"
echo "  ${RELEASES_DIR}/"
echo ""
ls -la "${RELEASES_DIR}/" 2>/dev/null || echo "  (no artifacts found - check build logs)"
echo ""