Skip to content

fix(install): add auth-free installer for CI/Docker#288

Merged
amondnet merged 2 commits into
mainfrom
amondnet/install
Jun 30, 2026
Merged

fix(install): add auth-free installer for CI/Docker#288
amondnet merged 2 commits into
mainfrom
amondnet/install

Conversation

@amondnet

@amondnet amondnet commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

요약

CI/Docker 환경에서 gh extension install pleaseai/gh-please 실행 시
api.github.com 익명 API 요청 제한(60회/시간)으로 HTTP 403이 발생해 인증 오류처럼 보이는 문제를 수정합니다.

근본 원인

실제 인증 문제가 아님. 공유 IP runner 환경에서 GitHub REST API의 익명 요청 제한에 도달하면 gh CLI가 이를 인증 오류로 표시함. 격리된 HOME에서 재현 검증을 통해 토큰 없이도 설치 자체는 성공함을 확인.

변경 사항

  • scripts/install.sh 신규 추가: api.github.com를 우회하는 인증 불필요 설치 스크립트
    • releases/latest 웹 리다이렉트(CDN, 레이트 리밋 없음)로 최신 태그 확인
    • 릴리즈 CDN에서 사전 컴파일 바이너리 및 체크섬 파일 다운로드
    • SHA-256 검증 후 gh 익스텐션 디렉토리에 manifest.yml 포함 설치
    • darwin/linux × amd64/arm64 자동 감지
    • --version <태그> 또는 GH_PLEASE_VERSION 환경변수로 버전 고정 지원
  • 문서 업데이트: README.md, README.ko.md, docs/content/en 및 ko 시작 가이드에 "CI/Docker (인증 불필요)" 섹션 및 curl one-liner 예시 추가

검증

# 토큰 없이 curl one-liner로 설치 → 체크섬 OK → gh please --version → 0.32.0 확인
curl -fsSL https://raw.githubusercontent.com/pleaseai/gh-please/main/scripts/install.sh | bash

테스트 계획

  • 격리된 HOME에서 토큰 없이 설치 성공 확인
  • SHA-256 체크섬 검증 통과 확인
  • gh please --version 출력 확인 (0.32.0)
  • darwin arm64 환경에서 end-to-end 검증

Summary by cubic

Adds an auth-free installer for pleaseai/gh-please to make CI/Docker installs reliable by bypassing GitHub API rate limits. Docs now include a curl one-liner, reproducible pinning examples, and guidance for tokened installs.

  • Bug Fixes

    • Avoids unauthenticated api.github.com calls that hit the 60 req/hour IP limit and cause HTTP 403 on shared runners.
  • New Features

    • New scripts/install.sh: resolves releases/latest via web redirect and downloads from the release CDN (no token); verifies SHA-256; installs to the gh extensions directory with manifest.yml; auto-detects darwin/linux and amd64/arm64; supports --version and GH_PLEASE_VERSION for pinning.
    • Hardening: fail-closed checksum verification; atomic staging then swap to preserve existing installs; TTY-aware color output; strict --version parsing; manifest records the final install path. Docs show pinning both the installer script and the binary to the same tag for reproducible builds and note setting GH_TOKEN (e.g. ${{ github.token }}) for gh extension install.

Written for commit 88ec06e. Summary will update on new commits.

Summary by CodeRabbit

  • New Features
    • Added an auth-free standalone installer for the GitHub CLI extension, supporting latest or pinned versions and automatic platform selection.
    • Added SHA-256 checksum verification with fail-closed behavior and safer, atomic installation of the extension files.
  • Documentation
    • Expanded English and Korean “Installation” guides with CI/Docker notes about unauthenticated gh extension install failures due to API rate limiting (HTTP 403).
    • Included guidance to use GH_TOKEN where available to prevent rate limits.

CI/Docker 환경에서 `gh extension install pleaseai/gh-please` 실행 시
api.github.com 익명 API 요청 제한(60회/시간)으로 HTTP 403이 발생해
인증 오류처럼 보이는 문제가 있었음.

실제 원인은 인증 문제가 아니라 공유 IP 환경의 레이트 리밋. 격리된 HOME에서
재현하고 토큰 없이 설치가 성공함을 확인함.

변경 내용:
- scripts/install.sh 추가: api.github.com를 우회하는 인증 불필요 설치 스크립트
  - releases/latest 웹 리다이렉트로 최신 태그 확인 (CDN, 레이트 리밋 없음)
  - 릴리즈 CDN에서 사전 컴파일 바이너리 및 체크섬 파일 다운로드
  - SHA-256 검증 후 gh 익스텐션 디렉토리에 manifest.yml 포함 설치
  - darwin/linux x amd64/arm64 자동 감지
  - --version <태그> 또는 GH_PLEASE_VERSION 환경변수로 버전 고정 지원
  - curl one-liner 엔드투엔드 검증 완료 (0.32.0)
