Skip to content

Validate resolved release version in installers#27

Merged
jclusso merged 1 commit into
masterfrom
harden-installer-version-resolution
Jun 2, 2026
Merged

Validate resolved release version in installers#27
jclusso merged 1 commit into
masterfrom
harden-installer-version-resolution

Conversation

@jclusso
Copy link
Copy Markdown
Member

@jclusso jclusso commented Jun 2, 2026

Problem

curl -fsSL https://emailable.com/install-cli | bash fails with a 404. The install-cli URL itself is fine (200, serves the script) — the 404 comes from inside the script when it downloads the release tarball.

Both installers derived the version from the /releases/latest redirect without validating the result. GitHub only points /releases/latest at a full release, so a prerelease-only (or release-less) repo redirects to the /releases listing instead of a /tag/ URL. The old sed 's#.*/tag/##' parse then left the entire URL as the "version", which passed the non-empty guard and produced a bogus download URL that 404'd with a confusing error.

install.ps1 had the identical flaw (($location -split '/tag/')[-1] with no validation).

Fix

Both scripts now:

  • parse the tag from the redirect and validate it against a semver pattern, so a non-/tag/ redirect is rejected here rather than 404ing on a bogus tarball URL later;
  • fall back to the GitHub API if redirect parsing fails;
  • abort with a clear message pointing at EMAILABLE_VERSION when no full release is resolvable.

The semver pattern accepts prerelease suffixes, so an explicit EMAILABLE_VERSION=0.3.0-rc.1 can install a prerelease, even though auto-detection never selects one (mirrors how GitHub's /releases/latest behaves).

Verification

  • bash -n passes; latest_version() correctly aborts against the current prerelease-only repo state.
  • Regex accepts 0.3.0 / 1.2.3-rc.1, rejects the bare releases URL.
  • End-to-end install with EMAILABLE_VERSION=0.3.0 downloads, verifies the checksum, and installs a working binary.
  • install.ps1 could not be execute-linted locally (no pwsh); logic mirrors the bash path and was traced by hand — worth a run on a Windows/pwsh box before merge.

This hardens the failure mode but does not by itself make the published install command succeed: that still requires v0.3.0 to be published as a full release rather than a prerelease.

Copilot AI review requested due to automatic review settings June 2, 2026 02:39
The installers derived the version from the /releases/latest redirect without checking the result. GitHub only points /releases/latest at a full release, so a prerelease-only (or release-less) repo redirects to the /releases listing instead of a /tag/ URL. The old parse left that whole URL as the "version", passed the non-empty guard, and built a bogus download URL that 404'd with a confusing error.

Both scripts now parse the tag from the redirect, validate it against a semver pattern, fall back to the GitHub API, and abort with a clear message pointing at EMAILABLE_VERSION when no full release is resolvable. The pattern accepts prerelease suffixes, so an explicit EMAILABLE_VERSION can install a prerelease even though auto-detection never selects one.
@jclusso jclusso force-pushed the harden-installer-version-resolution branch from 92bf42e to f28a7c4 Compare June 2, 2026 02:41
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens the Bash and PowerShell installers by correctly resolving the “latest full release” version from GitHub and failing early (with a clear error) when the repo has no full releases (e.g., prerelease-only state), preventing confusing 404s from malformed download URLs.

Changes:

  • Added a validated “latest version” resolution path that rejects non-tag redirects by enforcing a semver pattern.
  • Added a GitHub API fallback when /releases/latest redirect parsing fails.
  • Improved failure messaging to point users to EMAILABLE_VERSION / $env:EMAILABLE_VERSION for explicit installs.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
scripts/install.sh Adds latest_version() with semver validation + API fallback; updates version resolution error handling.
scripts/install.ps1 Adds semver validation + Get-LatestVersion with redirect parsing and API fallback; updates version resolution error handling.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jclusso jclusso merged commit 190239b into master Jun 2, 2026
3 checks passed
@jclusso jclusso deleted the harden-installer-version-resolution branch June 2, 2026 13:35
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