Skip to content

fix: improve release fetching#964

Draft
gregmagolan wants to merge 1 commit intomainfrom
release_fetch_fixes
Draft

fix: improve release fetching#964
gregmagolan wants to merge 1 commit intomainfrom
release_fetch_fixes

Conversation

@gregmagolan
Copy link
Member

@gregmagolan gregmagolan commented Mar 13, 2026

Currently the release fetcher fails if it finds a release without any assets. This is possible is you happen to check the latest release mid-release when it doesn't have any assets yet. This improves the code so that it falls back to the latest release that has an asset to download when searching.

Before

The GitHub source handler had a single code path for both pinned and unpinned versions:

  1. Compute tag as v{version} — for unpinned, version was always the launcher's own compiled-in version
  2. Query the GitHub API for that specific release: GET /repos/{org}/{repo}/releases/tags/{tag}
  3. Find the matching artifact in the response's assets array
  4. Download via the API asset URL (api.github.com/.../assets/{id})

Problems:

  • The Release struct required the assets field, but GitHub sometimes omits it → missing field 'assets' deserialization error
  • Unpinned versions were tied to the launcher's compiled-in version rather than discovering the latest available release
  • No handling for the release-in-progress window where a tag exists but assets haven't been uploaded yet
  • A version_pinned boolean was threaded through ToolSpec / AspectCliConfig but both paths used the same download logic

After

The GitHub source handler is now split into two clean steps — resolve, then download:

Step 1 — Resolve the tag:

  • Pinned (version = Some("2026.11.6") from version.axl): compute the tag directly (e.g. v2026.11.6). No API call.
  • Unpinned (version = None — no version.axl, or version() with no positional arg): query GET /repos/{org}/{repo}/releases?per_page=10, scan the most recent releases, and pick the first one whose assets contain the matching artifact.

Step 2 — Download using the resolved tag:

Both paths now have a concrete tag and use the same direct download URL:
https://github.com/{org}/{repo}/releases/download/{resolved_tag}/{artifact}

What this fixes:

  • assets now has #[serde(default)], so releases with missing or empty assets are skipped instead of causing a deserialization error
  • Unpinned versions discover the latest available release instead of guessing based on the launcher's compiled-in version
  • The release-in-progress window is handled gracefully — releases without the matching artifact are skipped in favor of the next one
  • The version_pinned boolean is removed; version: Option<String> on ToolSpec naturally encodes the distinction (Some = pinned, None = resolve from API)
  • The cache key is now based on the direct download URL (which includes the resolved tag), so different versions cache independently

@gregmagolan gregmagolan force-pushed the release_fetch_fixes branch from 83063aa to affe055 Compare March 13, 2026 21:31
@gregmagolan gregmagolan force-pushed the release_fetch_fixes branch from affe055 to 1fdcdbe Compare March 15, 2026 22:54
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