Skip to content

Name the version under development, and stop stamping 0.1.3.0 - #807

Merged
Rafael-SOWNet merged 1 commit into
masterfrom
chore/version-fields
Aug 8, 2026
Merged

Name the version under development, and stop stamping 0.1.3.0#807
Rafael-SOWNet merged 1 commit into
masterfrom
chore/version-fields

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Collaborator

Three version fields disagreed with each other and with what actually shipped.

What was wrong

where said should have said
Sources/Package.Build.props 1.4.0-preview.4 1.4.0 was released in January
Sources/AngouriMath/AngouriMath.csproj AssemblyVersion / FileVersion = 0.1.3.0 a number from long before 1.4

Nothing published was wrong — Nuget.yml packs with -p:PackageVersion taken from the release tag, so NuGet has always been named by the tag. But a local build and the assembly metadata carried these.

Worse, they disagreed with each other. The csproj override sits after the Package.Build.props import, so it won: AngouriMath.dll reported 0.1.3.0 while AngouriMath.FSharp.dll, which has no override, reported 1.4.0.0. Four packages built from one repository did not agree on their own version.

Now

The props carry it for all four packable projects, and the csproj override is gone:

Version           2.0.0-preview.1
AssemblyVersion   2.0.0.0
FileVersion       2.0.0.0

Measured on the built assembly rather than read off the diff:

AssemblyVersion   2.0.0.0
FileVersion       2.0.0.0
Informational     2.0.0-preview.1+21f0d16f
PublicKeyToken    bccdab90849ccf86     <- unchanged

Why AssemblyVersion is pinned, and does not track Version

The assembly is strong-named (SignAssembly, key.snk). For a signed assembly, every AssemblyVersion change breaks binding on any consumer that does not add a redirect. Holding it at 2.0.0.0 for the whole of 2.x makes each 2.x release a drop-in replacement; FileVersion and the informational version carry the actual release.

Why 2.0 and not 1.5

The changes since 1.4.0 include ones no minor version may carry:

  • Minusf.Minuend / .Subtrahend exchanged names — code using them still compiles and now means the other operand
  • Compile over a missing variable throws UncompilableNodeException where it threw KeyNotFoundException
  • mod, floor and ten other names that used to parse as products now raise

BREAKING-CHANGES.md's section is renamed to the version it will ship as, and still says unreleased — more is landing before the release.

Not included, on purpose

AngouriMath.CPP.Exporting references PackageReference AngouriMath 1.4.0-preview.2 — it builds the C++ bindings against a published package rather than the source beside it, and CPPBuild/CPPTest run on that. I verified it builds clean against a ProjectReference, but that changes what code is compiled and tested rather than just metadata, so it belongs in its own PR where CPPTest can adjudicate it. Raised separately.

Verification

5551 unit tests, 130 F# tests pass. All four packable projects build (AngouriMath, .FSharp, .Interactive, .Terminal).

🤖 Generated with Claude Code

Three fields disagreed with each other and with what shipped.

`Package.Build.props` still said `1.4.0-preview.4` although 1.4.0 was
released in January. Nothing published was wrong -- the NuGet workflow packs
with `-p:PackageVersion` taken from the release tag -- but a local build and
the assembly metadata carried the preview.

`AngouriMath.csproj` then overrode `AssemblyVersion` and `FileVersion` with
`0.1.3.0`, a number from long before 1.4. Because the override sat after the
props import it won, so `AngouriMath.dll` reported `0.1.3.0` while
`AngouriMath.FSharp.dll`, which has no override, reported `1.4.0.0`. The four
packages built from one repository did not agree on their own version.

Now the props carry it for all four:

    Version           2.0.0-preview.1
    AssemblyVersion   2.0.0.0
    FileVersion       2.0.0.0

Measured on the built assembly rather than read off the diff:

    AssemblyVersion   2.0.0.0
    FileVersion       2.0.0.0
    Informational     2.0.0-preview.1+21f0d16f
    PublicKeyToken    bccdab90849ccf86   (unchanged)

`AssemblyVersion` is pinned to the major for the whole of 2.x and deliberately
does not track `Version`. The assembly is strong-named, and for a signed
assembly every `AssemblyVersion` change breaks binding on a consumer that does
not add a redirect. Holding it at `2.0.0.0` makes each 2.x release a drop-in
replacement, and `FileVersion` carries the release for anyone reading the file
properties.

2.0 rather than 1.5 because the changes since 1.4.0 include ones no minor
version may carry: `Minusf.Minuend` and `.Subtrahend` exchanged names, so code
using them still compiles and now means the other operand; `Compile` over a
missing variable throws `UncompilableNodeException` where it threw
`KeyNotFoundException`; and `mod`, `floor` and ten other names that used to
parse as products now raise. BREAKING-CHANGES.md names the section for the
version it will ship as, and keeps saying it is unreleased.

5551 unit tests and 130 F# tests pass; all four packable projects build.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Rafael-SOWNet
Rafael-SOWNet merged commit eae262e into master Aug 8, 2026
25 checks passed
@Rafael-SOWNet
Rafael-SOWNet deleted the chore/version-fields branch August 8, 2026 12:27
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