- README.md, README.ko.md, docs/content/en 및 ko 시작 가이드에
  CI/Docker(인증 불필요) 섹션 및 curl one-liner 예시 추가
@vercel

vercel Bot commented Jun 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
gh-please Ready Ready Preview, Comment Jun 30, 2026 11:41am

Request Review

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds scripts/install.sh, a standalone binary installer for the gh-please extension that works without GitHub authentication. Updates README.md, README.ko.md, and EN/KO getting-started docs to document CI/Docker rate-limit issues with gh extension install and redirect users to the new installer.

Changes

Standalone installer and CI docs

Layer / File(s) Summary
Installer helpers and verification
scripts/install.sh
Defines usage, strict shell behavior, platform detection, latest-tag resolution, checksum computation, and checksum validation helpers.
Installer control flow
scripts/install.sh
Parses arguments, downloads release assets, verifies them, stages the extension payload, writes the manifest, swaps into place, and runs the script entry point.
Installation docs
README.md, README.ko.md, docs/content/en/1.guide/1.getting-started.md, docs/content/ko/1.guide/1.getting-started.md
Adds CI/Docker installation guidance, standalone installer commands, version pinning examples, and the GH_TOKEN note for gh extension install.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 No token? No trouble, the bunny declares,
A curl-and-bash script now slides down the stairs,
Detects your platform, grabs the right bin,
Checks the checksum and installs with a grin.
CI pipelines rejoice — no 403 despair! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 54.55% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding an auth-free installer for CI/Docker environments.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch amondnet/install

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jun 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a standalone, auth-free installer script (scripts/install.sh) for the gh-please GitHub CLI extension to bypass GitHub API rate limits in CI and Docker environments, along with corresponding documentation updates in English and Korean. The review feedback highlights two key improvements for the installer script: first, to prevent security bypasses, the script should fail if no checksum entry is found for the asset instead of skipping verification; second, it should explicitly validate the argument count before shifting parameters for the --version option to avoid shell errors.

