@diffci.com/diffci 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,6 +14,21 @@ From an existing repository checkout, with Node.js 22.5+ and Git installed:
14
14
  npx @diffci.com/diffci@latest observe --no-send
15
15
  ```
16
16
 
17
+ For the fastest self-serve runtime pilot, run one paired check from the repository root:
18
+
19
+ ```bash
20
+ npx @diffci.com/diffci@latest pilot --full "npm test"
21
+ ```
22
+
23
+ On Windows PowerShell, quote the package name:
24
+
25
+ ```powershell
26
+ npx '@diffci.com/diffci@latest' pilot --full "npm test"
27
+ ```
28
+
29
+ This writes `diffci-observe.json`, `diffci-savings.json`, and `diffci-savings.md` to a sibling
30
+ `diffci-output` folder outside the checkout, so it does not dirty the repository.
31
+
17
32
  **Upgrade from 0.1.3:** tests excluded by a source-only `tsconfig.json` could be discovered without
18
33
  their dependency edges, producing an incomplete selection. This is fixed in **0.1.4**. Revalidate
19
34
  affected observations before using them as opportunity evidence; see the
@@ -34,8 +49,8 @@ not Cal.com's production savings or a prediction for your repository.
34
49
  Selection counts alone do not establish runtime savings. Observation mode measures neither the
35
50
  selected test execution nor realized savings.
36
51
 
37
- For a self-serve paired runtime check, run `observe` first and then run `verify-savings` against the
38
- observation report. It compares your normal full command with
52
+ For an advanced paired runtime check, you can still run `observe` first and then run `verify-savings`
53
+ against the observation report. It compares your normal full command with
39
54
  DiffCI's proposed selected command and writes JSON plus Markdown evidence; see
40
55
  [`docs/npm-adoption.md`](docs/npm-adoption.md#self-serve-runtime-pilot).
41
56
 
@@ -28,7 +28,7 @@
28
28
  import { execFileSync } from "node:child_process";
29
29
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
30
30
  import { tmpdir } from "node:os";
31
- import { dirname, join, resolve } from "node:path";
31
+ import { basename, dirname, join, resolve } from "node:path";
32
32
  import { observe, isInsideRepository } from "./observe.js";
33
33
  import { submitObservation } from "./submit.js";
34
34
  import { formatVerifySavingsSummary, runVerifySavings, writeVerifySavingsReport } from "./verify-savings.js";
@@ -286,9 +286,65 @@ function runVerifySavingsCommand(flags, env) {
286
286
  console.log(` markdown: ${options.markdown}`);
287
287
  return report.comparison.fullCommandSucceeded && report.comparison.selectedCommandSucceeded ? 0 : 1;
288
288
  }
289
+ function defaultPilotOutputDir(repoPath) {
290
+ return join(dirname(repoPath), "diffci-output");
291
+ }
292
+ async function runPilot(flags, env) {
293
+ const full = stringFlag(flags, "full");
294
+ if (!full) {
295
+ console.error('--full <command> is required, for example: diffci pilot --full "npm test"');
296
+ return 1;
297
+ }
298
+ const repoPath = resolve(stringFlag(flags, "repo") ?? env.GITHUB_WORKSPACE ?? process.cwd());
299
+ const outDir = resolve(stringFlag(flags, "out-dir") ?? defaultPilotOutputDir(repoPath));
300
+ if (isInsideRepository(repoPath, outDir) || outDir === repoPath) {
301
+ console.error(`Refusing to write pilot reports inside the repository: ${outDir}. Pass --out-dir with a path outside the checkout.`);
302
+ return 2;
303
+ }
304
+ const label = stringFlag(flags, "label") ?? basename(repoPath);
305
+ const observationPath = join(outDir, "diffci-observe.json");
306
+ const savingsPath = join(outDir, "diffci-savings.json");
307
+ const markdownPath = join(outDir, "diffci-savings.md");
308
+ const identity = observerIdentity();
309
+ const observation = await observe({
310
+ repoPath,
311
+ env: env,
312
+ version: identity.version,
313
+ engineSha: identity.sha,
314
+ baseOverride: stringFlag(flags, "base"),
315
+ headOverride: stringFlag(flags, "head"),
316
+ redactPaths: flags["redact-paths"] === true,
317
+ reportPath: observationPath,
318
+ });
319
+ mkdirSync(outDir, { recursive: true });
320
+ writeFileSync(observationPath, `${JSON.stringify(observation, null, 2)}\n`, "utf8");
321
+ console.log(summarise(observation));
322
+ console.log(` observation report: ${observationPath}`);
323
+ if (observation.status !== "OBSERVED") {
324
+ console.log("DiffCI pilot stopped before timing because observation did not produce a selectable report.");
325
+ return 1;
326
+ }
327
+ const savings = runVerifySavings({
328
+ full,
329
+ selectedFromReport: observationPath,
330
+ out: savingsPath,
331
+ markdown: markdownPath,
332
+ label,
333
+ cwd: repoPath,
334
+ timeoutMs: numberFlag(flags, "timeout-ms") ?? 30 * 60 * 1000,
335
+ analysisOverheadMs: numberFlag(flags, "analysis-overhead-ms"),
336
+ tailBytes: numberFlag(flags, "tail-bytes") ?? 12_000,
337
+ });
338
+ writeVerifySavingsReport(savings, { out: savingsPath, markdown: markdownPath });
339
+ console.log(formatVerifySavingsSummary(savings));
340
+ console.log(` savings report: ${savingsPath}`);
341
+ console.log(` markdown: ${markdownPath}`);
342
+ return savings.comparison.fullCommandSucceeded && savings.comparison.selectedCommandSucceeded ? 0 : 1;
343
+ }
289
344
  const USAGE = `diffci - observation-only change-aware CI analysis
290
345
 
291
346
  Usage:
347
+ diffci pilot --full <command> [--repo <path>] [--out-dir <dir>] [--label <name>]
292
348
  diffci observe [--repo <path>] [--out <file>] [--base <sha> --head <sha>]
293
349
  [--redact-paths] [--json] [--quiet] [--fail-on-error]
294
350
  [--api-url <url> --api-token <token>] [--no-send]
@@ -298,6 +354,7 @@ Usage:
298
354
  diffci verify-workflow [--repo <path>]
299
355
  diffci version
300
356
 
357
+ pilot runs observe and verify-savings together, writing reports to ../diffci-output by default.
301
358
  observe analyses the checkout and writes one JSON report. It runs nothing and changes nothing.
302
359
  verify-savings runs both commands and reports measured paired runtime; it is an opt-in pilot command.
303
360
  verify-workflow checks that the job running DiffCI cannot affect any other job, and exits 1 if it can.
@@ -315,6 +372,9 @@ async function main() {
315
372
  return;
316
373
  }
317
374
  switch (command) {
375
+ case "pilot":
376
+ process.exitCode = await runPilot(flags, env);
377
+ return;
318
378
  case "observe":
319
379
  process.exitCode = await runObserve(flags, env);
320
380
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diffci.com/diffci",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "DiffCI - deterministic change-aware CI planning",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {