Skip to content

fix(installer): drop -L in resolve_version, parse first-redirect Location (AL-31)#19

Merged
Roo4L merged 2 commits into
masterfrom
fix/al-31-unpinned-version-resolution
May 9, 2026
Merged

fix(installer): drop -L in resolve_version, parse first-redirect Location (AL-31)#19
Roo4L merged 2 commits into
masterfrom
fix/al-31-unpinned-version-resolution

Conversation

@Roo4L
Copy link
Copy Markdown
Owner

@Roo4L Roo4L commented May 9, 2026

Summary

Fifth dogfood-discovered bug from the v0.3.2-rc2 retest. Unpinned curl ... | bash (no AGENTLINUX_VERSION) dies with "could not parse tag from redirect URL" because resolve_version() follows ALL redirects to the final release-assets.githubusercontent.com URL, which contains opaque tokens but no tag.

Fix

packaging/curl-installer/install.sh:111-117:

  • Drop the -L flag.
  • Read the FIRST hop's Location header via %{redirect_url} instead of %{url_effective}.
  • Tighten the failure-mode diagnostic.

The first redirect hop is always releases/latest/download/<asset>releases/download/<TAG>/<asset>, which carries the tag. The second hop into release-assets.githubusercontent.com does not — that's why -L followed by %{url_effective} lost the tag.

Confirmed locally against the live GitHub redirect: redirect_url evaluates to https://github.com/Roo4L/Agent-Linux/releases/download/v0.3.1/VERSION, tag extraction yields v0.3.1 cleanly.

Test guard

New INST-03 @test in tests/bats/60-curl-installer.bats. Source-shape assertions:

  1. %{redirect_url} is used in a curl invocation.
  2. %{url_effective} is NOT used in resolve_version() code (comments allowed).
  3. resolve_version's curl call carries no -L flag.

This is a static guard, not a behavior test — exercising the live redirect path requires either a 302→302 fixture chain or an env-var seam to override the hardcoded github.com URL, neither of which exists today. Shape guard is sufficient to prevent the regression class.

Why not a behavior test (yet)

The single-fixture python http server in 60-curl-installer.bats:setup_file only serves static files. Adding a 302→302 chain requires a custom python server script, AND resolve_version()'s URL is hardcoded to github.com/${ORG}/agent-linux/... with no env-var override seam. Two separate enhancements; outside this PR's scope. AL-29 may want to revisit if it touches resolve_version.

Test plan

  • gate-1-precommit
  • gate-2-docker × {22.04, 24.04, 26.04} — the new @test asserts on the actual file shipped in the tarball
  • gate-3-qemu × {22.04, 24.04}
  • After merge: dogfood unpinned curl ... | bash (no AGENTLINUX_VERSION) against the next published RC

Refs: AL-18, AL-21, AL-30, AL-31

…tion (AL-31)

Fifth dogfood-discovered bug, surfaced during the v0.3.2-rc2 retest.

`packaging/curl-installer/install.sh:111` (pre-fix) read the latest tag via
`curl -fsSIL -o /dev/null -w '%{url_effective}'` against
`/releases/latest/download/VERSION`. With `-L`, curl followed the entire
redirect chain to the final `release-assets.githubusercontent.com` URL,
which contains opaque tokens but NOT the tag string. The grep returned
empty and the installer died with `could not parse tag from redirect URL`.

The tag IS in the FIRST hop (`releases/latest/download/VERSION` 302→
`releases/download/<TAG>/VERSION`), but `%{url_effective}` after `-L`
reports only the LAST URL.

**Fix**: drop `-L`, switch the write-out template to `%{redirect_url}`
which prints the next-hop Location header without following. Confirmed
locally — `redirect_url=https://github.com/Roo4L/Agent-Linux/releases/
download/v0.3.1/VERSION`, tag extraction yields `v0.3.1` cleanly.

Also tightens the diagnostic message: when no Location header arrives
(server returned 200 instead of 302), the die output now hints
`set AGENTLINUX_VERSION to override` rather than asking the user to
parse an empty redirect URL.

**Test guard**: `tests/bats/60-curl-installer.bats` gains a new INST-03
@test that performs three source-shape assertions on `install.sh`:
  1. `%{redirect_url}` is used somewhere in a curl invocation
  2. `%{url_effective}` is NOT used in resolve_version() code (comments
     allowed — the explanatory comment legitimately mentions both)
  3. resolve_version's curl call carries no -L flag

This is a static guard, not a behavior test — exercising the live
redirect path requires a 302→302 fixture chain or an env-var seam to
override the hardcoded github.com URL, neither of which exists today.
The shape guard prevents the specific regression class without
requiring a fixture rewrite. Future PR can add a behavior fixture if
resolve_version grows.

Workaround for users on pre-AL-31 builds: `export AGENTLINUX_VERSION=...`
before piping. Documented in the v0.3.2-rc2 dogfood instructions
(.planning/quick/260503-dtx-...-SUMMARY.md).

Refs: AL-18, AL-21 (parent retest), AL-30 (the four-bug fix that
surfaced this), AL-31.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 9, 2026

PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://Roo4L.github.io/Agent-Linux/pr-preview/pr-19/

Built to branch gh-pages at 2026-05-09 07:38 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

pnpm v11 (released between 2026-05-03 and 2026-05-09) elevated the
"ignored build scripts" warning to a hard `ERR_PNPM_IGNORED_BUILDS`
error. Corepack auto-fetches the latest pnpm absent a `packageManager`
field, so every fresh install today picks up v11 and dies on the
unconfigured `@biomejs/biome` postinstall script.

Two paired changes:

1. `plugin/cli/package.json` gains a `packageManager: pnpm@10.18.2`
   field. Corepack honors this pin, so CI installs deterministically
   pull pnpm 10.x regardless of upstream releases. v10.18.2 was the
   pnpm version that produced the green CI runs landed on master on
   2026-05-03, so this is bisect-clean.

2. `plugin/cli/pnpm-workspace.yaml` (new) adds an `onlyBuiltDependencies`
   allowlist for `@biomejs/biome`. This is the v10/v11-compatible
   format pnpm itself emits as a template when an unconfigured build
   script is detected. Belt-and-suspenders: when we later relax the
   pin to v11+, the install no longer dies because the script is
   pre-approved.

Verified locally: `corepack pnpm install --frozen-lockfile` produces
`Done in 626ms using pnpm v10.18.2` cleanly. No `ERR_PNPM_IGNORED_BUILDS`.

This commit rides with the AL-31 fix because it blocks AL-31's CI from
ever going green; without it, the AL-31 PR cannot land. Splitting it
into a separate PR would just create a serialization hazard for
zero benefit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Roo4L Roo4L merged commit 20b27d3 into master May 9, 2026
13 checks passed
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