Skip to content

Release 3.10.0: version, changelog, archive - #5548

Merged
erikdarlingdata merged 2 commits into
devfrom
release/v3.10.0
Oct 8, 2026
Merged

erikdarlingdata merged 2 commits into
devfrom
release/v3.10.0

Conversation

@erikdarlingdata

@erikdarlingdata erikdarlingdata commented Oct 8, 2026 •

Copy link
Copy Markdown
Owner

Release checklist steps 1, 2, 2a and 4 for 3.10.0, on the dev side only. No dev to main PR, no tag, no GitHub release, nothing on main.

The splice covers every PR merged to dev through #5536 (merged 2026-10-08 08:05Z, dev 25983b8). PRs that land after this cut (#5528, #5532, #5537, #5543, #5540, the #5457 fix and the foreground-thread test fix) go in a follow-up splice PR. #5491 and #5545 have no entry by design.

What the seat's rulings changed (fix round 1)

Every change below is before -> after. The prose now lives in docs/changelog/3.10.md; CHANGELOG.md holds the compacted index, regenerated by split. The two new link definitions this needed ([#5052], [#5427]) are in CHANGELOG.md.

  1. Add the FinOps Database Resources tab to the web viewer (#4843) #5041 (Added). Before: the entry ended with the bracketed note [#5064 dev bea647e62 folded in: ...] and carried only ([#5041]). After: the note is gone and the refs read ([#5041], [#5064]). The window picker wording was already in the entry text.
  2. Custom view panels say a silent store's open timed out, whatever the driver wraps the timeout in, and the open-timeout test names the exception chain when it fails #5052 folded into Custom view panels say "could not get a store connection in time" for every way the driver reports a timed-out open, and three store tests stop flaking or name their cause #5016 (Fixed). Before: Custom view panels say a silent store's open timed out, whatever the driver wraps the timeout in, and the open-timeout test names the exception chain when it fails #5052 had no line. After: Custom view panels say "could not get a store connection in time" for every way the driver reports a timed-out open, and three store tests stop flaking or name their cause #5016's refs read ([#5016], [#5052]) and the entry gains one sentence, checked against Custom view panels say a silent store's open timed out, whatever the driver wraps the timeout in, and the open-timeout test names the exception chain when it fails #5052's diff (PostgresOpenTimeout.IsTimedOutByClock, ClockSlack of 100 ms): a failure that arrives at or after the connection's timeout, less 100 ms, with no server answer and the caller still waiting, is also reported as "could not get a store connection in time"; a failure the server answered keeps its own message. Custom view panels say a silent store's open timed out, whatever the driver wraps the timeout in, and the open-timeout test names the exception chain when it fails #5052's other change, the fix for a flaky Windows CI test, is not product behavior and is not in the entry.
  3. The 28 buffer instructions. Each was read in the buffer and applied as follows.
  4. Entry shapes. Web viewer: the server page's Range stops at 7 days, the widest window its reads serve #4946, Lite and Darling MCP tools refuse a fraction for a whole-number parameter, such as hours_back: 0.5, with a message that names it #4945, Darling Viewer: the Recommendations and FinOps pickers keep their servers when the server list reloads #4947, On Azure SQL Database, the long-query trace runs only in monitored databases and no longer drops a session another registration still uses #4944, Dependencies: SqlClient 7.1.1, Velopack 1.2.161 and two AWS SDK updates #4963 and collection_log compression: segment by collector as well as by server #4951 now read **Title** ([#N]) - text; the first sentence after the ref was reworded only enough to follow a dash (for example ([#4946]), the longest window nearly every panel reads became ([#4946]) - It is the longest window nearly every panel reads). collection_log compression: segment by collector as well as by server #4951 split its bold sentence: the title is "Darling compresses new collection_log chunks by collector as well as by server" and the dash text is "Reading one collector decompresses only its own runs." A second PagerDuty recovery inside the alert cooldown now resolves the incident (#5469) #5470 is ([#5470], [#5469]). Lite: Collection Log, System Events, Config Changes and Long Queries say where the data starts, and Duration Trends draws the whole range (#4966, group C) #4989 is ([#4989], [#4966]) (inside the data-start fold). WEB: the web server page's grids say where their data starts (part of #4966) #5000 is ([#5000]) - ... (inside the fold). collection_log compression: segment by collector as well as by server #4951 keeps its issue-keyed ref.
  5. The Darling viewer's procedure comparison, the two comparison twins and Query Store top text lookups get a time bound (#5420) #5427 (Fixed), new entry: "The Darling viewer's procedure comparison, its two comparison twins and the Query Store top reads look up statement text inside a time bound" ([#5427]). Checked against the PR body and its diff: the text lookup is bounded to the current and baseline ranges, the period joins use plain equalities, a NULL key and an empty key no longer merge in the outer join, the Query Store inline-text fallback is bounded in the viewer and the MCP reader, and Lite is unchanged. The numbers are the PR's rig table (procedure comparison, 15 days seeded): 24 h, 12.5-30.5 s before and 0.23-0.28 s after; 7 d, 24.4-27.5 s before and 1.6-3.1 s after. It also says a procedure whose only captured text is older than the window now shows no text, as the PR documents.
  6. Upgrade ladder fixture. Darling/Darling.Tests/Fixtures/migration-ladder-v3.9.0.sql is new: generated from a git worktree of tag v3.9.0 with Darling/tools/generate-ladder-fixture and -p:StorageProject= pointing at that worktree's storage project (156 rungs, top V157, which is the 3.9.0 SchemaVersion). The worktree is removed. MigrationUpgradeLadderLiveTests ran against a throwaway PostgreSQL (stopped and deleted after): Total 7, Failed 0.

Counts after the rulings: 257 index lines for 257 archived entries in 3.10.0 (before: 275). 275 - 4 (snapshot-time fold) - 15 (data-start fold: 16 lines into 1) + 1 (#5427) = 257. The splice covers 255 buffer PRs plus #5255, #5259 and #5427; #5052 is now inside #5016. The accounting table below still reads "No record anywhere: 1"; that PR is #5427 and it now has an entry.

Why

The 3.10.0 release needs its version, its changelog entry and its archive, and a clean rebuild.

What changes

  • Step 1: <Version>3.10.0</Version> in Directory.Build.props, that line only. The only other 3.9.0 strings in the tree are project-version ranges inside the packages.lock.json files and a comment in MigrationDataMovingRungCensusPins.cs. The 3.9.0 release left the lock files alone too, and the rebuild below restored and built cleanly.
  • Step 2: CHANGELOG.md gets ## [3.10.0] - 2026-10-08 under an empty ## [Unreleased], with Important, Added, Changed and Fixed in that order. One script, kept outside the repo, wrote it. It strips dev <sha> (<bookkeeping>): with a balanced-parenthesis match and keeps the rest of each entry as it was. It adds ([#N]) after the title only where the entry had none. Entries stay in buffer order. 264 reference links are added at the bottom, in ascending order, for every [#N] the new block uses that had no definition.
  • Step 2a: split moved the prose to the new docs/changelog/3.10.md and compacted the index. tools/changelog/archive-census.txt gains the 3.10.0 row (275 entries at the first write, 257 after the rulings).
  • Important: one entry, "Upgrading from 3.9 runs the Darling store migrations V158 through V170 on the service's first start" (SchemaVersion is 170 at this cut, StorageVersion.cs:19). I read every migration in the range (PgMigrations.cs:1071-1083, the SQL at lines 347-880). None rewrites a large table or needs an offline window. Ten create new tables that start empty (V158, V160 to V165, V167, V168, V170). V159 adds two nullable columns to the one-row install id table (PgMigrations.cs:378). V166 adds a boolean with a constant default to config.config_notification (:688), which PostgreSQL 11 and later does without a rewrite. V168 adds a trigger to collect.query_store_interval_latest (:815), a short lock and no rewrite. Two touch existing rows, both in small config tables. V167 copies one row per saved old-format password out of the server list (LegacyPinCandidateTables.cs:78). V169 adds columns and a check constraint to config.config_monitored_servers (:847), one row per configured server. The data-moving census in MigrationDataMovingRungCensusPins.cs:222 declares V169 as the only data-moving rung in this range. The entry says so, and says no maintenance window is needed.
  • No other Important item. I scanned the entries for anything an operator must do after upgrading. The installer's new .NET Runtime 10 check (The Darling installer refuses an install when the .NET Runtime 10 is missing (#5407) #5409) is a prerequisite, not a post-upgrade action. The password pin steps (The first start after the schema 165 upgrade takes the legacy password pins before it reads the server list, so saved passwords keep working #5456, Tighten the password pin step after the schema 165 upgrade #5466) run on their own.

Entry-line proof (step 2d), as first written, before the rulings above

The table compares the house-style lines before the write (the buffer plus two PR-body entries) with the lines read back from CHANGELOG.md on disk. Each row has the SHA-256 of the sorted lines.

Section Lines SHA-256 of sorted lines Before equals after
Added 106 72aa9a9fd24185389914bfc2d96c463c171a7cfa7ceb933509e08f8647bf6742 yes
Changed 37 f903cc5c17ace408caf04f3f728870d2237e68a19bd100558c63be310a39cb0e yes
Fixed 131 328ee0d1594e6bd3ec9b5164b3a465b9254d950e4c256c119fd9bb06aec3880c yes
All three 274 cb98945cbfb38f2222fa531c3e76e6fde94025852319db1741cb53b2d766b327 yes

The script also asserts that every older line of the file is unchanged (only the new block and the appended links differ). The working tree is CRLF and the blob is LF, as .gitattributes makes it. After the write, CR and LF counts are equal in CHANGELOG.md (5145 each), docs/changelog/3.10.md (558) and archive-census.txt (23).

Accounting (347 PRs merged to dev since the v3.9.0 tag at 2026-10-02T11:46:18Z)

Source of the record PRs
Buffer entry in Added, Changed or Fixed 255
Buffer entry folded into another PR's entry (#4959, #4969, #4986, #5007, #5064) 5
Buffer None line 60
Splice log line only 23
PR body only, section None (#5254) 1
PR body entry not in the buffer, spliced here (#5255, #5259, both Added) 2
No record at the cut; ruling 5 wrote its entry (#5427) 1
Total 347

At the cut, #5427 had no record: it was not in the buffer, the splice log, or its own body (no SECTION or ENTRY line). Ruling 5 added its Fixed entry, written from its PR body and checked against its diff.

Of the 255, one is #5052, which ruling 2 folded into #5016's entry. The buffer holds 273 entry lines for those PRs, since a few carry two or three. Minus the excluded line and plus the two PR-body entries, that is the 274 lines of the first write in the proof below.

Test plan

  • python tools/changelog/changelog_archive.py split exits 0 (last line: wrote 12 files), then census exits 0 (last line: wrote tools/changelog/archive-census.txt), after the rulings above.
  • verify exits 0 with no FAIL. The 3.10.0 rows read 257 index lines for 257 archived entries and 257 entries, prose sha256 a4ad534519744df0 matches tools/changelog/archive-census.txt.
  • roundtrip exits 0 (last line: NOT the whole document: the index has moved on since then, so this is the durable half of the claim rather than the byte comparison; the line before it reads PROSE INTACT every version 3653e8d63a08 held is byte-identical in prose, and every link definition still resolves).
  • Byte census after the writes: CHANGELOG.md 5129 CRLF and 5129 LF, docs/changelog/3.10.md 563 and 563, archive-census.txt 23 and 23, no bare CR. git ls-files --eol shows the index blobs as LF for all three.
  • dotnet build of Darling.Tests and Lite.Tests: 0 Warning(s), 0 Error(s).
  • Darling.Tests ChangelogIndexAndArchiveTests: Total 5, Failed 0.
  • Darling.Tests ProductVersionDeclarationTests: Total 26, Failed 0.
  • Darling.Tests ReleaseStatementGateWorkflowTests: Total 4, Failed 0.
  • Darling.Tests MigrationUpgradeLadderLiveTests on a throwaway PostgreSQL 18 rig with TimescaleDB: Total 7, Failed 0, Skipped 0.
  • Darling.Tests -trait Stage=Guard -failSkips: Total 1387, Failed 0, Skipped 0.
  • Darling.Tests *Census*: Total 462, Failed 0, Skipped 1. *Ratchet*: Total 15, Failed 0.
  • Lite.Tests -trait Stage=Guard -failSkips: Total 429, Failed 0, Skipped 0.
  • Full suites not run on this laptop. CI decides.
  • The earlier DARLING_RELEASE_CUT=1 ... StatementCensus_PendingEntries_BlockARelease run was not repeated; no statement-census input changed in this round.

Version 3.9.0 to 3.10.0 in Directory.Build.props. The pending entries are spliced into CHANGELOG.md as [3.10.0] - 2026-10-08 with an Important entry for store migrations V158 through V170, then archived to docs/changelog/3.10.md with a regenerated census.
@erikdarlingdata
erikdarlingdata marked this pull request as ready for review October 8, 2026 08:43
@erikdarlingdata
erikdarlingdata merged commit e954913 into dev Oct 8, 2026
27 of 38 checks passed
@erikdarlingdata
erikdarlingdata deleted the release/v3.10.0 branch October 8, 2026 09:05
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