Skip to content

CI intelligence: restore the classification the dorny v4 bump broke, cancel superseded PR runs, un-trap the nightly, bound the jobs - #1715

Merged
erikdarlingdata merged 7 commits into
devfrom
feature/ci-intelligence
Jul 26, 2026
Merged

CI intelligence: restore the classification the dorny v4 bump broke, cancel superseded PR runs, un-trap the nightly, bound the jobs#1715
erikdarlingdata merged 7 commits into
devfrom
feature/ci-intelligence

Conversation

@erikdarlingdata

Copy link
Copy Markdown
Owner

CI build-time and change-classification intelligence pass. The audit was supposed to find incremental wins; it found a same-day regression that had silently reduced ALL change classification to "markdown-only vs build-everything", fixed it, and validated the fix with per-file probes. Absorbed starting material: #1712 (merged while this was in flight) is the baseline; its two flagged allowlist judgment calls are ratified below.

The headline find: the dorny v4 pin bump broke every path filter (fixed here)

The 2026-07-26 08:02 action-pin bump moved dorny/paths-filter v3 -> v4. v4 evaluates each filter pattern as an INDEPENDENT predicate under its default predicate-quantifier: some - a filter is true when any changed file matches at least one rule - so a bare !**/*.md exclusion line stopped being a subtraction and became its own rule meaning "any file that is not markdown". Receipts, straight from run logs:

The bump could not have caught itself: its own PR touched build.yml, so root=true forced a full build that looked exactly like a correct run, and everything after it over-built, which also looks exactly like a correct run.

The fix keeps v4 (v3 is on the deprecated-runtime track) and removes every bare negation instead:

  • Area filters state the markdown carve-out INSIDE each include as an extglob (Darling/**/!(*.md)), where quantifier semantics cannot detach it.
  • The uninvertible code: filter is replaced by an all: counter; the classify step decides docs-only by all_count == docs_count, and additionally refuses to engage while any area filter is lit (an area build with restore skipped would run dotnet build --no-restore against nothing - the two classifications derive from the same allowlist today, the veto is for the day someone edits one and not the other).
  • check-version-bump.yml had the identical '**'-plus-exclusions shape, so its md-only skip was also silently dead; same counter fix.

Baseline, measured before changing anything

