Skip to content

feat: follow stable releases and parameterise the native build - #3

Merged
jcant0n merged 10 commits into
mainfrom
feat/stable-release-tracking
Aug 3, 2026
Merged

feat: follow stable releases and parameterise the native build#3
jcant0n merged 10 commits into
mainfrom
feat/stable-release-tracking

Conversation

@jcant0n

@jcant0n jcant0n commented Aug 3, 2026

Copy link
Copy Markdown
Member

Phases 1 and 2 of moving Meshoptimizer.NET onto tracked stable releases. No version bump yet — this only makes the machinery capable and the manifest truthful.

Verification of the native toolchain (rebuilding v1.0 and comparing exported symbols against the committed binaries) runs before this merges.

🤖 Generated with Claude Code

jcant0n and others added 8 commits August 3, 2026 09:14
The manifest moves from `ref: master` to release tracking on `stable`, recording
v1.0 as what is vendored. `master` was a hazard sitting there unarmed: had the
tracked CD been active it would have fetched the 1.2 header and left the 1.0
binaries in place.

meshopt-cmake.yml becomes callable with a `ref`, instead of carrying v1.0 in a
hardcoded line that had already drifted from the manifest and the README. Each
platform now stages its library directly into the runtimes layout the package
expects, so the CD can unpack every artifact over the project directory with no
mapping table anywhere.

It also records the exported symbols per platform. A rebuild is never
byte-identical -- different compiler, different date -- so comparing bytes proves
nothing; comparing the exported symbol set is what shows the toolchain still
produces an equivalent library.
Scraping dumpbin's output reported the DLL's own name and fragments of decorated
C++ names as exported symbols, so a comparison that was in fact clean showed two
differences per Windows platform. A comparator that cries wolf is worse than none
when the thing it guards is a silent runtime break.
Replaces binding-simple-cd, which published whatever was already in the tree
without ever looking upstream, and had no schedule at all.

Three jobs, because the halves cannot share a runner: the native libraries need
a matrix across three operating systems, the generator and packaging need one
machine holding the whole tree. `resolve` runs first and alone so exactly one
place decides which revision the run is about -- if the header and the binaries
each worked it out separately, a release published midway through would leave
them on different versions, and that mismatch is the invisible kind.

Monthly, in step with the rest of the fleet.
…annot

Two faults that hid each other.

The output path was a fixed climb of five directories, which is only correct
when the generator is published without a runtime identifier. CI and CD pass
linux-x64, adding a level, so every automated run wrote its bindings into
MeshOptimizerGen/MeshOptimizerGen/Evergine.Bindings.MeshOptimizer/Generated --
a directory no build reads. The checked-in bindings have therefore only ever
changed when a human ran the generator locally. That the published v1.0 package
works is not evidence against this: it was generated by hand, on Windows,
without a runtime identifier, and it was correct for v1.0.

Now it searches upward for the project by name, so how deep the build output
sits stops being something this file has to know.

Parse failures went to Debug.WriteLine, which compiles to nothing in Release,
and the process still returned 0. A header the generator could not read produced
no output, no message and no error. They now go to stderr with a non-zero exit.

Seven of the ten bindings pass a non-empty runtime-identifier, so this pattern is
worth checking in the others -- RenderDoc.NET especially, which regenerates on a
schedule.
The CppAst generator cannot read meshoptimizer.h on Linux. The libclang shipped
in the NuGet package carries no system include paths and none of its own builtin
headers, so <assert.h> and <stddef.h> do not resolve and the parse aborts before
any binding is produced -- previously in silence, since the diagnostics went to
Debug.WriteLine and the process still exited 0.

RenderDoc.NET and KTX.NET already generate on Windows for the same reason. This
does not constrain the package: the five native libraries are built in their own
matrix job, and runtime-identifier only feeds the generator's publish, never the
packing -- checked against binding-tracked-cd rather than assumed.

CI moves with CD. A CI that validates on a platform the CD does not use is
checking a build nobody ships.
…quest

Two contracts that a diff of 6,000 generated lines hides. The API gate says which
public symbols a change adds or removes; the coherence check says every P/Invoke
still resolves in all five shipped libraries.

auto-merge stays off. This binding rebuilds five native libraries when it bumps,
and that pipeline has run a handful of times -- measure first.

README follows the manifest to v1.2.
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

API gate: breaking

This removes or changes public symbols. Merging is left to a human — a rename is sometimes the right answer, but never an automatic one.

Target framework Added Removed
net10.0 +21 -1
net10.0 — 1 symbol(s) gone
K Evergine.Bindings.MeshOptimizer.MeshOptimizer.VERSION = 1000

Enum and constant values are part of the measured surface: a renumbering keeps compiling and sends the wrong number to the driver, so it counts as a removal.

@github-actions github-actions Bot added the api:breaking Removes or changes public API symbols label Aug 3, 2026
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

API gate: additive

Every symbol that existed still exists, unchanged. Nothing that compiled before stops compiling.

Target framework Added Removed
net10.0 +20 -0

Enum and constant values are part of the measured surface: a renumbering keeps compiling and sends the wrong number to the driver, so it counts as a removal.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

API gate: additive

Every symbol that existed still exists, unchanged. Nothing that compiled before stops compiling.

Target framework Added Removed
net10.0 +20 -0

Enum and constant values are part of the measured surface: a renumbering keeps compiling and sends the wrong number to the driver, so it counts as a removal.

@github-actions github-actions Bot removed the api:breaking Removes or changes public API symbols label Aug 3, 2026
@jcant0n
jcant0n merged commit 4803764 into main Aug 3, 2026
4 checks passed
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