Skip to content

[repo-assist] Fix inconsistent ~> LOCKEDVERSION twiddle range for short version strings - #4416

Merged
dsyme merged 1 commit into
masterfrom
repo-assist/fix-issue-3727-lockedversion-twiddle-4efcd01db48330e4
Sep 1, 2026
Merged

[repo-assist] Fix inconsistent ~> LOCKEDVERSION twiddle range for short version strings#4416
dsyme merged 1 commit into
masterfrom
repo-assist/fix-issue-3727-lockedversion-twiddle-4efcd01db48330e4

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

🤖 This is an automated response from Repo Assist, an AI assistant.

Closes #3727

Root cause

In paket.template, the bare LOCKEDVERSION/CURRENTVERSION placeholder (with no :Major/:Minor/:Patch/:Build spec) substituted the raw, un-normalized locked version text (e.g. "0.68") verbatim into the dependency line, instead of a normalized Major.Minor.Patch form.

That raw text then feeds into the ~> (twiddle) operator parser, which infers which segment to bump based on how many numeric fragments are present in the text (DependenciesFileParser.twiddle). As a result:

  • Locked version 0.68 (2 segments) → ~> LOCKEDVERSION produced [0.68, 1.0.0)
  • Locked version 0.68.1 (3 segments) → ~> LOCKEDVERSION produced [0.68.1, 0.69.0)

Both represent "the same" minor version conceptually, but yielded very different (and for the 2-segment case, unintended) upper bounds — exactly the inconsistency reported in #3727.

Fix

In TemplateFile.fs, when no explicit segment spec is given, the substituted version text is now padded to at least 3 segments (Major.Minor.Patch), preserving any pre-release/build suffix from the original source text. This makes ~> LOCKEDVERSION (and similar unspecced placeholders) behave consistently regardless of how many segments the locked version happens to have in paket.lock.

This only affects the no-spec case (segmentCount = 0); explicit :Major/:Minor/:Patch/:Build specs are unchanged.

Trade-offs

  • This changes behavior for any existing paket.template relying on the old (inconsistent) raw substitution for short (1–2 segment) locked versions combined with ~>. However, the old behavior was a bug with no clear intentional use, so this is considered a bugfix rather than a breaking change.
  • Exact-match (Specific) substitution behavior for bare LOCKEDVERSION (without ~>) was already normalizing 2-segment versions to 3 segments in existing tests (e.g. "1.2""1.2.0"), so this fix is consistent with, and does not change, that existing behavior.

Test Status

  • dotnet test tests/Paket.Tests/Paket.Tests.fsproj --filter "FullyQualifiedName~TemplateFile" (net9.0): 104/104 passed (including 3 new regression test cases added for this fix).
  • dotnet test tests/Paket.Tests/Paket.Tests.fsproj --filter "FullyQualifiedName~Version|FullyQualifiedName~Template|FullyQualifiedName~Twiddle" (net9.0): 294/294 passed.
  • net461 test target could not run in this sandbox (missing Mono host) — this is an environment limitation, not a code issue; net9.0 results are the reliable signal here.

AI Disclosure

This PR was authored autonomously by Repo Assist, an automated AI assistant for this repository. Please review carefully before merging.

Generated by 🌈 Repo Assist, see workflow run. Learn more.
Comment /repo-assist to run again

Add this agentic workflow to your repo

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@ae8d551f07c7ed7619f8c58c7bb4c3ac89395d38

…ings (#3727)

The bare LOCKEDVERSION/CURRENTVERSION placeholder substituted the raw,
un-normalized locked version text (e.g. "0.68") instead of a
normalized Major.Minor.Patch form. Since the ~> twiddle operator
infers which segment to bump from the number of numeric fragments in
the version text, a 2-segment locked version (e.g. "0.68") produced a
different (and unintended) upper bound than a 3-segment version (e.g.
"0.68.1"), even though both represent the same logical minor version.

Normalize the substituted version to at least 3 segments
(Major.Minor.Patch), preserving any pre-release/build suffix, so
~> LOCKEDVERSION behaves consistently regardless of how many segments
appear in paket.lock.

Added a regression test covering 2-segment, 3-segment (explicit
patch=0), and 3-segment (non-zero patch) locked versions with
~> LOCKEDVERSION, verifying they all now produce the same kind of
twiddle range.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dsyme
dsyme marked this pull request as ready for review August 30, 2026 20:53
@dsyme
dsyme merged commit 7c2d103 into master Sep 1, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

paket.template dependency ~> LOCKEDVERSION gives inconsistent behaviour for x.y.0 versions

1 participant