fix: version matching and tool cache keys for build-metadata tags#255
fix: version matching and tool cache keys for build-metadata tags#255Lauri "datafox" Heino (melodicore) wants to merge 7 commits into
Conversation
Tags like 1.4.0+20260707 were collapsed to 1.4.0 by semver.clean inside tool-cache, causing cache collisions across different dated builds of the same version. toSemverCacheKey now converts build metadata to a prerelease segment (1.4.0+20260707 -> 1.4.0-build.20260707) which semver.clean preserves. The existing-binary skip check and post-install mismatch warning were also doing exact string equality against the tag, which always failed because elide --version appends a commit hash suffix (.6f7ffa7) not present in the tag. Both comparisons now accept the binary version if it starts with the requested tag followed by a dot.
Pulling the binary-vs-tag comparison into a named exported function makes it independently testable. New tests cover exact matches, commit-hash suffixes, build-metadata tags, and false-positive guards (no dot separator, mismatched build dates, binary ahead of prerelease tag). Also adds a multi-part build metadata case to the toSemverCacheKey suite (e.g. 1.4.0+20260707.abc123) to guard against future tag format changes.
Shell, apt, msi, pkg, and rpm installers all set ElideRelease.version.tag_name to the binary's own obtainVersion() output. main.ts then compared that same value against itself in the post-install mismatch check, so the warning could never fire regardless of what version the user requested. Fix: non-archive installers now set tag_name to options.version (the version the user requested). The mismatch check gains an isSymbolic guard to skip verification when tag_name is 'latest', since that cannot be compared against a real binary version string.
Bundle ReportChanges will increase total bundle size by 1.94kB (0.09%) ⬆️. This is within the configured threshold ✅ Detailed changes
Affected Assets, Files, and Routes:view changes for bundle: setup-elideAssets Changed:
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #255 +/- ##
==========================================
+ Coverage 86.40% 86.81% +0.40%
==========================================
Files 13 13
Lines 1236 1365 +129
==========================================
+ Hits 1068 1185 +117
- Misses 168 180 +12
|
There was a problem hiding this comment.
Pull request overview
This PR fixes Elide version handling when tags include semver build metadata (e.g. 1.4.0+20260707), ensuring both tool-cache lookups and post-install version validation behave correctly across installers.
Changes:
- Prevents tool-cache collisions by converting build-metadata tags into semver prerelease form for cache keys (so
semver.clean()doesn’t drop the distinguishing segment). - Adds
versionMatchesTag(ver, tag)to treat.{commithash}-suffixed binary versions as matching the requested tag, and uses it for both “existing binary” preservation and mismatch warnings. - Fixes mismatch detection for non-archive installers by recording the requested tag as
release.version.tag_name(and skipping mismatch checks for symboliclatest).
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/releases.ts | Adds build-metadata-aware cache key conversion to avoid tool-cache key collisions. |
| src/main.ts | Introduces versionMatchesTag and uses it for preservation + mismatch warning logic (incl. skipping latest). |
| src/install-shell.ts | Ensures tag_name reflects the requested version (not the binary’s self-reported version). |
| src/install-apt.ts | Ensures tag_name reflects the requested version (not the binary’s self-reported version). |
| src/install-msi.ts | Ensures tag_name reflects the requested version (not the binary’s self-reported version). |
| src/install-pkg.ts | Ensures tag_name reflects the requested version (not the binary’s self-reported version). |
| src/install-rpm.ts | Ensures tag_name reflects the requested version (not the binary’s self-reported version). |
| tests/releases.test.ts | Adds unit coverage for toSemverCacheKey, including build-metadata cases. |
| tests/main.test.ts | Adds unit coverage for versionMatchesTag and updates mismatch-warning test setup. |
| tests/install-shell.test.ts | Updates expectations so returned tag_name matches the requested version. |
| tests/install-rpm.test.ts | Updates expectations so returned tag_name matches the requested version. |
| tests/install-pkg.test.ts | Updates expectations so returned tag_name matches the requested version. |
| tests/install-msi.test.ts | Updates expectations so returned tag_name matches the requested version. |
| tests/install-apt.test.ts | Updates expectations so returned tag_name matches the requested version. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Elide no longer ships a macOS AMD64 binary; only macos-arm64 is distributed.
…es API Explicit version pins were never resolved via the GitHub API (only `latest` was), so nightly/build-metadata tags (e.g. `1.4.1+20260716`) were passed straight through to the CDN, which doesn't reliably publish artifacts at that exact revision string and 404s. Add `resolveVersionByTag`, scoped to tags matching the existing nightly/build-metadata regexes, which looks up the release by tag and prefers a matching GitHub release asset over the CDN URL, falling back gracefully (never throwing) on any lookup failure. The GitHub API call is deferred until a tool-cache miss is confirmed, and `buildDownloadUrl` now tries multiple archive extensions against the release's assets instead of committing to one and missing a real asset published in a different format. Tightened `BUILD_META_TAG_RE` to require a semver-shaped prefix so arbitrary `+`-containing pins don't trigger this path.
… timing - BUILD_META_TAG_RE now also restricts the build segment to valid semver identifiers (dot-separated alphanumerics/hyphens), not any characters. Previously a tag like "1.0.0+foo_bar" would match and toSemverCacheKey would emit "1.0.0-build.foo_bar" — itself not valid semver (underscore), defeating the point of the conversion. - resolveVersionByTag's retry tests were sleeping for real between attempts (1s-3s). Added a small setTimeout override so the retry path is exercised without the wall-clock delay.
Summary
toSemverCacheKeynow converts build-metadata tags (1.4.0+20260707→1.4.0-build.20260707) so the prerelease segment survivessemver.clean()inside@actions/tool-cache. Previously, all1.4.0+<anything>builds collapsed to the same1.4.0cache slot.versionMatchesTag(ver, tag)which accepts the binary's self-reported version if it is the tag with a.{commithash}suffix appended — the format elide uses. Replaces two exact-string comparisons that always failed for build-metadata tags.release.version.tag_nameto the binary's ownobtainVersion()output, so the post-install mismatch check was comparing a value against itself and could never fire. They now settag_nameto the requested version (options.version), and the check skips when the version is the symbolic value'latest'.version: latestwas) — they were passed straight through to the CDN URL, which doesn't reliably publish artifacts at nightly/build-metadata revision strings (e.g.1.4.1+20260716) and 404s. AddedresolveVersionByTag, scoped to tags matching the existing nightly/build-metadata regexes, which looks up the release by tag and prefers a matching GitHub release asset over the CDN URL — falling back gracefully (never throwing) on any lookup failure. The API call is deferred until a tool-cache miss is confirmed, andbuildDownloadUrlnow tries multiple archive extensions against the release's assets instead of committing to one and missing a real asset published in a different format. Plain semver pins are unaffected — this only applies to nightly/build-metadata-shaped tags.macos-amd64test matrix entry — Elide no longer ships a macOS AMD64 binary; onlymacos-arm64is distributed.