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
44 changes: 36 additions & 8 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
name: Release

# Builds the `autter` binary for every supported platform, publishes them as a
# GitHub Release, and attaches a version-pinned install.sh (placeholders filled
# in with the real repo, version, and SHA256 checksums).
# GitHub Release, and attaches version-pinned install.sh/install.ps1 copies
# (placeholders filled in with the real repo, version, and SHA256 checksums).
#
# Trigger:
# - pushing a tag matching `v*` (e.g. v1.5.9) publishes a release
# - manual run via the Actions tab (workflow_dispatch) builds the binaries
# for validation but does NOT publish (no tag to release against)
#
# Asset names match what install.sh expects: autter-<os>-<arch>
# Asset names match what install.sh / install.ps1 expect: autter-<os>-<arch>
# macos/arm64 -> autter-macos-arm64 macos/x64 -> autter-macos-x64
# linux/x64 -> autter-linux-x64 linux/arm64 -> autter-linux-arm64
# windows/x64 -> autter-windows-x64.exe
# windows/arm64 -> autter-windows-arm64.exe

on:
push:
Expand Down Expand Up @@ -61,6 +63,18 @@
os: ubuntu-22.04
target: aarch64-unknown-linux-gnu
tool: cross
- asset: autter-windows-x64.exe

Check warning on line 66 in .github/workflows/release.yml

View check run for this annotation

Autter.dev / autter/review-gate

🟠 Medium · Missing linked tracker issue

The PR description does not reference a tracker issue for the release workflow and installer changes. Without issue traceability, the Windows release assets, checksum generation, and attached install scripts lack a linked record for downstream release and support follow-up. Suggested fix: Add a GitHub, Jira, or Linear tracker reference such as #123 or KEY-123 to the PR description, preferably in the summary or closing section.

Check warning on line 66 in .github/workflows/release.yml

View check run for this annotation

Autter.dev / autter/review-gate

🟠 Medium · Missing CODEOWNERS reviewer approval

No CODEOWNERS entries or approving reviewers are present for the changed paths; the only listed reviewer requested changes. This leaves release.yml, install.ps1, install.sh, documentation, changelog, and src/authorship/cas_bridge.rs without required owner approval, putting release publication, installer behavior, and enqueue_transcript_file/messages_from_transcript_file changes downstream at risk. Suggested fix: Add or restore CODEOWNERS coverage for every changed path, then obtain an approving review from a matching owner for each path. Resolve the requested changes before merging.

Check warning on line 66 in .github/workflows/release.yml

View check run for this annotation

Autter.dev / autter/review-gate

🟠 Medium · Missing linked tracker issue

The PR description does not reference a tracker issue for the release workflow and installer changes. Without issue traceability, the Windows release assets, checksum generation, and attached install scripts lack a linked record for downstream release and support follow-up. Suggested fix: Add a GitHub, Jira, or Linear tracker reference such as #123 or KEY-123 to the PR description, preferably in the summary or closing section.

Check warning on line 66 in .github/workflows/release.yml

View check run for this annotation

Autter.dev / autter/review-gate

🟠 Medium · Missing CODEOWNERS reviewer approval

No CODEOWNERS entries or approving reviewers are present for the changed paths; the only listed reviewer requested changes. This leaves release.yml, install.ps1, install.sh, documentation, changelog, and src/authorship/cas_bridge.rs without required owner approval, putting release publication, installer behavior, and enqueue_transcript_file/messages_from_transcript_file changes downstream at risk. Suggested fix: Add or restore CODEOWNERS coverage for every changed path, then obtain an approving review from a matching owner for each path. Resolve the requested changes before merging.
# No OpenSSL needed on Windows: TLS goes through native-tls/SChannel,
# and the only C build is the bundled SQLite (handled by cc + MSVC).
os: windows-2022
target: x86_64-pc-windows-msvc
tool: cargo
- asset: autter-windows-arm64.exe
# Cross-compile ARM64 on the x64 runner: the preinstalled VS 2022
# toolchain includes the ARM64 MSVC compiler and libraries.
os: windows-2022
target: aarch64-pc-windows-msvc
tool: cargo
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down Expand Up @@ -96,7 +110,11 @@
shell: bash
run: |
mkdir -p dist
cp "target/${{ matrix.target }}/release/autter" "dist/${{ matrix.asset }}"
src="target/${{ matrix.target }}/release/autter"
if [[ "${{ matrix.target }}" == *-windows-* ]]; then
src="${src}.exe"
fi
cp "${src}" "dist/${{ matrix.asset }}"

