release: v1.0.0#11
Conversation
Executes the v1.0 release-PR checklist from docs/roadmap.md verbatim:
1. PublicAPI flip — moved all 380 entries from
src/NetXlsx/PublicAPI.Unshipped.txt into PublicAPI.Shipped.txt.
Unshipped reset to just the `#nullable enable` header. Any
post-v1.0 surface addition now goes through the standard
Unshipped-then-Shipped-at-next-tag flow.
2. PublicApiSnapshotTests baseline — unchanged (the test is
TFM-invariant; it asserts the public type list and was already
in sync with the Unshipped entries).
3. net9.0 drop per decision I24. After 2026-05-12 STS EOS,
net9.0 leaves the TargetFrameworks list:
- Directory.Build.props: net8.0;net9.0;net10.0 -> net8.0;net10.0
- .github/workflows/{ci,release,bench}.yml: removed 9.0.x from
setup-dotnet matrices
- docs/design.md decision #12 updated
Consumers on net9.0 install the net8.0 build via the standard
TFM fallback — no API change.
4. CHANGELOG v1.0.0 entry with explicit BREAKING CHANGES banner
covering the net9.0 drop, plus a Highlights section
summarizing what shipped (style-pool dedup, source-gen typed
mapping, type-level streaming split, OPC preservation
guarantee, build-time AOT/trim guard, MissingFontException).
Slice-by-slice history retained below the highlights.
5. Stale-count sweep — README's "434 tests/TFM × 3 TFMs = 1,302"
updated to "434 × 2 = 868" post-drop. TFM mention in the
README intro updated to "net8.0 and net10.0 (both LTS)".
6. All three v1.0 ship-blockers confirmed landed in main before
this PR: headless-no-fonts CI gate (66e4f4d), benchmark
regression CI gate (97b981f), full preservation fixture
(4dfb001).
Validation: 868 test runs (434/TFM x 2 TFMs) green locally on
net8.0 + net10.0. Build clean, 0 warnings, 0 errors.
Note before tag: NUGET_API_KEY secret is not yet set in repo
settings. The release workflow has a graceful skip path
(uploads .nupkg artifacts to the workflow run, creates the GH
Release, but does not push to nuget.org). If we want v1.0.0
to publish synchronously with the tag, set NUGET_API_KEY first.
|
Bench-gate override — both initial run and re-run flagged Root-cause analysis: this PR's diff is zero runtime code. The src/ changes are:
The bench workflow's cache key includes This is a real flaw in the bench cache strategy — the Merging with admin override. Documented for the audit trail. |
Implements SetAutoFilter / ClearAutoFilter / SetAutoFilterColumn / ClearAutoFilterColumn / HasAutoFilter / AutoFilterRange on the SDK engine (new OoxmlSheet.AutoFilter.cs), per decisions I-56 + I-66. <autoFilter> is a 0..1 singleton in CT_Worksheet's strict sequence, so the insert routes through OoxmlSchemaOrder.GetOrInsert (SDK-quirk #8). Per-column criteria emit <filterColumn colId><customFilters [and]> with 1-2 <customFilter operator val> conditions, inserted before any trailing sortState/extLst an opened file may carry. Oracle-checked against the NPOI engine's emitted XML (quirk #11 habit): SetAutoFilter also creates/updates Excel's hidden built-in _xlnm._FilterDatabase defined name (new internal OoxmlWorkbook.SetFilterDatabaseName — bypasses user-name validation and the uniqueness rule, since built-in names repeat per localSheetId); the refers-to keeps the r1:r2 form with no 1x1 collapse and quotes the sheet name when needed. Re-setting the range keeps existing filterColumn entries; ClearAutoFilter leaves the stale name in place. NPOI's showButton="1" is the OOXML default and is deliberately omitted. Conformance: AutoFilterTests mirrors the NPOI-engine suite + the oracle-pinned name/replace semantics; schema-gate fixtures incl. the required open-mutate case (autoFilter inserts before an existing mergeCells); cross-engine differential scenarios (filter state + _FilterDatabase name, cleared state); and a corrupt @ref malformed- input parity check (SDK-quirk #13 diligence).
Implements ISheet.AddChart (all six ChartTypes) + IChart (Sheet/Type/ SetTitle) on the SDK engine: a ChartPart hung off the sheet's DrawingsPart, referenced from an xdr:graphicFrame in a twoCellAnchor with the exclusive end-cell convention (quirk #10 checked against the NPOI oracle, not assumed). strCache/numCache snapshot the referenced cells at AddChart time with NPOI's skip semantics (ptCount = full range; only type-matching cells get a pt). The chart XML was oracle-dumped from the NPOI engine for all six types before implementing (quirk #11). Documented conformance-positive divergences (quirk #14): pie dPt list in CT_PieSer schema order (NPOI emits it after val), no dangling pie axes, scatter plotted on two value axes (NPOI pairs a catAx), nonzero cNvPr ids (NPOI emits id=0), editAs omitted (schema default). IChart.Underlying (NPOI XSSFChart) throws NotSupportedException on the SDK engine — the established escape-hatch divergence. New ChartTests (33) incl. a cross-engine emission-projection parity test, plus two schema-gate fixtures; all six chart types validate clean under Microsoft365.
v1.0.0 release PR
Executes the v1.0 release-PR checklist from
docs/roadmap.md.Checklist
Unshipped.txt→Shipped.txtinsrc/NetXlsx/. Unshipped reset to header-only.PublicApiSnapshotTestsbaseline — unchanged (TFM-invariant; was already in sync).Directory.Build.props, CI workflows,docs/design.mddecision Bump the test-stack group with 1 update #12.[1.0.0]entry calls out the net9.0 drop with migration guidance.v1.0.0matches the release workflow'sv*trigger.NUGET_API_KEYsecret — NOT YET SET. If we want v1.0.0 to publish synchronously with the tag, set this in repo Settings → Secrets and variables → Actions before pushing the tag. Otherwise the release workflow skips the NuGet push and just uploads .nupkg artifacts + creates the GH Release.Validation
868 test runs (434 per TFM × 2 TFMs) green locally on net8.0 + net10.0. Build clean, 0 warnings, 0 errors. CI matrix on this PR will verify the same across ubuntu-latest + windows-latest.
After merge
git tag v1.0.0from the merge commit,git push origin v1.0.0.NUGET_API_KEYis set) or uploads artifacts + creates the GH Release without the publish.[Unreleased]slot inCHANGELOG.mdis empty and ready for the next slice.