Skip to content

Instantly share code, notes, and snippets.

@shalomb
Last active May 19, 2026 14:16
Show Gist options
  • Select an option

  • Save shalomb/ac562175ee2dbd138899d33d7a8d33df to your computer and use it in GitHub Desktop.

Select an option

Save shalomb/ac562175ee2dbd138899d33d7a8d33df to your computer and use it in GitHub Desktop.
Non-sudo dev tools installer for Rocky Linux/RHEL: uv, Homebrew, gh (webi bootstrap), Copilot CLI + symlink, VS Code, Python 3.12
Non-sudo dev tools installer for Rocky Linux/RHEL: uv, gh (webi), Copilot CLI + symlink, VS Code, Python 3.12
#!/bin/bash
# ==============================================================================
# Non-Sudo Dev Tools Installer for Rocky Linux / RHEL
# Installs: uv, GitHub CLI (gh), Copilot CLI, VS Code, Python 3.12
# ==============================================================================
set -e
# Configuration
LOCAL_DIR="$HOME/.local"
BIN_DIR="$HOME/.local/bin"
VSCODE_DIR="$LOCAL_DIR/vscode"
echo "πŸš€ Starting non-sudo dev environment setup..."
# 1. Create directory structure
mkdir -p "$LOCAL_DIR"
mkdir -p "$BIN_DIR"
# 2. Architecture Detection
ARCH=$(uname -m)
echo "πŸ” Detected architecture: $ARCH"
# 3. Install uv (Python toolchain)
echo "🐍 Installing uv..."
curl -LsSf https://astral.sh/uv/install.sh | INSTALLER_NO_MODIFY_PATH=1 sh
# Ensure uv is in the path for the rest of the script
export PATH="$BIN_DIR:$PATH"
# 4. Install GitHub CLI (gh) via webi
echo "πŸ™ Installing GitHub CLI (gh) via webi..."
curl -sS https://webi.sh/gh | sh
# webi installs into ~/.local/bin β€” ensure it's on PATH for the rest of this script
export PATH="$BIN_DIR:$PATH"
# 5. Authenticate with GitHub
if ! gh auth status &>/dev/null; then
echo "πŸ” No active GitHub login detected, running 'gh auth login'..."
gh auth login
else
echo "βœ… Already authenticated with GitHub."
fi
# 6. Install Copilot CLI + symlink
# As of gh v2.x, 'gh copilot' is a built-in β€” no extension install needed.
# Trigger gh to download the built-in copilot binary.
echo "πŸ€– Downloading GitHub Copilot CLI (built-in)..."
gh copilot --version || echo "⚠️ Could not download Copilot binary. Run 'gh auth login' and retry."
# 6a. Symlink the built-in copilot binary directly into ~/.local/bin/copilot
# Symlinking directly avoids the 'gh copilot ...' wrapper which doesn't pass
# args (especially post-'--') transparently to the underlying binary.
COPILOT_BIN="$HOME/.local/share/gh/copilot/copilot"
COPILOT_LINK="$BIN_DIR/copilot"
echo "πŸ”— Symlinking $COPILOT_BIN -> $COPILOT_LINK..."
if [ -f "$COPILOT_BIN" ]; then
ln -sf "$COPILOT_BIN" "$COPILOT_LINK"
echo "βœ… copilot symlink created: $(ls -la "$COPILOT_LINK")"
else
echo "⚠️ Copilot binary not found at $COPILOT_BIN β€” skipping symlink."
fi
# 7. Install VS Code (Portable tar.gz)
echo "πŸ’» Installing VS Code..."
if [ "$ARCH" = "x86_64" ]; then
VSCODE_URL="https://go.microsoft.com/fwlink/?LinkID=620884"
elif [ "$ARCH" = "aarch64" ]; then
VSCODE_URL="https://go.microsoft.com/fwlink/?LinkID=760865"
else
echo "❌ Unsupported architecture for VS Code: $ARCH"
exit 1
fi
curl -L "$VSCODE_URL" -o vscode.tar.gz
mkdir -p "$VSCODE_DIR"
tar -xzf vscode.tar.gz -C "$VSCODE_DIR" --strip-components=1
ln -sf "$VSCODE_DIR/bin/code" "$BIN_DIR/code"
rm vscode.tar.gz
# 8. Install Python 3.12 via uv
echo "🐍 Installing Python 3.12 via uv..."
uv python install 3.12
# 9. Final Instructions
echo ""
echo "=============================================================================="
echo "πŸŽ‰ Installation Complete!"
echo "=============================================================================="
echo ""
echo "To finalize the setup, add these lines to your ~/.bashrc (or ~/.zshrc):"
echo ""
echo "# Dev Tools Path"
echo "export PATH=\"\$HOME/.local/bin:\$PATH\""
echo ""
echo "Then, run: source ~/.bashrc"
echo ""
echo "Notes:"
echo "1. If Copilot binary was not downloaded, run 'gh auth login' then re-run this script."
echo "2. Use 'uv --help' to learn about Python management."
echo "3. Run 'code' to start VS Code."
echo "=============================================================================="
@shalomb

shalomb commented May 19, 2026

Copy link
Copy Markdown
Author

Feedback from a test run on Rocky Linux (x86_64)

Environment: Rocky Linux / x86_64, non-sudo user

What worked βœ…

  • gh via webi β€” already installed, idempotent (v2.92.0)
  • uv install β€” clean and fast (v0.11.15)
  • Homebrew clone to ~/.linuxbrew β€” worked; subsequent runs correctly skip the clone
  • VS Code portable tar.gz install β€” downloaded and extracted fine (~202MB)
  • Python 3.12 via uv python install 3.12 β€” installed cpython-3.12.13 without issue

Notes ⚠️

  • Step 6 (Copilot extension) is outdated for gh v2.92.0+: gh extension install github/gh-copilot fails with "copilot" matches the name of a built-in command or alias. As of gh v2.x, gh copilot is a built-in β€” no extension install needed.
  • Copilot binary location changed: The built-in gh copilot downloads the binary to ~/.local/share/gh/copilot/copilot (not ~/.local/share/gh/extensions/gh-copilot/gh-copilot). The symlink path in step 6a should be updated to:
    COPILOT_BIN="$HOME/.local/share/gh/copilot/copilot"

Suggested fix for steps 5–6a

Replace the Copilot extension install + symlink block with:

# Trigger gh to download the built-in copilot binary
gh copilot --version

# Symlink to ~/.local/bin
COPILOT_BIN="$HOME/.local/share/gh/copilot/copilot"
COPILOT_LINK="$BIN_DIR/copilot"
if [ -f "$COPILOT_BIN" ]; then
    ln -sf "$COPILOT_BIN" "$COPILOT_LINK"
    echo "βœ… copilot symlink created: $(ls -la "$COPILOT_LINK")"
else
    echo "⚠️  Copilot binary not found at $COPILOT_BIN"
fi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment