Summary
The GitHub Packages badge endpoint cannot reliably show the latest CI prerelease when feature-branch prereleases also exist for the same package/base version.
For localstack-dotnet/LocalStack.Aspire.Hosting, the latest CI package in GitHub Packages is currently 13.4.0-ci.82, but the default badge endpoint returns 13.4.0-feature-ws2-dynamodb-streams-squashed.79:
https://api.localstackfor.net/badges/packages/github/localstack-dotnet/LocalStack.Aspire.Hosting?prerelease=true
Current behavior
The endpoint returns:
{"schemaVersion":1,"label":"github","message":"13.4.0-feature-ws2-dynamodb-streams-squashed.79","color":"orange","namedLogo":"github"}
A narrow exact-version range can force the expected CI version:
https://api.localstackfor.net/badges/packages/github/localstack-dotnet/LocalStack.Aspire.Hosting?prerelease=true&version=%5B13.4.0-ci%2C13.4.0-ci.zzzz%5D
That returns:
{"schemaVersion":1,"label":"github","message":"13.4.0-ci.82","color":"orange","namedLogo":"github"}
But this is too fragile for README badges because it bakes in the current base version (13.4.0) and will break or go stale when the package moves to 13.4.1, 13.5.0, etc.
Source finding
README.md documents the GitHub Packages endpoint as:
GET /badges/packages/github/{org}/{package}[?version={pattern}&prerelease={bool}]
However, the implementation appears to pass the version query straight into NuGet VersionRange.TryParse:
src/BadgeSmith.Api/Features/GitHub/GithubPackagesBadgeHandler.cs reads version into versionRange.
src/BadgeSmith.Api/Features/GitHub/GitHubPackageService.cs passes versionRange to INuGetVersionService.ParseAndFilterVersions(...).
src/BadgeSmith.Api/Core/Versioning/NuGetVersionService.cs parses with VersionRange.TryParse(...) and then picks the max NuGetVersion.
So the documented pattern behavior is not actually available for GitHub Packages today.
Repro attempts
These do not select only -ci.* prereleases and still return the feature prerelease:
?prerelease=true&version=*-ci.*
?prerelease=true&version=%2A-ci.%2A
?prerelease=true&version=13.4.0-ci.*
?prerelease=true&version=13.4.*-ci.*
?prerelease=true&version=%5B13.0.0-ci%2C14.0.0-ci%29
Expected behavior
There should be a non-version-pinned way to request the latest CI prerelease, for example one of:
?prerelease=true&prereleaseLabel=ci
?prerelease=true&prereleasePrefix=ci
?prerelease=true&versionPattern=*-ci.*
The endpoint should then return the latest package whose normalized NuGet prerelease label starts with or equals ci, e.g. 13.4.0-ci.82 for the current package state.
Suggested fix
Add a first-class prerelease-label/prefix filter before max-version selection, and update the docs so version is clearly a NuGet VersionRange unless pattern matching is actually implemented.
Potential acceptance criteria:
- GitHub Packages badge supports selecting latest
ci prerelease without hardcoding the base version.
- Feature branch prereleases such as
feature-ws2-dynamodb-streams-squashed.79 do not win when the caller asks for ci prereleases.
- Existing
version range behavior remains backward compatible.
- README endpoint documentation matches the implemented query semantics.
Summary
The GitHub Packages badge endpoint cannot reliably show the latest CI prerelease when feature-branch prereleases also exist for the same package/base version.
For
localstack-dotnet/LocalStack.Aspire.Hosting, the latest CI package in GitHub Packages is currently13.4.0-ci.82, but the default badge endpoint returns13.4.0-feature-ws2-dynamodb-streams-squashed.79:Current behavior
The endpoint returns:
{"schemaVersion":1,"label":"github","message":"13.4.0-feature-ws2-dynamodb-streams-squashed.79","color":"orange","namedLogo":"github"}A narrow exact-version range can force the expected CI version:
That returns:
{"schemaVersion":1,"label":"github","message":"13.4.0-ci.82","color":"orange","namedLogo":"github"}But this is too fragile for README badges because it bakes in the current base version (
13.4.0) and will break or go stale when the package moves to13.4.1,13.5.0, etc.Source finding
README.mddocuments the GitHub Packages endpoint as:However, the implementation appears to pass the
versionquery straight into NuGetVersionRange.TryParse:src/BadgeSmith.Api/Features/GitHub/GithubPackagesBadgeHandler.csreadsversionintoversionRange.src/BadgeSmith.Api/Features/GitHub/GitHubPackageService.cspassesversionRangetoINuGetVersionService.ParseAndFilterVersions(...).src/BadgeSmith.Api/Core/Versioning/NuGetVersionService.csparses withVersionRange.TryParse(...)and then picks the maxNuGetVersion.So the documented
patternbehavior is not actually available for GitHub Packages today.Repro attempts
These do not select only
-ci.*prereleases and still return the feature prerelease:Expected behavior
There should be a non-version-pinned way to request the latest CI prerelease, for example one of:
The endpoint should then return the latest package whose normalized NuGet prerelease label starts with or equals
ci, e.g.13.4.0-ci.82for the current package state.Suggested fix
Add a first-class prerelease-label/prefix filter before max-version selection, and update the docs so
versionis clearly a NuGet VersionRange unless pattern matching is actually implemented.Potential acceptance criteria:
ciprerelease without hardcoding the base version.feature-ws2-dynamodb-streams-squashed.79do not win when the caller asks forciprereleases.versionrange behavior remains backward compatible.