- name: Upload artifact
uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -126,29 +144,36 @@
run: |
set -euo pipefail
mkdir -p dist
assets="autter-macos-arm64 autter-macos-x64 autter-linux-x64 autter-linux-arm64 autter-windows-x64.exe autter-windows-arm64.exe"
# download-artifact nests each artifact under its own directory
for asset in autter-macos-arm64 autter-macos-x64 autter-linux-x64 autter-linux-arm64; do
for asset in ${assets}; do
cp "artifacts/${asset}/${asset}" "dist/${asset}"
chmod +x "dist/${asset}"
done

# Build the checksums file and the pipe-separated string install.sh embeds.
# Build the checksums file and the pipe-separated string the install
# scripts embed.
: > dist/checksums.txt
CHECKSUMS=""
for asset in autter-macos-arm64 autter-macos-x64 autter-linux-x64 autter-linux-arm64; do
for asset in ${assets}; do
line="$(cd dist && sha256sum "${asset}")"
echo "${line}" >> dist/checksums.txt
CHECKSUMS="${CHECKSUMS:+${CHECKSUMS}|}${line}"
done
echo "Checksums:"
cat dist/checksums.txt

# Fill the install.sh placeholders for the version-pinned release copy.
# Fill the install script placeholders for the version-pinned release
# copies (bash and PowerShell).
python3 scripts/fill-install-template.py install.sh dist/install.sh \
--repo "${GITHUB_REPOSITORY}" \
--version "${GITHUB_REF_NAME}" \
--checksums "${CHECKSUMS}"
chmod +x dist/install.sh
python3 scripts/fill-install-template.py install.ps1 dist/install.ps1 \
--repo "${GITHUB_REPOSITORY}" \
--version "${GITHUB_REF_NAME}" \
--checksums "${CHECKSUMS}"

- name: Create GitHub Release
env:
Expand All @@ -162,5 +187,8 @@
dist/autter-macos-x64 \
dist/autter-linux-x64 \
dist/autter-linux-arm64 \
dist/autter-windows-x64.exe \
dist/autter-windows-arm64.exe \
dist/install.sh \
dist/install.ps1 \
dist/checksums.txt
2 changes: 1 addition & 1 deletion INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ curl -fsSL https://api.autter.dev/install.sh | bash
Run:

```powershell
powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://api.autter.dev/install.ps1 | iex"
powershell -NoProfile -ExecutionPolicy Bypass -Command "iex (irm https://api.autter.dev/install.ps1)"
```

> **Git Bash is not WSL.** The bash installer only runs on macOS, Linux, and WSL; in Git Bash it exits with instructions instead of installing. Use the Windows command above (it also works from Git Bash), and install Autter in the environment where your coding agents run — agents inside WSL need the WSL install.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ curl -fsSL https://api.autter.dev/install.sh | bash
**Windows (PowerShell, Command Prompt, or Git Bash)**

```powershell
powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://api.autter.dev/install.ps1 | iex"
powershell -NoProfile -ExecutionPolicy Bypass -Command "iex (irm https://api.autter.dev/install.ps1)"
```

