You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maka.apache.org by as...@apache.org on 2026/09/01 16:31:46 UTC

(maka) 01/03: ci: give the full-suite fallback's biggest buckets their real owners

This is an automated email from the ASF dual-hosted git repository.

Astro-Han pushed a commit to branch ci/4480-classify-planner-fallback-paths
in repository https://gitbox.apache.org/repos/asf/maka.git

commit f6d540c166b62e9f11dd2172b7ce9832740abb57
Author: AstroHan <le...@outlook.com>
AuthorDate: Wed Sep 2 00:30:58 2026 +0800

    ci: give the full-suite fallback's biggest buckets their real owners
    
    A path the classifier does not recognise sets `unknownCode`, which returns
    the full suite. That fallback is correct as a default and is the largest
    single source of full-suite runs, so the fix is to give its biggest
    occupants an owner rather than to weaken it.
    
    `native/gitoxide-helper/` and `native/runtime-host-peer/` each have an
    admission lane that owns `cargo fmt` and `cargo test` for them, and the
    direct-peer crate additionally reaches CLI packaging, which builds it into
    the tarball and runs `cargo deny` against `deny.toml`. Nothing under either
    is read by lint, typecheck, Storybook, or a real window.
    
    They are named one crate at a time rather than by the `native/` prefix.
    What earns the exemption is having a lane, not being written in Rust: a
    crate added under `native/` has neither a lane nor a JavaScript consumer on
    the commit that introduces it, and this fallback is the only thing that
    would build it at all. A regression asserts that an unowned native root
    still selects full.
    
    `.asf.yaml` goes to `RELEASE_CONTRACT_FILES`. It names the required
    contexts and the release-environment admission rules, and
    `product-release.test.mjs` is the suite that parses it and asserts them —
    so selecting the release contract is what proves a change to the merge gate
    still passes its own policy test. Routing it anywhere else lets that gate
    change while the test that guards it is skipped.
    
    `patches/` deliberately keeps the fallback. A patch rewrites a dependency's
    behaviour, and which suite proves that behaviour is a property of the patch
    rather than of the directory: the node-pty patch is regressed by
    `packages/runtime/src/__tests__/node-pty-write-lifecycle.test.ts`, while the
    packaging smoke a build-shaped selection would run only asserts that a
    method name still appears in the tarball. Narrowing this bucket needs an
    explicit patch-to-consumer mapping; until one exists the cost here is runner
    minutes rather than a silent regression.
    
    Refs #4480
---
 scripts/ci-test-plan.mjs      | 33 ++++++++++++++++++++
 scripts/ci-test-plan.test.mjs | 71 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 104 insertions(+)

