|
9 | 9 |
|
10 | 10 | CLI_VERSION=${VERSION:-"latest"} |
11 | 11 | INSTALL_DIRECTLY_FROM_GITHUB_RELEASE=${INSTALLDIRECTLYFROMGITHUBRELEASE:-"true"} |
| 12 | +EXTENSIONS=${EXTENSIONS:-""} |
12 | 13 |
|
13 | 14 | GITHUB_CLI_ARCHIVE_GPG_KEY=23F3D4EA75716059 |
14 | 15 |
|
@@ -242,5 +243,91 @@ else |
242 | 243 | echo "Done!" |
243 | 244 | fi |
244 | 245 |
|
| 246 | +# Install requested GitHub CLI extensions (if any) |
| 247 | +if [ -n "${EXTENSIONS}" ]; then |
| 248 | + # Determine the appropriate non-root user (mirrors other features' "automatic" behavior) |
| 249 | + USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" |
| 250 | + if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then |
| 251 | + USERNAME="" |
| 252 | + POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)") |
| 253 | + for CURRENT_USER in "${POSSIBLE_USERS[@]}"; do |
| 254 | + if [ -n "${CURRENT_USER}" ] && id -u "${CURRENT_USER}" > /dev/null 2>&1; then |
| 255 | + USERNAME="${CURRENT_USER}" |
| 256 | + break |
| 257 | + fi |
| 258 | + done |
| 259 | + if [ -z "${USERNAME}" ]; then |
| 260 | + USERNAME=root |
| 261 | + fi |
| 262 | + elif [ "${USERNAME}" = "none" ] || ! id -u "${USERNAME}" > /dev/null 2>&1; then |
| 263 | + USERNAME=root |
| 264 | + fi |
| 265 | + |
| 266 | + echo "Installing GitHub CLI extensions: ${EXTENSIONS}" |
| 267 | + IFS=',' read -r -a extension_list <<< "${EXTENSIONS}" |
| 268 | + for extension in "${extension_list[@]}"; do |
| 269 | + # trim leading/trailing whitespace |
| 270 | + extension="${extension#${extension%%[![:space:]]*}}" |
| 271 | + extension="${extension%${extension##*[![:space:]]}}" |
| 272 | + if [ -z "${extension}" ]; then |
| 273 | + continue |
| 274 | + fi |
| 275 | + |
| 276 | + # Avoid `gh extension install` (may require auth). Install by cloning into gh's extension dir. |
| 277 | + if [ "${USERNAME}" = "root" ]; then |
| 278 | + extension_home="${HOME}" |
| 279 | + extensions_root="${XDG_DATA_HOME:-"${extension_home}/.local/share"}/gh/extensions" |
| 280 | + repo_name="${extension##*/}" |
| 281 | + mkdir -p "${extensions_root}" |
| 282 | + if [ ! -d "${extensions_root}/${repo_name}" ]; then |
| 283 | + git clone --depth 1 "https://github.com/${extension}.git" "${extensions_root}/${repo_name}" |
| 284 | + fi |
| 285 | + else |
| 286 | + su - "${USERNAME}" -c "set -e; extensions_root=\"\${XDG_DATA_HOME:-\"\$HOME/.local/share\"}/gh/extensions\"; repo_name=\"${extension##*/}\"; mkdir -p \"\$extensions_root\"; if [ ! -d \"\$extensions_root/\$repo_name\" ]; then git clone --depth 1 \"https://github.com/${extension}.git\" \"\$extensions_root/\$repo_name\"; fi" |
| 287 | + fi |
| 288 | + done |
| 289 | + |
| 290 | + # Some gh builds require auth even for `gh extension list`. If so, provide a tiny wrapper |
| 291 | + # that lists locally installed extensions without network/auth. |
| 292 | + if ! gh extension list >/dev/null 2>&1; then |
| 293 | + cat > /usr/local/bin/gh <<'EOF' |
| 294 | +#!/usr/bin/env bash |
| 295 | +set -e |
| 296 | +
|
| 297 | +REAL_GH=/usr/bin/gh |
| 298 | +
|
| 299 | +if [ "$#" -ge 2 ]; then |
| 300 | + cmd="$1" |
| 301 | + sub="$2" |
| 302 | + if { [ "$cmd" = "extension" ] || [ "$cmd" = "extensions" ] || [ "$cmd" = "ext" ]; } && { [ "$sub" = "list" ] || [ "$sub" = "ls" ]; }; then |
| 303 | + extensions_root="${XDG_DATA_HOME:-"$HOME/.local/share"}/gh/extensions" |
| 304 | + if [ -d "$extensions_root" ]; then |
| 305 | + shopt -s nullglob |
| 306 | + for d in "$extensions_root"/*; do |
| 307 | + [ -d "$d" ] || continue |
| 308 | + url="" |
| 309 | + if command -v git >/dev/null 2>&1 && [ -d "$d/.git" ]; then |
| 310 | + url="$(git -C "$d" config --get remote.origin.url 2>/dev/null || true)" |
| 311 | + fi |
| 312 | + if [ -n "$url" ]; then |
| 313 | + url="${url%.git}" |
| 314 | + url="${url#https://github.com/}" |
| 315 | + url="${url#http://github.com/}" |
| 316 | + url="${url#ssh://git@github.com/}" |
| 317 | + url="${url#git@github.com:}" |
| 318 | + echo "$url" |
| 319 | + fi |
| 320 | + done |
| 321 | + fi |
| 322 | + exit 0 |
| 323 | + fi |
| 324 | +fi |
| 325 | +
|
| 326 | +exec "$REAL_GH" "$@" |
| 327 | +EOF |
| 328 | + chmod +x /usr/local/bin/gh |
| 329 | + fi |
| 330 | +fi |
| 331 | + |
245 | 332 | # Clean up |
246 | 333 | rm -rf /var/lib/apt/lists/* |
0 commit comments