Comment thread scripts/install.sh Outdated
Comment thread scripts/install.sh
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/content/en/1.guide/1.getting-started.md`:
- Around line 37-38: The reproducible-build example still pulls install.sh from
main, so update the getting-started snippet to use an immutable installer source
instead of the moving branch. Adjust the curl command in the pinned-version
example so it fetches the script from the same tagged release or commit as the
github-v0.32.0 binary, keeping the example consistent and reproducible.

In `@docs/content/ko/1.guide/1.getting-started.md`:
- Around line 37-38: The reproducible-build example only pins the binary version
and still fetches install.sh from main, so update the getting-started example to
pin the installer source as well. In the docs snippet, adjust the curl
invocation used for the fixed-version install so it references a specific
release tag or commit for the installer, matching the versioned binary
reference, and keep the guidance consistent with the install script example.

In `@scripts/install.sh`:
- Around line 96-99: The checksum verification flow in install.sh currently
treats a missing entry from checksums.txt as success, which can silently bypass
integrity checks. Update the checksum lookup/verification path around the
expected-value handling so that when the asset name is not found for a
gh-please_* artifact, the script fails closed instead of returning 0; keep the
existing lookup logic but change the missing-entry branch in the checksum
verification function to abort with an error message.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5076d854-1a2a-40a4-a4cf-693b8cd6dfda

📥 Commits

Reviewing files that changed from the base of the PR and between 289a7b9 and 30275f0.

📒 Files selected for processing (5)
  • README.ko.md
  • README.md
  • docs/content/en/1.guide/1.getting-started.md
  • docs/content/ko/1.guide/1.getting-started.md
  • scripts/install.sh

Comment thread docs/content/en/1.guide/1.getting-started.md Outdated
Comment thread docs/content/ko/1.guide/1.getting-started.md Outdated
Comment thread scripts/install.sh Outdated
@greptile-apps

greptile-apps Bot commented Jun 30, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds scripts/install.sh, a standalone auth-free installer that resolves the latest release tag via GitHub's releases/latest redirect and downloads precompiled binaries from the release CDN — bypassing api.github.com and its 60 req/hour unauthenticated rate limit that causes HTTP 403 errors on shared CI runners. Documentation across README, README.ko.md, and both language getting-started guides is updated with the curl | bash one-liner and a pinned-version variant.

  • New scripts/install.sh: resolves tag via web redirect (no API call), downloads binary + checksums.txt from the CDN, verifies SHA-256, stages the extension atomically before swapping into place, and auto-detects darwin/linux × amd64/arm64; --version / GH_PLEASE_VERSION support pinning.
  • Previous review findings addressed: the checksum function now fails closed on a missing entry, installation uses a staging directory to avoid leaving a broken state, and ANSI color codes are gated on [[ -t 2 ]] so CI logs stay clean.
  • Docs: all four documentation files gain a CI/Docker installation section with the one-liner, a pinned-version example, and guidance to set GH_TOKEN when preferring gh extension install.

Confidence Score: 5/5

Safe to merge; the new installer script is well-structured and all three issues from the previous review round are addressed.

The new installer script handles checksum verification with fail-closed behavior, uses a staging directory for atomic installation, and guards ANSI codes behind a terminal check. The only remaining gap is missing curl timeouts, which is a hardening improvement rather than a defect affecting current behavior.

scripts/install.sh — adding curl timeouts would improve robustness in exactly the CI/Docker environments this script targets.

Important Files Changed

Filename Overview
scripts/install.sh New auth-free installer script; previous review findings (silent checksum skip, non-atomic install, unconditional ANSI codes) are all addressed; one remaining concern with missing curl timeouts
README.md Adds CI/Docker installation section with curl one-liner and GH_TOKEN guidance; clear and accurate
README.ko.md Korean translation of CI/Docker installation section; mirrors README.md changes correctly
docs/content/en/1.guide/1.getting-started.md Adds CI/Docker install section with pinned-version example and callout for GH_TOKEN alternative; content is accurate
docs/content/ko/1.guide/1.getting-started.md Korean translation of CI/Docker install section; mirrors the English getting-started changes correctly

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User as CI / Docker
    participant Script as install.sh
    participant GH as github.com (web)
    participant CDN as objects.githubusercontent.com (CDN)

    User->>Script: "curl -fsSL .../install.sh | bash"
    alt --version not set
        Script->>GH: GET /releases/latest (no-follow, capture redirect_url)
        GH-->>Script: 302 to /releases/tag/github-vX.Y.Z
        Script->>Script: extract tag from redirect URL
    end
    Script->>CDN: "GET /releases/download/{tag}/gh-please_{tag}_{platform}"
    CDN-->>Script: binary (no auth, no rate limit)
    Script->>CDN: "GET /releases/download/{tag}/checksums.txt"
    CDN-->>Script: checksums.txt
    Script->>Script: SHA-256 verify (fail closed if entry missing)
    Script->>Script: stage to .gh-please.tmp.$$
    Script->>Script: rm -rf existing extension dir
    Script->>Script: mv staging to final dir (atomic rename)
    Script-->>User: Installed + manifest.yml written
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant User as CI / Docker
    participant Script as install.sh
    participant GH as github.com (web)
    participant CDN as objects.githubusercontent.com (CDN)

    User->>Script: "curl -fsSL .../install.sh | bash"
    alt --version not set
        Script->>GH: GET /releases/latest (no-follow, capture redirect_url)
        GH-->>Script: 302 to /releases/tag/github-vX.Y.Z
        Script->>Script: extract tag from redirect URL
    end
    Script->>CDN: "GET /releases/download/{tag}/gh-please_{tag}_{platform}"
    CDN-->>Script: binary (no auth, no rate limit)
    Script->>CDN: "GET /releases/download/{tag}/checksums.txt"
    CDN-->>Script: checksums.txt
    Script->>Script: SHA-256 verify (fail closed if entry missing)
    Script->>Script: stage to .gh-please.tmp.$$
    Script->>Script: rm -rf existing extension dir
    Script->>Script: mv staging to final dir (atomic rename)
    Script-->>User: Installed + manifest.yml written
Loading

Reviews (2): Last reviewed commit: "chore(install): apply AI code review sug..." | Re-trigger Greptile

Comment thread scripts/install.sh Outdated
Comment thread scripts/install.sh Outdated
Comment thread scripts/install.sh Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 5 files

Confidence score: 3/5

  • In scripts/install.sh, allowing install to proceed when a checksum entry is missing means an unverified binary can be installed, which is a concrete supply-chain risk for users—fail closed on missing checksum metadata before merging.
  • In docs/content/en/1.guide/1.getting-started.md, using an installer URL on main makes the reproducible-build example drift over time even with --version fixed, which can cause inconsistent results for readers—pin the URL to the same tag/commit to keep behavior deterministic.
Architecture diagram
sequenceDiagram
    participant User as CI/Docker Runner
    participant Script as install.sh
    participant GHWeb as GitHub Release Web
    participant GHCDN as GitHub Release CDN
    participant LocalFS as gh Extensions Dir

    Note over User,LocalFS: NEW: Auth-free installer flow (bypasses API rate limits)

    User->>Script: curl -fsSL install.sh | bash
    Script->>Script: detect OS/arch (linux/darwin × amd64/arm64)

    alt No version pinned (latest)
        Script->>GHWeb: GET /releases/latest (web redirect, no API)
        GHWeb-->>Script: HTTP 302 → redirect_url (tag extracted)
    else Version pinned (--version or GH_PLEASE_VERSION)
        Note over Script: tag = user-specified version
    end

    Script->>Script: Construct asset URL: releases/download/{tag}/gh-please_{tag}_{platform}
    Script->>GHCDN: download binary asset (no auth, no rate limit)
    GHCDN-->>Script: binary file

    Script->>GHCDN: download checksums.txt
    GHCDN-->>Script: checksums.txt

    alt Checksum match
        Script->>Script: SHA-256 verify (sha256sum or shasum)
        Note over Script: Checksum verified
    else Checksum mismatch or missing
        Script->>Script: die with error
    end

    Script->>LocalFS: create ~/.local/share/gh/extensions/gh-please/
    Script->>LocalFS: install binary (chmod 0755)
    Script->>LocalFS: write manifest.yml (owner, name, tag, etc.)
    LocalFS-->>Script: installed
    Script-->>User: success message + "Run: gh please --version"

    Note over User,GHCDN: Alternative path (documented but unchanged in PR):
    Note over User,GHCDN: `gh extension install` uses api.github.com (rate-limited).
    Note over User,GHCDN: Remedy: set GH_TOKEN (e.g. ${{ github.token }}) to lift limit.
Loading

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread scripts/install.sh Outdated
Comment thread docs/content/en/1.guide/1.getting-started.md Outdated
- verify_checksum: 체크섬 항목 누락 시 건너뛰지 않고 die (fail-closed, 무결성 보장)
- 색상 코드는 stderr가 TTY일 때만 출력 (CI/Docker 로그 깨짐 방지)
- --version 인자 검증을 shift 전에 수행 (쉘 내부 에러 메시지 방지)
- 확장 설치를 staging 디렉터리에 준비 후 원자적 교체 (실패 시 기존 설치 보존)
- manifest path는 최종 경로로 기록 (staging 경로 아님)
- 조건문 [ -> [[ 전환 (SonarCloud)
- docs: 재현 가능 빌드 예시에서 install.sh도 동일 태그로 고정
@sonarqubecloud

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
scripts/install.sh (1)

182-185: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add retry/timeout to curl for CI/Docker resilience.

This script's primary target is CI and Docker builds, where transient network blips on the release CDN are common. The bare curl -fsSL here (and the redirect probe at Line 88) has no connect timeout or retry, so a single hiccup fails the whole install. Adding --connect-timeout, --retry, and --retry-delay makes the download self-healing without changing behavior on the happy path.

♻️ Proposed resilience flags
-  curl -fsSL -o "$binary" "${base}/${asset}" \
+  curl -fsSL --connect-timeout 10 --retry 3 --retry-delay 2 -o "$binary" "${base}/${asset}" \
     || die "Failed to download ${base}/${asset} (does the release have a ${platform} binary?)."
-  curl -fsSL -o "$checksums" "${base}/checksums.txt" \
+  curl -fsSL --connect-timeout 10 --retry 3 --retry-delay 2 -o "$checksums" "${base}/checksums.txt" \
     || die "Failed to download checksums from ${base}/checksums.txt"

Please confirm the target environments ship a curl that supports --retry/--retry-delay (curl ≥ 7.12.3, universally available on modern CI images).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/install.sh` around lines 182 - 185, The install script’s curl calls
are too fragile for CI/Docker because they lack timeout and retry handling.
Update both the redirect probe and the two download calls in the install flow
that fetch into $binary and $checksums to use curl with --connect-timeout,
--retry, and --retry-delay while keeping the existing failure behavior. Make
sure the chosen flags are supported by the target environments’ curl versions
and preserve the current success path semantics.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@scripts/install.sh`:
- Around line 182-185: The install script’s curl calls are too fragile for
CI/Docker because they lack timeout and retry handling. Update both the redirect
probe and the two download calls in the install flow that fetch into $binary and
$checksums to use curl with --connect-timeout, --retry, and --retry-delay while
keeping the existing failure behavior. Make sure the chosen flags are supported
by the target environments’ curl versions and preserve the current success path
semantics.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 59185e6d-cdde-40da-88c5-110f17ea3714

📥 Commits

Reviewing files that changed from the base of the PR and between 30275f0 and 88ec06e.

📒 Files selected for processing (3)
  • docs/content/en/1.guide/1.getting-started.md
  • docs/content/ko/1.guide/1.getting-started.md
  • scripts/install.sh
✅ Files skipped from review due to trivial changes (1)
  • docs/content/ko/1.guide/1.getting-started.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/content/en/1.guide/1.getting-started.md

@amondnet
amondnet merged commit 68873bc into main Jun 30, 2026
14 checks passed
@amondnet
amondnet deleted the amondnet/install branch June 30, 2026 12:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant