Skip to content

feat(install): add install.sh and install.ps1 one-line installers#549

Open
SantiagoDePolonia wants to merge 2 commits into
mainfrom
feat/install-script
Open

feat(install): add install.sh and install.ps1 one-line installers#549
SantiagoDePolonia wants to merge 2 commits into
mainfrom
feat/install-script

Conversation

@SantiagoDePolonia

@SantiagoDePolonia SantiagoDePolonia commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • docs/install/install.sh — macOS/Linux installer: detects OS/arch, resolves the latest release via the releases/latest redirect (no GitHub API rate limit), downloads the GoReleaser archive, verifies its SHA-256 against checksums.txt, and installs to /usr/local/bin (or ~/.local/bin when not writable). Overridable via GOMODEL_VERSION / GOMODEL_INSTALL_DIR. No sudo, no telemetry.
  • docs/install/install.ps1 — Windows equivalent: installs to %LOCALAPPDATA%\Programs\gomodel and registers it on the user PATH when missing.

User-visible impact

Enables the one-line install flow:

curl -fsSL https://gomodel.enterpilot.io/install.sh | sh
irm https://gomodel.enterpilot.io/install.ps1 | iex

The serving endpoint (a Cloudflare Worker on gomodel.enterpilot.io) relays these files from main, so they go live once this merges and the Worker is deployed.

Testing

  • install.sh verified end-to-end on macOS arm64 against the real v0.1.53 release (download, checksum, install, binary runs).
  • sh -n clean; install.ps1 untested on a real Windows box (worth one manual run before announcing).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added installation scripts for macOS, Linux, and Windows.
    • Automatically selects the appropriate release and CPU architecture.
    • Verifies downloads with SHA-256 checksums before installation.
    • Installs the command-line tool and provides PATH setup guidance.
    • Supports selecting a specific version and customizing the installation directory.
    • Displays post-installation instructions and cleans up temporary files.

Both scripts resolve the latest GitHub release, download the platform
archive, verify its SHA-256 against checksums.txt, and install the
binary (/usr/local/bin or ~/.local/bin on Unix; %LOCALAPPDATA%\Programs
on Windows, with user-PATH registration). Version and install dir are
overridable via GOMODEL_VERSION / GOMODEL_INSTALL_DIR. The scripts send
no telemetry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds macOS/Linux and Windows installer scripts that resolve GoModel releases, select supported architectures, verify archive checksums, install binaries to configurable locations, update PATH guidance, and clean up temporary files.

Changes

Cross-platform installation

Layer / File(s) Summary
Release resolution and platform selection
docs/install/install.sh, docs/install/install.ps1
Installers validate prerequisites or supported architectures, resolve latest or pinned releases, and construct platform-specific archive URLs.
Artifact verification and Unix installation
docs/install/install.sh
The shell installer downloads and verifies the archive, extracts the binary, selects a writable directory, and prints setup guidance.
Windows release verification and installation
docs/install/install.ps1
The PowerShell installer verifies the ZIP, installs gomodel.exe, updates the user PATH, and removes temporary files.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Installer
  participant GitHubReleases
  participant InstallDirectory
  Installer->>GitHubReleases: Resolve release and download archive
  Installer->>Installer: Verify archive checksum
  Installer->>InstallDirectory: Extract and install GoModel binary
  Installer-->>Installer: Print PATH and setup guidance
Loading

Poem

A rabbit hops through scripts so neat,
With checksums guarding every treat.
ZIP or tar, the paths align,
“GoModel!” shines in terminal time.
Cleanup dances, ears held high.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding the shell and PowerShell installers.
✨ 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 feat/install-script

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@greptile-apps

greptile-apps Bot commented Jul 18, 2026

Copy link
Copy Markdown

Confidence Score: 5/5

Safe to merge with low risk.

The change is limited to new installer scripts and verifies downloaded archives before installation.

No files require special attention.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex ran the requested verification for the pull request.
  • T-Rex noted that local artifact references were not uploaded with the verification results.

T-Rex Ran code and verified through T-Rex

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant User
participant Installer as install.sh / install.ps1
participant GitHub as GitHub Releases
participant FS as Local filesystem

User->>Installer: Run one-line installer
Installer->>Installer: Detect OS/architecture and install dir
Installer->>GitHub: Resolve latest tag or use GOMODEL_VERSION
GitHub-->>Installer: Release tag
Installer->>GitHub: Download archive and checksums.txt
GitHub-->>Installer: Archive + checksums
Installer->>Installer: Verify SHA-256 checksum
Installer->>FS: Extract and copy gomodel binary
Installer-->>User: Print PATH guidance and next steps
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
participant Installer as install.sh / install.ps1
participant GitHub as GitHub Releases
participant FS as Local filesystem

User->>Installer: Run one-line installer
Installer->>Installer: Detect OS/architecture and install dir
Installer->>GitHub: Resolve latest tag or use GOMODEL_VERSION
GitHub-->>Installer: Release tag
Installer->>GitHub: Download archive and checksums.txt
GitHub-->>Installer: Archive + checksums
Installer->>Installer: Verify SHA-256 checksum
Installer->>FS: Extract and copy gomodel binary
Installer-->>User: Print PATH guidance and next steps
Loading

Reviews (1): Last reviewed commit: "feat(install): add install.sh and instal..." | Re-trigger Greptile

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai 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.

Actionable comments posted: 6

🤖 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 `@install/install.ps1`:
- Around line 41-43: Update the checksum selection in the PowerShell install
flow around $expected to parse each checksums.txt row into fields and require
the second field to equal $archive exactly, matching the behavior in install.sh;
retain the first-field checksum as the selected value and avoid substring regex
matching.
- Around line 59-62: Update the PATH assignment in the user PATH handling block
to avoid prepending a semicolon when $userPath is unset or empty. Build the new
value conditionally while preserving the existing behavior of appending
$installDir when a user PATH already exists and only setting it when $installDir
is not present.
- Line 62: Update the Write-Host message in the install script to replace the
non-ASCII em dash with a plain ASCII hyphen, keeping the rest of the user PATH
guidance unchanged.
- Around line 18-22: Update the architecture selection around $arch to prefer
$env:PROCESSOR_ARCHITEW6432 when it is set, falling back to
$env:PROCESSOR_ARCHITECTURE otherwise, then retain the existing AMD64, ARM64,
and unsupported-architecture mappings.

In `@install/install.sh`:
- Around line 81-83: Update the non-writable-directory branch guarded by `[ -w
"$install_dir" ]` to disable the temporary-directory cleanup trap before calling
`fail`, preserving the downloaded binary for manual installation. Correct the
suggested `sudo install` command to use the `$install_dir` variable instead of
hardcoding `/usr/local/bin/`.
- Around line 63-67: Update the checksum selection logic around sha256sum and
shasum to explicitly check whether the fallback shasum utility exists before
invoking it. If neither checksum tool is available, terminate with a clear error
message instead of computing an empty hash or reporting a misleading checksum
mismatch.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5eb1a131-693d-4f88-b10c-047d2c1cdbb2

📥 Commits

Reviewing files that changed from the base of the PR and between 50e1869 and 65c04c0.

📒 Files selected for processing (2)
  • install/install.ps1
  • install/install.sh

Comment thread docs/install/install.ps1
Comment on lines +18 to +22
$arch = switch ($env:PROCESSOR_ARCHITECTURE) {
'AMD64' { 'amd64' }
'ARM64' { 'arm64' }
default { throw "unsupported architecture: $env:PROCESSOR_ARCHITECTURE" }
}

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show file size and relevant section
wc -l install/install.ps1
sed -n '1,120p' install/install.ps1

# Trace all uses of $arch in this file
rg -n '\$arch\b|PROCESSOR_ARCHITECTURE|PROCESSOR_ARCHITEW6432' install/install.ps1

Repository: ENTERPILOT/GoModel

Length of output: 3507


🏁 Script executed:

#!/bin/bash
set -euo pipefail
wc -l install/install.ps1
sed -n '1,120p' install/install.ps1
rg -n '\$arch\b|PROCESSOR_ARCHITECTURE|PROCESSOR_ARCHITEW6432' install/install.ps1

Repository: ENTERPILOT/GoModel

Length of output: 3507


Detect the native OS architecture under WOW64. install/install.ps1:18-22 A 32-bit PowerShell session reports x86 here, so supported amd64/arm64 Windows installs can be rejected; use PROCESSOR_ARCHITEW6432 when present.

🧰 Tools
🪛 PSScriptAnalyzer (1.25.0)

[warning] Missing BOM encoding for non-ASCII encoded file 'install.ps1'

(PSUseBOMForUnicodeEncodedFile)

🤖 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 `@install/install.ps1` around lines 18 - 22, Update the architecture selection
around $arch to prefer $env:PROCESSOR_ARCHITEW6432 when it is set, falling back
to $env:PROCESSOR_ARCHITECTURE otherwise, then retain the existing AMD64, ARM64,
and unsupported-architecture mappings.

Comment thread docs/install/install.ps1
Comment on lines +41 to +43
$expected = (Get-Content (Join-Path $tmpDir 'checksums.txt') |
Where-Object { $_ -match [regex]::Escape($archive) } |
ForEach-Object { ($_ -split '\s+')[0] }) | Select-Object -First 1

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Match the checksum filename exactly.

The substring regex can select a row for a similarly named artifact. Parse the checksum and require the second field to equal $archive, matching install/install.sh.

Proposed fix
     $expected = (Get-Content (Join-Path $tmpDir 'checksums.txt') |
-        Where-Object { $_ -match [regex]::Escape($archive) } |
-        ForEach-Object { ($_ -split '\s+')[0] }) | Select-Object -First 1
+        ForEach-Object {
+            $parts = $_ -split '\s+', 2
+            if ($parts.Count -eq 2 -and $parts[1].Trim() -eq $archive) {
+                $parts[0]
+            }
+        }) | Select-Object -First 1
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
$expected = (Get-Content (Join-Path $tmpDir 'checksums.txt') |
Where-Object { $_ -match [regex]::Escape($archive) } |
ForEach-Object { ($_ -split '\s+')[0] }) | Select-Object -First 1
$expected = (Get-Content (Join-Path $tmpDir 'checksums.txt') |
ForEach-Object {
$parts = $_ -split '\s+', 2
if ($parts.Count -eq 2 -and $parts[1].Trim() -eq $archive) {
$parts[0]
}
}) | Select-Object -First 1
🧰 Tools
🪛 PSScriptAnalyzer (1.25.0)

[warning] Missing BOM encoding for non-ASCII encoded file 'install.ps1'

(PSUseBOMForUnicodeEncodedFile)

🤖 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 `@install/install.ps1` around lines 41 - 43, Update the checksum selection in
the PowerShell install flow around $expected to parse each checksums.txt row
into fields and require the second field to equal $archive exactly, matching the
behavior in install.sh; retain the first-field checksum as the selected value
and avoid substring regex matching.

