Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions scripts/install-openshell.sh
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,26 @@ tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

CHECKSUM_FILE="openshell-checksums-sha256.txt"
if command -v gh >/dev/null 2>&1; then
GH_TOKEN="${GITHUB_TOKEN:-}" gh release download --repo NVIDIA/OpenShell \
--pattern "$ASSET" --dir "$tmpdir"
GH_TOKEN="${GITHUB_TOKEN:-}" gh release download --repo NVIDIA/OpenShell \
--pattern "$CHECKSUM_FILE" --dir "$tmpdir"
else
download_with_curl() {
curl -fsSL "https://github.com/NVIDIA/OpenShell/releases/latest/download/$ASSET" \
-o "$tmpdir/$ASSET"
curl -fsSL "https://github.com/NVIDIA/OpenShell/releases/latest/download/$CHECKSUM_FILE" \
-o "$tmpdir/$CHECKSUM_FILE"
}

if command -v gh >/dev/null 2>&1; then
if GH_PROMPT_DISABLED=1 GH_TOKEN="${GH_TOKEN:-${GITHUB_TOKEN:-}}" gh release download --repo NVIDIA/OpenShell \
--pattern "$ASSET" --dir "$tmpdir" 2>/dev/null \
&& GH_PROMPT_DISABLED=1 GH_TOKEN="${GH_TOKEN:-${GITHUB_TOKEN:-}}" gh release download --repo NVIDIA/OpenShell \
--pattern "$CHECKSUM_FILE" --dir "$tmpdir" 2>/dev/null; then
: # gh succeeded
else
warn "gh CLI download failed (auth may not be configured) — falling back to curl"
rm -f "$tmpdir/$ASSET" "$tmpdir/$CHECKSUM_FILE"
download_with_curl
fi
else
download_with_curl
fi

info "Verifying SHA-256 checksum..."
Expand Down
62 changes: 62 additions & 0 deletions test/runner.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,68 @@ describe("regression guards", () => {
expect(src).toContain("openshell-checksums-sha256.txt");
expect(src).toContain("shasum -a 256 -c");
});

it("install-openshell.sh falls back to curl when gh fails (#1318)", () => {
const src = fs.readFileSync(
path.join(import.meta.dirname, "..", "scripts", "install-openshell.sh"),
"utf-8",
);
expect(src).toContain("download_with_curl");
const ghBlock = src.slice(src.indexOf("command -v gh"));
expect(ghBlock).toContain("2>/dev/null");
expect(ghBlock).toContain("falling back to curl");
expect(ghBlock).toContain("download_with_curl");
});

it("install-openshell.sh gh-absent path uses curl directly", () => {
const src = fs.readFileSync(
path.join(import.meta.dirname, "..", "scripts", "install-openshell.sh"),
"utf-8",
);
expect(src).toContain("download_with_curl");
const ghCheck = src.indexOf("command -v gh");
const elseBlock = src.indexOf("\nelse\n", ghCheck);
const finalFi = src.indexOf("\nfi\n", elseBlock);
expect(ghCheck).toBeGreaterThan(-1);
expect(elseBlock).toBeGreaterThan(ghCheck);
expect(finalFi).toBeGreaterThan(elseBlock);
const fallthrough = src.slice(elseBlock, finalFi);
expect(fallthrough).toContain("download_with_curl");
expect(fallthrough).not.toContain("gh release");
});

it("install-openshell.sh gh-present-but-fails path falls back to curl", () => {
const scriptPath = path.join(import.meta.dirname, "..", "scripts", "install-openshell.sh");
const tmpBin = fs.mkdtempSync(path.join(os.tmpdir(), "gh-stub-"));
const ghStub = path.join(tmpBin, "gh");
fs.writeFileSync(ghStub, "#!/bin/sh\nexit 4\n");
fs.chmodSync(ghStub, 0o755);

const stub = `
#!/usr/bin/env bash
openshell() { echo "openshell 0.0.1"; }
export -f openshell
export PATH="${tmpBin}:/usr/bin:/bin"
curl() { echo "CURL_FALLBACK $*"; return 0; }
export -f curl
shasum() { echo "checksum OK"; return 0; }
export -f shasum
tar() { return 0; }; export -f tar
install() { return 0; }; export -f install
source "${scriptPath}"
`;
try {
const result = spawnSync("bash", ["-c", stub], {
encoding: "utf-8",
timeout: 5000,
});
const out = (result.stdout || "") + (result.stderr || "");
expect(out).toContain("falling back to curl");
expect(out).toContain("CURL_FALLBACK");
} finally {
fs.rmSync(tmpBin, { recursive: true, force: true });
}
});
});

describe("curl-pipe-to-shell guards (#574, #583)", () => {
Expand Down
Loading