diff --git a/scripts/ci-test-plan.mjs b/scripts/ci-test-plan.mjs
index 149dd30152..74e89538d5 100644
--- a/scripts/ci-test-plan.mjs
+++ b/scripts/ci-test-plan.mjs
@@ -35,6 +35,11 @@ const FULL_SUITE_FILES = new Set([
 ]);
 
 const RELEASE_CONTRACT_FILES = new Set([
+  // Branch protection. `product-release.test.mjs` parses it and asserts the
+  // required contexts and the release-environment admission rules, and that
+  // suite runs behind `check:release` — so this selection is what proves a
+  // change to the merge gate still satisfies its own policy test.
+  '.asf.yaml',
   'apps/desktop/src/main/app-update-test-context.ts',
   'apps/desktop/build/entitlements.mac.inherit.plist',
   'apps/desktop/build/entitlements.mac.plist',
@@ -158,6 +163,10 @@ const CLI_PACKAGE_WORKSPACES = [
 
 function isCliPackagePath(path) {
   if (CLI_PACKAGE_FILES.has(path) || path.startsWith('patches/')) return true;
+  // `release:cli:pack` builds the direct-peer addon into the tarball and runs
+  // `cargo deny` against that policy, so this crate ships and CLI packaging is
+  // the JavaScript gate that proves it still does.
+  if (path === 'deny.toml' || path.startsWith('native/runtime-host-peer/')) return true;
   if (isDocumentation(path)) return false;
   if (path.startsWith('scripts/release-cli-')) return true;
   if (path.startsWith('tsconfig') && path.endsWith('.json')) return true;
@@ -442,6 +451,30 @@ export function planTests(changedFiles, options = {}) {
       code = true;
       continue;
     }
+    // Rust. Each of these crates has an admission lane that owns `cargo fmt`
+    // and `cargo test` for it, and `native/runtime-host-peer` additionally
+    // reaches CLI packaging through `isCliPackagePath` above. Nothing under
+    // either is read by lint, typecheck, Storybook, or a real window, so
+    // falling through to the guard below made this directory the largest
+    // single source of full-suite runs.
+    //
+    // Named one crate at a time rather than by the `native/` prefix: what
+    // earns the exemption is having a lane, not being written in Rust. A new
+    // native root has neither until someone adds one, and until then the
+    // guard below is the only thing that would test it at all.
+    //
+    // `deny.toml` is the lint policy both crates share and travels with them.
+    if (
+      path.startsWith('native/gitoxide-helper/') ||
+      path.startsWith('native/runtime-host-peer/') ||
+      path === 'deny.toml'
+    ) {
+      continue;
+    }
+    // Branch protection selects no workspace, but it is not unknown either:
+    // `RELEASE_CONTRACT_FILES` above routes it to `product-release.test.mjs`,
+    // the suite that parses it and asserts the required contexts.
+    if (path === '.asf.yaml') continue;
     if (path.startsWith('.github/')) continue;
     code = true;
     unknownCode = true;
diff --git a/scripts/ci-test-plan.test.mjs b/scripts/ci-test-plan.test.mjs
index a9d03ddeb0..8aca785578 100644
--- a/scripts/ci-test-plan.test.mjs
+++ b/scripts/ci-test-plan.test.mjs
@@ -371,6 +371,77 @@ test('unknown top-level code fails safe to full selection', () => {
   assert.equal(planTests(['unknown.config'], { graph }).full, true);
 });
 
+// Everything below reached that fail-safe until now. `native/` alone was the
+// largest single source of full-suite runs — 14 of the last 300 first-parent
+// commits, ahead of `package-lock.json` — because the classifier had no opinion
+// about a directory that three dedicated lanes already own.
+
+test('a Rust crate with its own admission lane selects no JavaScript surface', () => {
+  // `gitoxide-helper-admission.yml` owns `cargo fmt`, `cargo test`, and the
+  // JavaScript invocation contract for this crate on three operating systems.
+  // No step in `ci.yml` reads it, so the plan has nothing to select.
+  for (const path of ['native/gitoxide-helper/src/main.rs', 'native/gitoxide-helper/Cargo.toml']) {
+    const plan = planTests([path], { graph });
+    assert.equal(plan.full, false, path);
+    assert.equal(plan.code, false, path);
+    assert.equal(plan.cliPackage, false, path);
+    assert.deepEqual(plan.workspaces, [], path);
+  }
+});
+
+test('the direct-peer crate and its lint policy select CLI packaging alone', () => {
+  // `release:cli:pack` builds this addon into the tarball and runs `cargo deny`
+  // against that policy, so CLI packaging is the one JavaScript gate with a
+  // stake here. Lint, typecheck, Storybook, and a real window have none.
+  for (const path of [
+    'native/runtime-host-peer/src/engine.rs',
+    'native/runtime-host-peer/Cargo.lock',
+    'deny.toml',
+  ]) {
+    const plan = planTests([path], { graph });
+    assert.equal(plan.full, false, path);
+    assert.equal(plan.cliPackage, true, path);
+    assert.equal(plan.releaseContract, true, path);
+    assert.equal(plan.e2e, false, path);
+    assert.equal(plan.storybook, false, path);
+    assert.equal(plan.appIcons, false, path);
+    assert.deepEqual(plan.workspaces, [], path);
+  }
+});
+
+test('a native root without an admission lane still fails safe to full', () => {
+  // The exemption above is owned by a lane, not by the language. A crate added
+  // under `native/` has no lane on the commit that introduces it, so nothing
+  // but this fallback would compile or test it at all.
+  for (const path of ['native/new-helper/src/main.rs', 'native/new-helper/Cargo.toml']) {
+    assert.equal(planTests([path], { graph }).full, true, path);
+  }
+});
+
+test('branch protection reaches the suite that parses it', () => {
+  // `.asf.yaml` names the required contexts and the release-environment
+  // admission rules. `product-release.test.mjs` is the only suite that reads
+  // it, and it runs behind `check:release` — so selecting the release contract
+  // is what proves a change to the merge gate still passes its own policy test.
+  const plan = planTests(['.asf.yaml'], { graph });
+  assert.equal(plan.full, false);
+  assert.equal(plan.releaseContract, true);
+  assert.equal(plan.code, false);
+  assert.deepEqual(plan.workspaces, []);
+});
+
+test('a dependency patch keeps the full suite until a consumer map exists', () => {
+  // A patch rewrites a dependency's behaviour, and which suite proves that
+  // behaviour is a property of the patch rather than of the directory. The
+  // node-pty patch is regressed by
+  // `packages/runtime/src/__tests__/node-pty-write-lifecycle.test.ts`, while
+  // the packaging smoke that a build-shaped selection would run only asserts
+  // that a method name still appears in the tarball. Narrowing this bucket
+  // needs an explicit patch-to-consumer mapping; until then it stays here,
+  // where the cost is runner minutes rather than a silent regression.
+  assert.equal(planTests(['patches/node-pty+1.2.0-beta.15.patch'], { graph }).full, true);
+});
+
 test('full-suite authority files select every surface', () => {
   for (const path of ['package-lock.json', '.github/workflows/ci.yml']) {
     assert.equal(planTests([path], { graph }).full, true, path);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org