Comment thread docs/install/install.ps1
Comment on lines +59 to +62
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
if (($userPath -split ';') -notcontains $installDir) {
[Environment]::SetEnvironmentVariable('Path', "$userPath;$installDir", 'User')
Write-Host "Added $installDir to your user PATH — restart your terminal to pick it up."

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Avoid creating an empty PATH entry.

When the user PATH is unset, Line 61 persists ;$installDir. Build the value conditionally.

Proposed fix
     $userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
     if (($userPath -split ';') -notcontains $installDir) {
-        [Environment]::SetEnvironmentVariable('Path', "$userPath;$installDir", 'User')
+        $newUserPath = if ([string]::IsNullOrWhiteSpace($userPath)) {
+            $installDir
+        } else {
+            "$userPath;$installDir"
+        }
+        [Environment]::SetEnvironmentVariable('Path', $newUserPath, 'User')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
if (($userPath -split ';') -notcontains $installDir) {
[Environment]::SetEnvironmentVariable('Path', "$userPath;$installDir", 'User')
Write-Host "Added $installDir to your user PATH — restart your terminal to pick it up."
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
if (($userPath -split ';') -notcontains $installDir) {
$newUserPath = if ([string]::IsNullOrWhiteSpace($userPath)) {
$installDir
} else {
"$userPath;$installDir"
}
[Environment]::SetEnvironmentVariable('Path', $newUserPath, 'User')
Write-Host "Added $installDir to your user PATH — restart your terminal to pick it up."
🧰 Tools
🪛 PSScriptAnalyzer (1.25.0)

[warning] Missing BOM encoding for non-ASCII encoded file 'install.ps1'

(PSUseBOMForUnicodeEncodedFile)

🤖 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 `@install/install.ps1` around lines 59 - 62, Update the PATH assignment in the
user PATH handling block to avoid prepending a semicolon when $userPath is unset
or empty. Build the new value conditionally while preserving the existing
behavior of appending $installDir when a user PATH already exists and only
setting it when $installDir is not present.

Comment thread docs/install/install.ps1
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
if (($userPath -split ';') -notcontains $installDir) {
[Environment]::SetEnvironmentVariable('Path', "$userPath;$installDir", 'User')
Write-Host "Added $installDir to your user PATH — restart your terminal to pick it up."

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

python3 - <<'PY'
from pathlib import Path
p = Path('install/install.ps1')
data = p.read_bytes()
print('byte_len', len(data))
print('starts_with_utf8_bom', data.startswith(b'\xef\xbb\xbf'))
# show non-ascii bytes with positions
non_ascii = [(i,b) for i,b in enumerate(data) if b >= 0x80]
print('non_ascii_count', len(non_ascii))
print('first_non_ascii', non_ascii[:20])
# print lines around 62 with repr and bytes
text = data.decode('utf-8')
lines = text.splitlines()
for n in range(58, 66):
    if 1 <= n <= len(lines):
        print(f'ল{n}: {lines[n-1]!r}')
PY

Repository: ENTERPILOT/GoModel

Length of output: 669


🏁 Script executed:

sed -n '58,66p' install/install.ps1 | cat -n

Repository: ENTERPILOT/GoModel

Length of output: 587


🏁 Script executed:

python3 - <<'PY'
from pathlib import Path
p = Path('install/install.ps1')
data = p.read_bytes()
print('byte_len', len(data))
print('starts_with_utf8_bom', data.startswith(b'\xef\xbb\xbf'))
non_ascii = [(i,b) for i,b in enumerate(data) if b >= 0x80]
print('non_ascii_count', len(non_ascii))
print('first_non_ascii', non_ascii[:20])
text = data.decode('utf-8')
for n, line in enumerate(text.splitlines(), 1):
    if 58 <= n <= 66:
        print(f'{n}: {line!r}')
PY

Repository: ENTERPILOT/GoModel

Length of output: 697


Replace the em dash with - or add a UTF-8 BOM.

install/install.ps1 is UTF-8 without a BOM, so the non-ASCII em dash can be misread by Windows PowerShell 5.1. Using plain ASCII avoids the encoding warning.

🧰 Tools
🪛 PSScriptAnalyzer (1.25.0)

[warning] Missing BOM encoding for non-ASCII encoded file 'install.ps1'

(PSUseBOMForUnicodeEncodedFile)

🤖 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 `@install/install.ps1` at line 62, Update the Write-Host message in the install
script to replace the non-ASCII em dash with a plain ASCII hyphen, keeping the
rest of the user PATH guidance unchanged.

Source: Linters/SAST tools

Comment thread docs/install/install.sh
Comment on lines +63 to +67
if command -v sha256sum >/dev/null 2>&1; then
actual=$(sha256sum "$tmpdir/$archive" | awk '{ print $1 }')
else
actual=$(shasum -a 256 "$tmpdir/$archive" | awk '{ print $1 }')
fi

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Handle missing checksum utilities cleanly.

If sha256sum is missing, the script falls back to shasum. However, if both tools are missing from the system, the shasum execution will fail silently, resulting in an empty hash and a misleading "checksum mismatch" error.

Explicitly verify the fallback tool's presence and fail with a clear message if neither is available.

🛠️ Proposed fix
 if command -v sha256sum >/dev/null 2>&1; then
     actual=$(sha256sum "$tmpdir/$archive" | awk '{ print $1 }')
-else
+elif command -v shasum >/dev/null 2>&1; then
     actual=$(shasum -a 256 "$tmpdir/$archive" | awk '{ print $1 }')
+else
+    fail "neither sha256sum nor shasum is available"
 fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if command -v sha256sum >/dev/null 2>&1; then
actual=$(sha256sum "$tmpdir/$archive" | awk '{ print $1 }')
else
actual=$(shasum -a 256 "$tmpdir/$archive" | awk '{ print $1 }')
fi
if command -v sha256sum >/dev/null 2>&1; then
actual=$(sha256sum "$tmpdir/$archive" | awk '{ print $1 }')
elif command -v shasum >/dev/null 2>&1; then
actual=$(shasum -a 256 "$tmpdir/$archive" | awk '{ print $1 }')
else
fail "neither sha256sum nor shasum is available"
fi
🤖 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 `@install/install.sh` around lines 63 - 67, Update the checksum selection logic
around sha256sum and shasum to explicitly check whether the fallback shasum
utility exists before invoking it. If neither checksum tool is available,
terminate with a clear error message instead of computing an empty hash or
reporting a misleading checksum mismatch.

Comment thread docs/install/install.sh
Comment on lines +81 to +83
mkdir -p "$install_dir" || fail "cannot create $install_dir"
[ -w "$install_dir" ] || fail "$install_dir is not writable — rerun with GOMODEL_INSTALL_DIR set, or run: sudo install -m 755 $tmpdir/$BINARY /usr/local/bin/"
install -m 755 "$tmpdir/$BINARY" "$install_dir/$BINARY"

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.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Prevent temporary directory cleanup on permission failure and fix the suggested path.

If the target directory is not writable, the script fails and advises the user to run sudo install .... However, there are two issues here:

  1. The global trap configured on line 55 removes the temporary directory immediately when the script exits, which means the suggested sudo install command will fail because the downloaded binary was deleted.
  2. The suggested command hardcodes /usr/local/bin/, ignoring the custom GOMODEL_INSTALL_DIR if the user provided one.

Disable the cleanup trap right before failing to leave the file intact for the manual step, and use the $install_dir variable.

🐛 Proposed fix
 mkdir -p "$install_dir" || fail "cannot create $install_dir"
-[ -w "$install_dir" ] || fail "$install_dir is not writable — rerun with GOMODEL_INSTALL_DIR set, or run: sudo install -m 755 $tmpdir/$BINARY /usr/local/bin/"
+if [ ! -w "$install_dir" ]; then
+    trap - EXIT INT TERM
+    fail "$install_dir is not writable — rerun with GOMODEL_INSTALL_DIR set, or run: sudo install -m 755 $tmpdir/$BINARY $install_dir/"
+fi
 install -m 755 "$tmpdir/$BINARY" "$install_dir/$BINARY"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
mkdir -p "$install_dir" || fail "cannot create $install_dir"
[ -w "$install_dir" ] || fail "$install_dir is not writable — rerun with GOMODEL_INSTALL_DIR set, or run: sudo install -m 755 $tmpdir/$BINARY /usr/local/bin/"
install -m 755 "$tmpdir/$BINARY" "$install_dir/$BINARY"
mkdir -p "$install_dir" || fail "cannot create $install_dir"
if [ ! -w "$install_dir" ]; then
trap - EXIT INT TERM
fail "$install_dir is not writable — rerun with GOMODEL_INSTALL_DIR set, or run: sudo install -m 755 $tmpdir/$BINARY $install_dir/"
fi
install -m 755 "$tmpdir/$BINARY" "$install_dir/$BINARY"
🤖 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 `@install/install.sh` around lines 81 - 83, Update the non-writable-directory
branch guarded by `[ -w "$install_dir" ]` to disable the temporary-directory
cleanup trap before calling `fail`, preserving the downloaded binary for manual
installation. Correct the suggested `sudo install` command to use the
`$install_dir` variable instead of hardcoding `/usr/local/bin/`.

…t lean

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 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/install/install.ps1`:
- Around line 25-27: Update the tag resolution branch in the PowerShell
installer to avoid the unauthenticated GitHub API call. Mirror install.sh by
resolving the releases/latest HTTP redirect and extracting the redirected
release tag, while preserving the provided $tag path and existing behavior when
a tag is supplied.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3c92f6b9-01b0-4ea9-a27e-7882c7a6ab13

📥 Commits

Reviewing files that changed from the base of the PR and between 65c04c0 and de026bd.

📒 Files selected for processing (2)
  • docs/install/install.ps1
  • docs/install/install.sh

Comment thread docs/install/install.ps1
Comment on lines +25 to +27
if (-not $tag) {
$tag = (Invoke-RestMethod "https://api.github.com/repos/$Repo/releases/latest").tag_name
}

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.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Avoid unauthenticated GitHub API calls to prevent rate limiting.

The script uses the GitHub API to fetch the latest release tag. Unauthenticated GitHub API requests are subject to a strict rate limit (60 requests per hour per IP), which frequently causes failures in CI environments, enterprise networks, or shared IPs. The shell script (install.sh) already avoids this by resolving the /releases/latest HTTP redirect instead.

You can resolve the redirect in PowerShell without hitting the API rate limit:

🛠️ Proposed fix
 $tag = $env:GOMODEL_VERSION
 if (-not $tag) {
-    $tag = (Invoke-RestMethod "https://api.github.com/repos/$Repo/releases/latest").tag_name
+    $req = [System.Net.WebRequest]::Create("https://github.com/$Repo/releases/latest")
+    $req.AllowAutoRedirect = $false
+    $res = $req.GetResponse()
+    $tag = ($res.Headers.Location -split '/')[-1]
+    $res.Close()
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (-not $tag) {
$tag = (Invoke-RestMethod "https://api.github.com/repos/$Repo/releases/latest").tag_name
}
if (-not $tag) {
$req = [System.Net.WebRequest]::Create("https://github.com/$Repo/releases/latest")
$req.AllowAutoRedirect = $false
$res = $req.GetResponse()
$tag = ($res.Headers.Location -split '/')[-1]
$res.Close()
}
🧰 Tools
🪛 PSScriptAnalyzer (1.25.0)

[warning] Missing BOM encoding for non-ASCII encoded file 'install.ps1'

(PSUseBOMForUnicodeEncodedFile)

🤖 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 `@docs/install/install.ps1` around lines 25 - 27, Update the tag resolution
branch in the PowerShell installer to avoid the unauthenticated GitHub API call.
Mirror install.sh by resolving the releases/latest HTTP redirect and extracting
the redirected release tag, while preserving the provided $tag path and existing
behavior when a tag is supplied.

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.

2 participants