> **Git Bash is not WSL.** The bash installer needs a real Linux environment, so on Windows it only runs inside [WSL](https://learn.microsoft.com/windows/wsl/about) — in Git Bash it exits with instructions. Use the Windows command instead (it works from Git Bash too), and install the CLI where your coding agents actually run: agents launched from Windows need the native install, agents inside WSL need the WSL install.
Expand Down
44 changes: 44 additions & 0 deletions changelog/windows-release-and-installer-fixes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Windows Release Binaries & Installer Fixes

## Summary

Windows installs were broken end-to-end, with five independent reports converging on the same experience: the documented PowerShell one-liner either died in the shell before running, crashed inside architecture detection, or failed with an opaque `Failed to download binary (HTTP error)`. Three stacked root causes:

Check notice on line 5 in changelog/windows-release-and-installer-fixes.md

View check run for this annotation

Autter.dev / autter/review-gate

🟡 Low · markdownlint: MD013

Line length: Expected: 80; Actual: 315 Suggested fix: Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:5: Line length: Expected: 80; Actual: 315

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 [deterministic] markdownlint: MD013 — Risk: 30/100

Line length: Expected: 80; Actual: 315

🛠 AI fix prompt (copy & paste into your coding agent)
Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:5: Line length: Expected: 80; Actual: 315

Flagged by Autter security & observability checks.


1. **Releases shipped no Windows binaries at all.** `release.yml` had no Windows targets in its build matrix, so every `autter-windows-x64.exe` download URL 404'd — while the docs advertised Windows support.

Check notice on line 7 in changelog/windows-release-and-installer-fixes.md

View check run for this annotation

Autter.dev / autter/review-gate

🟡 Low · markdownlint: MD013

Line length: Expected: 80; Actual: 207 Suggested fix: Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:7: Line length: Expected: 80; Actual: 207

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 [deterministic] markdownlint: MD013 — Risk: 30/100

Line length: Expected: 80; Actual: 207

🛠 AI fix prompt (copy & paste into your coding agent)
Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:7: Line length: Expected: 80; Actual: 207

Flagged by Autter security & observability checks.

2. **`install.ps1` architecture detection could crash.** `Get-Architecture` probed `RuntimeInformation::OSArchitecture` (unresolvable on some Windows PowerShell 5.1 hosts) and its env-var fallback misdetected 32-bit shells on 64-bit Windows (`PROCESSOR_ARCHITECTURE='x86'` under WOW64), returning `$null` — and the "unsupported architecture" error message then re-probed `RuntimeInformation` *outside* any try/catch, replacing the friendly error with an uncaught `PropertyNotFound`/`TypeNotFound` exception.

Check notice on line 8 in changelog/windows-release-and-installer-fixes.md

View check run for this annotation

Autter.dev / autter/review-gate

🟡 Low · markdownlint: MD013

Line length: Expected: 80; Actual: 507 Suggested fix: Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:8: Line length: Expected: 80; Actual: 507

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 [deterministic] markdownlint: MD013 — Risk: 30/100

Line length: Expected: 80; Actual: 507

🛠 AI fix prompt (copy & paste into your coding agent)
Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:8: Line length: Expected: 80; Actual: 507

Flagged by Autter security & observability checks.

3. **Download failures were opaque.** All download exceptions were swallowed and reported as a single `Failed to download binary (HTTP error)` with no URL, status code, or troubleshooting path.

Check notice on line 9 in changelog/windows-release-and-installer-fixes.md

View check run for this annotation

Autter.dev / autter/review-gate

🟡 Low · markdownlint: MD013

Line length: Expected: 80; Actual: 193 Suggested fix: Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:9: Line length: Expected: 80; Actual: 193

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 [deterministic] markdownlint: MD013 — Risk: 30/100

Line length: Expected: 80; Actual: 193

🛠 AI fix prompt (copy & paste into your coding agent)
Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:9: Line length: Expected: 80; Actual: 193

Flagged by Autter security & observability checks.


Fixing this also surfaced a latent release bug affecting **all** platforms: the version-pinned install scripts attached to releases silently ignored their version pin and skipped checksum verification (see below).

Check notice on line 11 in changelog/windows-release-and-installer-fixes.md

View check run for this annotation

Autter.dev / autter/review-gate

🟡 Low · markdownlint: MD013

Line length: Expected: 80; Actual: 213 Suggested fix: Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:11: Line length: Expected: 80; Actual: 213

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 [deterministic] markdownlint: MD013 — Risk: 30/100

Line length: Expected: 80; Actual: 213

🛠 AI fix prompt (copy & paste into your coding agent)
Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:11: Line length: Expected: 80; Actual: 213

Flagged by Autter security & observability checks.


## Changes

### `.github/workflows/release.yml`

- **New build targets**: `autter-windows-x64.exe` (`x86_64-pc-windows-msvc`) and `autter-windows-arm64.exe` (`aarch64-pc-windows-msvc`, cross-compiled on the same x64 runner via the VS 2022 ARM64 toolchain), both on `windows-2022`. No OpenSSL is needed on Windows — TLS goes through native-tls/SChannel, and the only C build is the bundled SQLite.

Check notice on line 17 in changelog/windows-release-and-installer-fixes.md

View check run for this annotation

Autter.dev / autter/review-gate

🟡 Low · markdownlint: MD013

Line length: Expected: 80; Actual: 347 Suggested fix: Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:17: Line length: Expected: 80; Actual: 347

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 [deterministic] markdownlint: MD013 — Risk: 30/100

Line length: Expected: 80; Actual: 347

🛠 AI fix prompt (copy & paste into your coding agent)
Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:17: Line length: Expected: 80; Actual: 347

Flagged by Autter security & observability checks.

- The stage step appends `.exe` to the built-binary path for Windows targets; the assemble step's asset list (single `assets` variable now, previously duplicated) includes both Windows binaries in `checksums.txt` and the embedded checksum string.

Check notice on line 18 in changelog/windows-release-and-installer-fixes.md

View check run for this annotation

Autter.dev / autter/review-gate

🟡 Low · markdownlint: MD013

Line length: Expected: 80; Actual: 246 Suggested fix: Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:18: Line length: Expected: 80; Actual: 246

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 [deterministic] markdownlint: MD013 — Risk: 30/100

Line length: Expected: 80; Actual: 246

🛠 AI fix prompt (copy & paste into your coding agent)
Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:18: Line length: Expected: 80; Actual: 246

Flagged by Autter security & observability checks.

- **Version-pinned `install.ps1` is now attached to releases** (filled by the same `fill-install-template.py`), giving Windows the pin + checksum verification that install.sh already had on paper.

Check notice on line 19 in changelog/windows-release-and-installer-fixes.md

View check run for this annotation

Autter.dev / autter/review-gate

🟡 Low · markdownlint: MD013

Line length: Expected: 80; Actual: 196 Suggested fix: Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:19: Line length: Expected: 80; Actual: 196

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 [deterministic] markdownlint: MD013 — Risk: 30/100

Line length: Expected: 80; Actual: 196

🛠 AI fix prompt (copy & paste into your coding agent)
Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:19: Line length: Expected: 80; Actual: 196

Flagged by Autter security & observability checks.


### `install.ps1`

- **`Get-Architecture` rewritten**: checks `PROCESSOR_ARCHITEW6432` first (set for 32-bit shells on 64-bit Windows, where `PROCESSOR_ARCHITECTURE` misreports `x86`), then `PROCESSOR_ARCHITECTURE`, then falls back to `RuntimeInformation` inside a try/catch. Env vars exist on every PowerShell version and can't throw.

Check notice on line 23 in changelog/windows-release-and-installer-fixes.md

View check run for this annotation

Autter.dev / autter/review-gate

🟡 Low · markdownlint: MD013

Line length: Expected: 80; Actual: 316 Suggested fix: Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:23: Line length: Expected: 80; Actual: 316

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 [deterministic] markdownlint: MD013 — Risk: 30/100

Line length: Expected: 80; Actual: 316

🛠 AI fix prompt (copy & paste into your coding agent)
Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:23: Line length: Expected: 80; Actual: 316

Flagged by Autter security & observability checks.

- **Unsupported-architecture error no longer crashes**: it reports `$env:PROCESSOR_ARCHITECTURE` instead of re-probing `RuntimeInformation` outside a try/catch.

Check notice on line 24 in changelog/windows-release-and-installer-fixes.md

View check run for this annotation

Autter.dev / autter/review-gate

🟡 Low · markdownlint: MD013

Line length: Expected: 80; Actual: 160 Suggested fix: Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:24: Line length: Expected: 80; Actual: 160

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 [deterministic] markdownlint: MD013 — Risk: 30/100

Line length: Expected: 80; Actual: 160

🛠 AI fix prompt (copy & paste into your coding agent)
Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:24: Line length: Expected: 80; Actual: 160

Flagged by Autter security & observability checks.

- **Transparent download errors**: each failed attempt is recorded as `<url> -> HTTP <code> <status>` (or the exception message for network/TLS failures). The final error lists every attempted URL with its specific failure, and a 404 gets targeted guidance: the release has no Windows binary, Windows binaries ship with v1.6.8+, and how to unpin `AUTTER_RELEASE_TAG`.

Check notice on line 25 in changelog/windows-release-and-installer-fixes.md

View check run for this annotation

Autter.dev / autter/review-gate

🟡 Low · markdownlint: MD013

Line length: Expected: 80; Actual: 367 Suggested fix: Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:25: Line length: Expected: 80; Actual: 367

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 [deterministic] markdownlint: MD013 — Risk: 30/100

Line length: Expected: 80; Actual: 367

🛠 AI fix prompt (copy & paste into your coding agent)
Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:25: Line length: Expected: 80; Actual: 367

Flagged by Autter security & observability checks.


### `install.sh` + `install.ps1` — fill-proof placeholder guards

`fill-install-template.py` blindly replaces every occurrence of each placeholder token, **including the guard comparisons**. In the pinned copy attached to releases, `[ "$PINNED_VERSION" != "__VERSION_PLACEHOLDER__" ]` became `[ "v1.6.7" != "v1.6.7" ]` (never true → the pin was ignored and "latest" installed) and the checksum guard compared the checksums string to itself (always true → verification silently skipped). Verified against the actual v1.6.7 release asset. Both scripts now compare against sentinel values built by string concatenation (`'__VERSION_' + 'PLACEHOLDER__'`), which survive the fill; comments no longer embed the literal tokens either.

Check notice on line 29 in changelog/windows-release-and-installer-fixes.md

View check run for this annotation

Autter.dev / autter/review-gate

🟡 Low · markdownlint: MD013

Line length: Expected: 80; Actual: 661 Suggested fix: Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:29: Line length: Expected: 80; Actual: 661

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 [deterministic] markdownlint: MD013 — Risk: 30/100

Line length: Expected: 80; Actual: 661

🛠 AI fix prompt (copy & paste into your coding agent)
Fix the markdownlint `MD013` issue at changelog/windows-release-and-installer-fixes.md:29: Line length: Expected: 80; Actual: 661

Flagged by Autter security & observability checks.


### `README.md`, `INSTALL.md`

- The Windows one-liner is now `powershell ... -Command "iex (irm https://api.autter.dev/install.ps1)"` instead of `"irm ... | iex"`. With the pipe form, any context that strips/mangles the quotes (smart-quote rendering, copy-paste through quote-stripping shells) turns `|` into a real shell pipe and `iex` is lost, producing "'iex' is not recognized". The `iex (...)` form has no pipe to hijack and survives quote stripping in cmd, PowerShell, and Git Bash.

## Behaviour Guarantees

| Scenario | Before | After |
|---|---|---|
| Windows install, any release ≤ v1.6.7 | 404 → `Failed to download binary (HTTP error)` | v1.6.8+ releases include `autter-windows-{x64,arm64}.exe`; 404s explain the cause and fix |
| 32-bit PowerShell on 64-bit Windows | arch `$null` → uncaught `PropertyNotFound`/`TypeNotFound` crash | detected via `PROCESSOR_ARCHITEW6432` → correct binary |
| PS 5.1 host without `RuntimeInformation` | crash or fallback-dependent | env-var detection, no type probing needed |
| Download failure (network/proxy/TLS) | opaque one-liner | per-URL reason + troubleshooting hints |
| Pinned release install script | installed "latest", skipped checksum verification | installs the pinned version, verifies checksums |
| One-liner pasted through quote-stripping contexts | `'iex' is not recognized` | works (no pipe to hijack) |
85 changes: 63 additions & 22 deletions install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ function Verify-Checksum {
)

# Skip verification if no checksums are embedded
if ($EmbeddedChecksums -eq '__CHECKSUMS_PLACEHOLDER__') {
if ($EmbeddedChecksums -eq $ChecksumsSentinel) {
return
}

Expand Down Expand Up @@ -218,42 +218,52 @@ function Verify-Checksum {
Write-Success "Checksum verified for $BinaryName"
}

# GitHub repository details
# Replaced during release builds with the actual repository (e.g., "autter-dev/autter-cli")
# When set to __REPO_PLACEHOLDER__, defaults to "autter-dev/autter-cli"
# Release-fill placeholders. The release workflow blindly string-replaces each
# placeholder token EVERYWHERE in this file, so the guards below compare
# against *Sentinel values built by concatenation — those survive the fill.
# Comparing against the literal token would self-destruct on fill: the pinned
# copy would ignore its version pin and skip checksum verification.

# Repository ("owner/repo"); the sentinel defaults to the canonical repo.
$Repo = '__REPO_PLACEHOLDER__'
if ($Repo -eq '__REPO_PLACEHOLDER__') {
$RepoSentinel = '__REPO_' + 'PLACEHOLDER__'
if ($Repo -eq $RepoSentinel) {
$Repo = 'autter-dev/autter-cli'
}

# Version placeholder - replaced during release builds with actual version (e.g., "v1.0.24")
# When set to __VERSION_PLACEHOLDER__, defaults to "latest"
# Version pin (e.g. "v1.6.8") in release copies; the sentinel means "latest".
$PinnedVersion = '__VERSION_PLACEHOLDER__'
$VersionSentinel = '__VERSION_' + 'PLACEHOLDER__'

# Embedded checksums - replaced during release builds with actual SHA256 checksums
# Format: "hash filename|hash filename|..." (pipe-separated)
# When set to __CHECKSUMS_PLACEHOLDER__, checksum verification is skipped
# Pipe-separated "sha256 filename" entries in release copies; checksum
# verification is skipped when left as the sentinel.
$EmbeddedChecksums = '__CHECKSUMS_PLACEHOLDER__'
$ChecksumsSentinel = '__CHECKSUMS_' + 'PLACEHOLDER__'

# Ensure TLS 1.2 for GitHub downloads on older PowerShell versions
try {
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
} catch { }

function Get-Architecture {
# Environment variables first: they exist on every PowerShell version.
# PROCESSOR_ARCHITEW6432 is set when a 32-bit shell runs on a 64-bit OS
# (WOW64), where PROCESSOR_ARCHITECTURE misreports 'x86'.
foreach ($pa in @($env:PROCESSOR_ARCHITEW6432, $env:PROCESSOR_ARCHITECTURE)) {
if ([string]::IsNullOrWhiteSpace($pa)) { continue }
if ($pa -match 'ARM64') { return 'arm64' }
if ($pa -match '64') { return 'x64' }
}
# Fallback: RuntimeInformation, which some Windows PowerShell 5.1 hosts
# cannot resolve (the type lives in a facade assembly that is not always
# loaded), so it may throw rather than return.
try {
$arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
switch ($arch) {
switch ("$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)") {
'X64' { return 'x64' }
'Arm64' { return 'arm64' }
default { return $null }
}
} catch {
$pa = $env:PROCESSOR_ARCHITECTURE
if ($pa -match 'ARM64') { return 'arm64' }
elseif ($pa -match '64') { return 'x64' }
else { return $null }
}
} catch { }
return $null
}

# Ensure $PathToAdd is on the User PATH (appended if absent). No Machine PATH,
Expand Down Expand Up @@ -312,7 +322,13 @@ function Set-PathEnsureContains {

# Detect architecture and OS
$arch = Get-Architecture
if (-not $arch) { Write-ErrorAndExit "Unsupported architecture: $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)" }
if (-not $arch) {
# Do NOT probe RuntimeInformation here: on hosts where it is unavailable
# that probe itself throws, replacing this message with an unrelated
# PropertyNotFound/TypeNotFound error.
$reported = if ([string]::IsNullOrWhiteSpace($env:PROCESSOR_ARCHITECTURE)) { 'unknown' } else { $env:PROCESSOR_ARCHITECTURE }
Write-ErrorAndExit "Unsupported architecture (PROCESSOR_ARCHITECTURE='$reported'). autter provides Windows binaries for x64 and arm64."
}
$os = 'windows'

# Determine binary name and download URLs
Expand All @@ -322,7 +338,7 @@ $binaryName = "autter-$os-$arch"
# Priority: 1. Local binary override, 2. Pinned version (for release builds), 3. Environment variable, 4. "latest"
if (-not [string]::IsNullOrWhiteSpace($env:AUTTER_LOCAL_BINARY)) {
$releaseTag = 'local'
} elseif ($PinnedVersion -ne '__VERSION_PLACEHOLDER__') {
} elseif ($PinnedVersion -ne $VersionSentinel) {
# Version-pinned install script from a release
$releaseTag = $PinnedVersion
$downloadUrlExe = "https://github.com/$Repo/releases/download/$releaseTag/$binaryName.exe"
Expand Down Expand Up @@ -452,6 +468,10 @@ New-Item -ItemType Directory -Force -Path $installDir | Out-Null
Write-Host ("Downloading autter (release: {0})..." -f $releaseTag)
$tmpFile = Join-Path $installDir "autter.tmp.$PID.exe"

# Each failed attempt is recorded as "<url> -> <reason>" so the final error
# can report exactly what was tried instead of an opaque "HTTP error".
$downloadFailures = New-Object System.Collections.Generic.List[string]

function Try-Download {
param(
[Parameter(Mandatory = $true)][string]$Url
Expand All @@ -468,6 +488,17 @@ function Try-Download {
}
return $true
} catch {
$reason = $_.Exception.Message
try {
# WebException (PowerShell 5.1) and HttpResponseException (7+) both
# carry the response; pure network/TLS failures have none, and on
# some exception types even probing .Response throws — hence the
# inner try/catch keeping the plain exception message.
if ($_.Exception.Response -and $_.Exception.Response.StatusCode) {
$reason = 'HTTP {0} {1}' -f [int]$_.Exception.Response.StatusCode, $_.Exception.Response.StatusCode
}
} catch { }
[void]$downloadFailures.Add((" {0}`n -> {1}" -f $Url, $reason))
return $false
}
}
Expand All @@ -489,7 +520,17 @@ if (-not [string]::IsNullOrWhiteSpace($env:AUTTER_LOCAL_BINARY)) {

if (-not $downloadedBinaryName) {
Remove-Item -Force -ErrorAction SilentlyContinue $tmpFile
Write-ErrorAndExit 'Failed to download binary (HTTP error)'
$details = $downloadFailures -join "`n"
$message = "Failed to download $binaryName (release: $releaseTag). Attempted:`n$details"
if ($details -match 'HTTP 404') {
$message += "`nA 404 means release '$releaseTag' does not include a Windows binary named $binaryName."
$message += "`nWindows binaries ship with releases v1.6.8 and later - see https://github.com/$Repo/releases"
$message += "`nIf AUTTER_RELEASE_TAG pins an older version, unset it to install the latest release."
} else {
$message += "`nCheck your network connection, proxy, and TLS settings, then retry."
$message += "`nReleases: https://github.com/$Repo/releases"
}
Write-ErrorAndExit $message
}

try {
Expand Down
Loading
Loading