Skip to content

fix: Install plugins that publish only pre-releases - #361

Merged
0xmc merged 2 commits into
mainfrom
fix/plugin-install-prerelease
Nov 6, 2026
Merged

0xmc merged 2 commits into
mainfrom
fix/plugin-install-prerelease

Conversation

@0xmc

@0xmc 0xmc commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Installing a plugin by repository failed when the repository had only pre-releases, with an error naming "releases" as the tag.

GitHub never marks a pre-release as latest, so the installer misread the release list page as a tag.

The installer now falls back to the newest pre-release, and upgrades follow newer pre-releases the same way. When nothing installable exists, the error names the tags it found and shows how to pin a version.

Test plan

  • Installing a plugin whose repository has only pre-releases installs the newest one
  • A repository with a stable release still installs that release
  • A repository with no releases, or one that doesn't exist, fails with a message that says how to pin a version

Fixes #356

🤖 Generated with Claude Code

GitHub never marks a pre-release as the latest release, so for a
repository with only pre-releases the releases/latest URL redirects
to the release list. The installer took the last path segment of
that URL as the tag and failed with an unexpected tag format error
naming "releases".

The installer now reads the tag only from a releases/tag/<tag>
redirect. When there is no latest release it lists the repository's
releases through the GitHub API and picks the highest semantic
version tag, skipping drafts. Plugin upgrade uses the same lookup, so
a pre-release install upgrades to newer pre-releases.

Tags must now be valid semantic versions, and errors name the
rejected tag, the accepted format, and how to pin a release with
owner/repo@<tag>.

Fixes #356

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@0xmc
0xmc requested a review from a team as a code owner November 6, 2026 19:17
@0xmc
0xmc enabled auto-merge November 6, 2026 19:17

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

Approve.

"Latest" still resolves to the release GitHub marks latest, and the pre-release listing is used only when that redirect says no stable release exists, so a stable release is never displaced by a pre-release. Checksum and signature verification take the resolved tag and are untouched.

  • Fallback ordering is right: fetchLatestTag returns the stable tag whenever one exists and only then calls the API. Drafts are skipped, and semver.Compare ranks -rc.1 above -beta.2 correctly and ignores build metadata (two tags differing only in +build tie, first listed wins).
  • Pagination: only the first 100 releases are read and Link is not followed. For a repo with more than 100 pre-releases the true highest could sit on a later page, though the API lists newest first so it is rarely wrong in practice.
  • semver.IsValid is now enforced on the stable path too. A stable repo whose latest tag is not semver (for example vNext or v1.2.3.4) used to install and now errors out. That is stricter and safer for the path-derived tag, but it is a behaviour change.

Follow-ups:

  • Print a notice when the fallback picks a pre-release, so a user who typed an unpinned install knows they got v1.0.0-preview.28 rather than a stable build.
  • Follow Link: rel=next pages, or stop at the first page and say so in the error.
  • Unauthenticated API calls are limited to 60 per hour per IP; the error already carries the owner/repo@<tag> pin hint, which is the right fallback.

@0xmc
0xmc merged commit a6135d8 into main Nov 6, 2026
2 checks passed
@0xmc
0xmc deleted the fix/plugin-install-prerelease branch November 6, 2026 19:50
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.

plugin install datum-cloud/connect fails on the release tag format

3 participants