Per-job and per-step timings for the 30 most recent completed build.yml runs (all of them post-bump, so every row below is the BROKEN classification - "full build" rows include PRs that should have been single-area):

  • build job, full path: median ~6m30s (5m55s-7m51s, n=19). Step medians: restore ~25s, Build Lite.Tests ~50s, Build Installer.Tests ~4s, Build Dashboard.Tests ~26s, Build Darling ~27s, Run Lite tests ~2m25s (the dominant step), Run Installer ~3s, Run Dashboard ~5s, Run Darling ~12s.
  • build job, md-only path: 1m27s-1m44s (checkout ~1m is the floor; restore still ran pre-CI: stop charging documentation changes for a .NET restore #1712).
  • darling-pg: 2m38s-3m39s, parallel, never the critical path - but per the bug above, that IS the full-suite cost on every PR; the intended skip path costs ~1m.
  • Queue delay: 2-6s on all 30 runs (no Execute both Availability Group reads against a real Postgres (#991) #1697-style pool contention in this sample).
Full 30-run table
run event title build job queued restore b-lite b-inst b-dash b-darl t-lite t-inst t-dash t-darl darling-pg job
30218595273 pull_request State the rule that decides how a new AG meas 5m55s 0m02s 0m20s 0m43s 0m03s 0m24s 0m21s 2m27s 0m03s 0m04s 0m10s 2m44s
30218556648 push Merge pull request #1709 from erikdarlingdata 1m44s 0m01s 0m24s skip skip skip skip skip skip skip skip 2m51s
30218459544 pull_request AG fixture: state the commit-time conclusion 1m27s 0m03s 0m25s skip skip skip skip skip skip skip skip 2m43s
30218345310 push Merge pull request #1708 from erikdarlingdata 6m14s 0m02s 0m22s 0m53s 0m04s 0m26s 0m28s 2m21s 0m04s 0m05s 0m11s 2m42s
30218083739 pull_request Correct the commit-delta guidance: it fails l 6m58s 0m04s 0m25s 0m56s 0m04s 0m34s 0m29s 2m39s 0m04s 0m05s 0m15s 2m43s
30218069931 pull_request Correct the commit-delta guidance: it fails l 6m10s 0m02s 0m25s 0m50s 0m03s 0m30s 0m27s 2m19s 0m03s 0m05s 0m11s 2m57s
30218053068 push Merge pull request #1707 from erikdarlingdata 1m31s 0m03s 0m23s skip skip skip skip skip skip skip skip 3m00s
30217949894 pull_request AG fixture: land the suspended-row evidence, 1m43s 0m02s 0m24s skip skip skip skip skip skip skip skip 2m46s
30217925712 pull_request AG fixture: land the suspended-row evidence, 1m38s 0m02s 0m26s skip skip skip skip skip skip skip skip 3m26s
30217373778 push Merge pull request #1704 from erikdarlingdata 1m37s 0m02s 0m25s skip skip skip skip skip skip skip skip 3m38s
30217263890 pull_request AG fixture: land the secondary_lag_seconds ev 1m32s 0m02s 0m30s skip skip skip skip skip skip skip skip 3m05s
30217178627 push Merge pull request #1703 from erikdarlingdata 5m58s 0m02s 0m24s 0m50s 0m04s 0m24s 0m28s 2m07s 0m04s 0m06s 0m14s 3m12s
30216944299 pull_request Say what secondary_lag_seconds actually measu 6m26s 0m02s 0m23s 0m54s 0m04s 0m25s 0m26s 2m37s 0m03s 0m05s 0m13s 2m40s
30216868032 push Merge pull request #1702 from erikdarlingdata 6m56s 0m04s 0m24s 0m54s 0m04s 0m25s 0m27s 2m48s 0m03s 0m05s 0m11s 3m04s
30216742664 pull_request Say what secondary_lag_seconds actually measu 6m11s 0m04s 0m25s 0m57s 0m03s 0m27s 0m27s 2m02s 0m03s 0m06s 0m12s 2m42s
30216720883 pull_request Say what secondary_lag_seconds actually measu 6m45s 0m06s 0m33s 1m02s 0m04s 0m32s 0m27s 2m27s 0m04s 0m06s 0m11s 3m39s (failure)
30216627847 pull_request AG suspension semantics: one rule that holds 6m43s 0m04s 0m26s 0m55s 0m04s 0m23s 0m27s 2m39s 0m03s 0m06s 0m13s 2m50s
30216571584 pull_request Say what secondary_lag_seconds actually measu 6m07s 0m02s 0m26s 0m52s 0m03s 0m25s 0m27s 2m20s 0m03s 0m06s 0m11s 2m59s
30216545237 pull_request Say what secondary_lag_seconds actually measu 6m57s 0m02s 0m25s 0m54s 0m04s 0m32s 0m27s 2m51s 0m03s 0m06s 0m11s 2m47s
30216414335 pull_request AG suspension semantics: one rule that holds 7m13s 0m03s 0m26s 0m53s 0m04s 0m30s 0m26s 2m52s 0m03s 0m05s 0m12s 3m13s
30216390743 push Merge pull request #1701 from erikdarlingdata 6m20s 0m02s 0m25s 0m50s 0m03s 0m31s 0m29s 2m23s 0m03s 0m05s 0m11s 2m38s
30216357216 push Merge pull request #1700 from erikdarlingdata 6m36s 0m02s 0m27s 0m47s 0m04s 0m31s 0m26s skip 0m04s 0m05s 0m11s 2m55s
30216286972 push Merge pull request #1699 from erikdarlingdata 6m32s 0m03s 0m23s 0m53s 0m03s 0m24s 0m27s skip 0m03s 0m05s 0m11s 3m11s
30216260901 push Merge pull request #1695 from erikdarlingdata 6m05s 0m02s 0m26s 0m55s 0m04s 0m23s 0m27s skip 0m04s 0m05s 0m13s 2m48s
30216175720 pull_request Collapse CI's Lite fast / analysis-heavy test 6m02s 0m04s 0m23s 0m49s 0m04s 0m26s 0m27s 2m13s 0m03s 0m05s 0m12s 2m56s
30216164639 pull_request Collapse CI's Lite fast / analysis-heavy test 6m03s 0m03s 0m24s 0m48s 0m04s 0m29s 0m25s 2m13s 0m03s 0m05s 0m11s 2m43s
30216118248 pull_request Alert on a suspended secondary that is fallin 6m33s 0m02s 0m26s 0m50s 0m03s 0m31s 0m26s skip 0m03s 0m06s 0m14s 2m51s
30216091111 pull_request Alert on a suspended secondary that is fallin 7m51s 0m02s 0m19s 0m35s 0m03s 0m24s 0m19s skip 0m02s 0m05s 0m14s 3m14s
30216041334 pull_request Darling Web: an "AG Health" seed notebook, an 6m53s 0m02s 0m22s 0m39s 0m03s 0m22s 0m24s skip 0m02s 0m04s 0m09s 2m46s
30215989791 pull_request AG latency: commit-time columns, drain-time e 7m28s 0m03s 0m30s 0m54s 0m03s 0m30s 0m26s skip 0m03s 0m06s 0m14s 3m02s

Caveat: in rows at or before run 30216390743 (#1701's merge), the t-lite column reads "skip" because the Lite test step had different names before #1701 collapsed the fast/analysis split; the suites did run. Collection artifact, not a skip.

What changed, commit by commit

  1. Concurrency groups (build.yml, sql-validation.yml): a PR re-push cancels that PR's superseded in-flight runs. Push and release runs get a UNIQUE per-run group (run_id), so dev/main integration builds and release builds are never queued behind, replaced by, or cancelled through this mechanism - every push commit keeps its own check result. claude-review.yml already had this shape.
  2. Allowlist ratified + tightened (build.yml, check-version-bump.yml): CITATION.cff and Screenshots/ stay documentation (ratifying CI: stop charging documentation changes for a .NET restore #1712's flagged judgment calls - citation metadata and screenshot images cannot affect any build.yml job), but the directory-wide grants become extension-explicit (docs/**/*.{md,svg,png,jpg,jpeg,gif}), so a .sql or script dropped into docs/ tomorrow defaults to CODE - the allowlist's own stated principle. Note: the brief's spec listed THIRD_PARTY_NOTICES.md explicitly; it is covered by **/*.md. check-version-bump.yml now mirrors the same allowlist, so a LICENSE-only dev->main correction is documentation to both gates.
  3. Nightly dispatcher (nightly.yml): see below.
  4. Timeouts on every job that never carries the release/signing path (darling-pg 30, nightly check 10 / build 90 / pg 60 / redispatch 5, sql-validation 30 per matrix leg, claude-review 30). build.yml's build job stays unbounded ON PURPOSE: on release it waits on SignPath's manual approval gate, which can legitimately take hours.
  5. The dorny v4 classification fix described above.
  6. CHANGELOG.

Throwaway validation (PR #1714 - stays open for Stage 3, then closes unmerged)

Stage 1 - proved the regression against dev's shipped workflow. A .gitignore-only diff was supposed to engage the #1712 fast path (~1m45s); instead it paid the full build and the full PG suite (run 30219202642, receipts above).

Stage 2 - proved the fix with a per-file truth table. The fixed build.yml plus three probes was pushed to the same PR: diff = .gitignore (docs), .github/workflows/build.yml (root), Darling/throwaway-probe.txt (darling), Darling/throwaway-probe.md (docs, NOT darling). Filter log from run 30219765613:

Run 30219765613 concluded success (the fixed workflow also passed its own root-triggered full build end to end — concurrency block, classify step, extglob filters, notices, timeouts all live on the runner). The classify step's decision line:

Changed files: 4 total, 2 on the documentation allowlist.
Areas: root=true core=false installer_core=false dashboard=false lite=false installer=false darling=true

docs_count=2 is exactly .gitignore + throwaway-probe.md. Per-file matched list (darling-pg job's darling filter, same pattern family as the build job's):

Filter darling = true
Matching files:
.github/workflows/build.yml [modified]    <- the intended workflow-file literal
Darling/throwaway-probe.txt [added]       <- extglob still matches non-md Darling files

Darling/throwaway-probe.md is absent (the markdown carve-out holds inside the include) and .gitignore is absent (the predicate leak is gone). Compare Stage 1, where .gitignore ALONE made lite, dashboard, and darling all true. Every filter now reads exactly as designed, per file, on the real runner.

Stage 3 - end-to-end fast-path engagement needs a docs-only diff against a dev that already carries this PR's build.yml, so it runs after this merges: #1714's branch gets rebased to the .gitignore-only diff for one final run, expected ~45s-1m (setup + restore + versioning all skipped, notice naming the file), then closed.

Projected effect (attribution, not hand-waving)

  • Single-area PRs stop paying for the other products. From the step table, a Darling-only PR drops from the broken-state ~6m30s to a projected ~3m40s (checkout ~1m + setup ~30s + restore ~25s + Build Darling ~30s + Darling tests ~15s + two Darling publishes ~1m; no Lite build, no 2m25s Lite suite, no Lite publish). Lite-only PRs keep the Lite suite but shed the Darling builds/publishes.
  • darling-pg returns to skipping non-Darling PRs (~1m instead of ~3m), freeing a shared-pool Windows runner ~2 minutes per non-Darling PR - capacity, which is what actually serializes CI here.
  • md-only PRs additionally shed setup+restore via the now-functional fast path (1m30s -> ~45s-1m projected; Stage 3 will measure it).

Nightly: diagnosis and the ONE manual step this PR cannot do

Scheduled run 30194606068 (2026-07-26 06:00 UTC) failed in Set nightly version: scheduled workflows always execute the DEFAULT branch's copy of the workflow file, and main's stale copy still reads Dashboard/Dashboard.csproj - a path #1612 moved to deprecated/ on dev - against the dev tree it checks out. Same trap as #1550/#1551. Syncing the file again would fix tonight and re-break at the next pre-release layout drift, so this PR restructures instead: on schedule, nightly.yml does nothing but re-dispatch itself onto the dev ref (workflow_dispatch runs execute the DISPATCHED ref's copy of the file - dev's, current by definition; GITHUB_TOKEN can create workflow_dispatch runs, the recursion guard exempts them, and the dispatched run cannot loop because it arrives as workflow_dispatch, not schedule). Manual dispatches still always build (from_schedule defaults false), the scheduled path keeps the 24h new-commit check, and the artifact job stays pinned to ref: dev so a branch dispatch can never ship branch binaries.

Until main's copy is synced once, the 06:00 UTC schedule keeps failing. After this merges to dev, one of:

git fetch origin && git checkout main && git pull origin main
git checkout origin/dev -- .github/workflows/nightly.yml
git commit -m "Sync nightly.yml from dev: scheduled runs execute main's copy of the workflow"
git push origin main

(requires your admin bypass if branch protection is enforced for admins; check-pr-branch.yml blocks a non-dev hotfix PR to main by design), or simply let the next dev->main release promotion carry it - at the cost of a red scheduled nightly each morning until then. After that one sync, this trap class is dead: main's copy has exactly one job that must keep working, and it references no tree paths at all.

Measured and deliberately NOT done

  • Per-area restore gating: warm restore measured 19-33s across 30 runs. Splitting one restore into four condition-mirrored steps buys back seconds at the price of the exact condition-drift risk Collapse CI's Lite fast / analysis-heavy test split into one step #1701 just retired a test split over. Not worth it at 25s; revisit only if restore cost grows.
  • Splitting test suites across jobs: Run Lite tests (~2m25s) dominates the full build, but a second Windows job costs ~2m45s of checkout/setup/restore/build before its first test - a net loss, and worse under a shared runner pool where a second job also queues. The numbers say no.
  • Sparse checkout to shave the ~1m45s floor: per the brief - it breaks the paths-filter design; not attempted.

Recommendation (repo setting - your click, deliberately not attempted): merge queue on dev

The CHANGELOG-conflict re-push train is structural: serialized auto-merges each conflict on CHANGELOG.md, re-push, and re-run full CI. A dev merge queue removes the train tax (the queue rebases and revalidates serially). Settings -> Rules -> Rulesets -> New branch ruleset targeting dev -> enable Require merge queue; suggested: merge method Merge commit, build concurrency 5, min/max PRs per group 1/5, wait 1 min, "Only merge non-failing entries". Prerequisite first: build.yml (and darling-pg's filter step) must handle the merge_group trigger - a queued PR's required checks otherwise never report and every entry stalls. That trigger wiring (plus a dorny base for merge_group events) is a follow-up PR if you want the queue; enabling the setting before it would brick dev merges.

Corrections to the brief (reported, not silently deviated from)

  • The brief's TASK 1 premise ("the root catch-all drags CHANGELOG.md into full builds") was already corrected by CI: stop charging documentation changes for a .NET restore #1712's measurement: root is four literal build files, markdown never triggered full builds, and the real gap was non-markdown documentation. Confirmed independently here.
  • CI: stop charging documentation changes for a .NET restore #1712's fast path itself never functioned (v4 predicate semantics, above). Its measurements were honest but measured the area filters. This PR is where the fast path first actually works.
  • The brief said measure against "the last ~20 runs"; 30 were pulled for a better median. All 30 turned out to be post-regression, which is itself the finding.

🤖 Generated with Claude Code

erikdarlingdata and others added 7 commits July 26, 2026 16:34
Concurrency groups for build.yml and sql-validation.yml, keyed per PR
number for pull_request events only. Push and release runs get a unique
per-run group (run_id), so dev/main integration builds, release builds,
and every push commit's required-check result are never queued behind,
replaced by, or cancelled through this mechanism.

Rationale: the shared Windows runner pool is what serializes everyone's
CI (#1697 sat queued behind two dev builds), so a stale PR run cancelled
at re-push time is reclaimed capacity for whatever sits queued behind
it. claude-review.yml already had exactly this shape; build.yml and
sql-validation.yml now match it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rrors it

Ratifies #1712's two flagged judgment calls (CITATION.cff and the
Screenshots/ entry stay on the documentation allowlist - citation
metadata and screenshot images cannot affect any build.yml job) but
replaces the bare directory globs docs/** and Screenshots/** with
extension-explicit patterns for markdown, SVG, and image files. Both
directories hold exactly those types today, so nothing classified as
documentation before this commit stops being documentation - but a .sql
or script dropped into either directory tomorrow now defaults to being
CODE, which restores the allowlist's own stated principle (an unfamiliar
file type should default to the safe direction) that a directory-wide
grant quietly undermined.

check-version-bump.yml gets the same allowlist as exclusions: its gate
still said *.md-only, so a LICENSE or .gitignore correction in a dev to
main PR would demand a version bump while build.yml calls the same diff
documentation. The two filters now state the same policy and say so.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…hat executes

Scheduled workflows always execute the DEFAULT branch's copy of the
workflow file, while nightly artifacts deliberately build from dev's
tree. That skew is exactly how the 2026-07-26 scheduled nightly failed
(run 30194606068): main's stale copy still read Dashboard/Dashboard.csproj,
a path #1612 moved to deprecated/ on dev, so 'Set nightly version' died
on a file missing from the tree it had just checked out. Same trap as
before (#1550/#1551) - syncing the file again would fix tonight and
re-break at the next pre-release layout drift.

Structural fix instead: on schedule the workflow does nothing but
re-dispatch itself onto the dev ref (GITHUB_TOKEN can create
workflow_dispatch runs; the Actions recursion guard exempts
workflow_dispatch, and the dispatched run cannot loop back because it
arrives as workflow_dispatch, not schedule). A workflow_dispatch run
executes the DISPATCHED ref's copy of the file - dev's, current by
definition - so after a one-time sync of this file to main, main's copy
has exactly one tree-independent job that must keep working, and nightly
logic changes take effect the night they merge to dev.

Semantics preserved: manual dispatches (from_schedule defaults false)
always build, exactly as before; the scheduled path keeps the 24h
new-commit check via from_schedule=true; the artifact-publishing build
job stays pinned to ref dev so a branch dispatch still cannot ship
branch binaries.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Every job that never carries the release/signing path gets a
timeout-minutes ceiling sized at roughly 3x its worst observed or
cold-cache path: build.yml darling-pg 30 (max observed 3m40s warm, cold
pg-runtime fetch adds a ~340MB download), nightly check 10 / build 90 /
darling-pg 60, sql-validation 30 per matrix leg, claude-review 30. The
failure these bound is hung-not-slow - pg_ctl -w waiting forever on a
cluster that will never come up, a SQL Server container that never
reaches healthy - which otherwise holds a shared-pool runner for the 6h
default while every other PR queues behind it.

Deliberately NOT bounded: build.yml's build job. On release it waits on
SignPath's manual approval gate, which can legitimately take hours; a
timeout there could kill a release mid-signing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The 2026-07-26 08:02 action-pin bump moved dorny/paths-filter v3 to v4.
v4 evaluates every filter pattern as an INDEPENDENT predicate under the
default predicate-quantifier 'some' (a filter is true when any changed
file matches at least one rule), so a bare '!**/*.md' line stopped
being a subtraction and became its own rule: 'any file that is not
markdown'. Every area filter ending in that line went true for ANY
non-markdown change anywhere in the repo, and the code: filter ('**'
plus exclusions) could never be false again.

Measured consequences, straight from run logs:
- darling-pg ran the full TimescaleDB suite on every PR since the bump,
  including md-only ones. Run 30218459544 (PR #1709, two .md files):
  'Filter darling = true, Matching files: CHANGELOG.md' - CHANGELOG.md
  matched '!Darling/**/*.md' by virtue of not being a Darling markdown.
- A single root .gitignore edit built and tested every product: run
  30219202642 (throwaway PR #1714) lit lite, dashboard, AND darling,
  each reporting 'Matching files: .gitignore' via its '!**/*.md' rule.
- The #1712 docs fast path shipped unable to engage: every changed file
  matches '**', so code: was always true and setup/restore always ran.
  Its measured 1m43s md-only runs were real but came from the area
  filters (markdown matches no include), not from the fast path.

The fix keeps v4 (v3 is on the deprecated-runtime track) and removes
every bare negation instead:
- Area filters state the markdown carve-out INSIDE each include as an
  extglob - 'Darling/**/!(*.md)' - where quantifier semantics cannot
  detach it. The positive-only docs allowlist needed no change.
- The uninvertible code: filter becomes an all: counter. The classify
  step decides docs-only by all_count == docs_count, and additionally
  refuses to engage while any area filter is lit, because an area build
  step with restore skipped would run dotnet build --no-restore against
  nothing. Counts and areas derive from the same allowlist today; the
  veto exists for the day someone edits one and not the other.
- check-version-bump.yml had the identical '**'-plus-exclusions shape,
  so its md-only skip had also silently stopped working. Same counter
  fix, same allowlist, and its gate now says why.

Validation: probe commit on throwaway PR #1714 (this build.yml plus a
Darling .txt probe and a Darling .md probe) makes the filter log a
per-file truth table; results recorded in the CI-intelligence PR body.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@erikdarlingdata
erikdarlingdata merged commit 7be6821 into dev Jul 26, 2026
8 checks passed
@erikdarlingdata

Copy link
Copy Markdown
Owner Author

Stage 3 complete - the docs fast path measured end to end. #1714 was rebased to a .gitignore-only diff against dev carrying this PR: both required checks reported in 13 seconds each (run 30220291489). build job: DOCS FAST PATH ENGAGED ... Changed files: 1 total, 1 on the documentation allowlist. Areas: root=false core=false installer_core=false dashboard=false lite=false installer=false darling=false - setup, restore, versioning, every build/test/publish step skipped; the job was checkout + filter + classify. darling-pg: No Darling code changed notice, suite skipped, 13s. For scale: the SAME diff under the broken classifier paid a ~7m full build plus the full PG suite (stage 1, run 30219202642), and the pre-#1712 docs floor was ~1m30s-1m45s. One correction to the earlier floor claim: checkout time is runner-dependent (~5s here, ~1m elsewhere), so docs-only PRs land between ~15s and ~1m depending on runner luck - the fixed cost is the classification, which is now correct either way. #1714 closes now, unmerged, its job done.

@erikdarlingdata

Copy link
Copy Markdown
Owner Author

Correction to the merge-queue recommendation above: it is not available on this repository. Merge queues exist only on organization-owned repos (public on any plan, private on Enterprise Cloud) - personal-account repositories are excluded entirely. Attempting the recommended ruleset here returns 422 Validation Failed: Invalid rule 'merge_queue'. Source: https://github.blog/changelog/2023-07-12-pull-request-merge-queue-is-now-generally-available/ and https://github.com/orgs/community/discussions/51483. The #1716 merge_group wiring stays (inert, zero cost, live the day the repo ever moves to an organization). The CHANGELOG-train options that DO work on a personal repo are being written up separately. Meanwhile the classification fix in this PR already cut the train re-run cost: single-area re-pushes ~3m40s instead of ~6m30s, docs-only re-pushes 13s.

pull Bot pushed a commit to ehtick/PerformanceMonitor that referenced this pull request Jul 29, 2026
Lands the prerequisite erikdarlingdata#1715's merge-queue recommendation named: without
a merge_group trigger the required 'build' and 'Darling PostgreSQL
tests' checks never report inside a queue, and every queued PR stalls -
enabling the ruleset before this wiring would brick dev merges. The
trigger is inert until the queue ruleset is actually enabled.

Queue runs take the same always-restore path as dev/main pushes (a
queue run is the last validation before its result lands on dev) and
the per-run concurrency group, so they are never cancelled or replaced.
Path classification works unchanged: dorny/paths-filter v4.0.1+
resolves merge_group diffs from the payload's base_sha/head_sha
whenever the base input is empty, which is exactly what the filter
steps pass for non-push events.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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