@scalequality/check 0.5.4 → 0.5.5

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/bin/check.mjs CHANGED
@@ -9,7 +9,7 @@ import { readFileSync, existsSync, appendFileSync } from "node:fs"
9
9
  import { prepareCheckoutArchive, normalizeExcludes } from "./archive.mjs"
10
10
  import { measureDurability } from "./durability.mjs"
11
11
  import { stageCoverageReports } from "./coverage.mjs"
12
- import { ciContext } from "./ci.mjs"
12
+ import { ciContext, changedFiles } from "./ci.mjs"
13
13
 
14
14
  const args = process.argv.slice(2)
15
15
  const flag = (name) => {
@@ -256,6 +256,9 @@ async function main() {
256
256
  if (ci.headRef) form.append("ciHeadRef", ci.headRef)
257
257
  if (ci.pullRequest) form.append("ciPullRequest", String(ci.pullRequest))
258
258
  }
259
+ // Which files the change touched: the other modules of a monorepo it reached are measured again too.
260
+ const touched = changedFiles()
261
+ if (touched) form.append("ciChangedFiles", touched.join("\n"))
259
262
  const r = await fetch(`${base}/report/upload`, {
260
263
  method: "POST",
261
264
  headers: auth,
@@ -268,9 +271,10 @@ async function main() {
268
271
  if (r.status === 409) fail(body.includes("measurement_already_running") ? "another measurement is already running for this project. Wait for it to finish and rerun this step." : "continuous is not enabled for this project. Turn it on in ScaleQuality.")
269
272
  fail(`report failed (${r.status}) ${body}`)
270
273
  }
271
- const { runId } = await r.json()
274
+ const { runId, modules } = await r.json()
272
275
  if (!runId) fail("no run id returned.")
273
276
  log(`ScaleQuality: measuring ${project} …`)
277
+ if (Array.isArray(modules) && modules.length) log(`ScaleQuality: also measuring the ${modules.length === 1 ? "module" : `${modules.length} modules`} this change touched: ${modules.map((m) => m.path || "whole repository").join(", ")}`)
274
278
 
275
279
  // The poll interval is part of the measured gate time, not just politeness. A flat
276
280
  // 5s quantizes every verdict to a 5s boundary: an analysis that finishes in 7s is
package/bin/ci.mjs CHANGED
@@ -1,3 +1,5 @@
1
+ import { spawnSync } from "node:child_process"
2
+ import { readFileSync } from "node:fs"
1
3
  // Where a CI run happened, read from the provider's own variables.
2
4
 
3
5
  /**
@@ -16,3 +18,31 @@ export function ciContext(env = process.env) {
16
18
  if (env.BITBUCKET_BUILD_NUMBER) return { provider: "bitbucket", baseRef: env.BITBUCKET_PR_DESTINATION_BRANCH || null, headRef: env.BITBUCKET_BRANCH || null, pullRequest: env.BITBUCKET_PR_ID || null }
17
19
  return null
18
20
  }
21
+
22
+ /**
23
+ * The files this change touched, so ScaleQuality measures again only the modules of a monorepo it reached
24
+ * (Erik, 09/10/2026). A pull request compares against its base branch; a push against the commit before it
25
+ * (or the previous one when the CI does not say). Null when git cannot tell: the server then measures them all.
26
+ */
27
+ export function changedFiles(env = process.env, cwd = process.cwd(), run = spawnSync) {
28
+ const git = (...args) => {
29
+ const r = run("git", ["--no-optional-locks", "-C", cwd, ...args], { encoding: "utf8", timeout: 20000, maxBuffer: 32 * 1024 * 1024 })
30
+ return r.error || r.status !== 0 ? null : String(r.stdout)
31
+ }
32
+ const zero = (sha) => !sha || /^0+$/.test(sha)
33
+ const strip = (v) => (v ? String(v).replace(/^refs\/heads\//, "") : "")
34
+ let range = null
35
+ const prBase = env.GITHUB_BASE_REF || env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME || strip(env.SYSTEM_PULLREQUEST_TARGETBRANCH) || env.BITBUCKET_PR_DESTINATION_BRANCH
36
+ if (env.CI_MERGE_REQUEST_DIFF_BASE_SHA) range = [`${env.CI_MERGE_REQUEST_DIFF_BASE_SHA}...HEAD`]
37
+ else if (prBase) range = [`origin/${prBase}...HEAD`]
38
+ else {
39
+ let before = env.CI_COMMIT_BEFORE_SHA || null
40
+ if (!before && env.GITHUB_EVENT_PATH) {
41
+ try { before = JSON.parse(readFileSync(env.GITHUB_EVENT_PATH, "utf8")).before || null } catch { before = null }
42
+ }
43
+ range = zero(before) ? ["HEAD~1", "HEAD"] : [before, "HEAD"]
44
+ }
45
+ const out = git("diff", "--name-only", ...range)
46
+ if (out === null) return null
47
+ return out.split("\n").map((f) => f.trim()).filter(Boolean).slice(0, 20000)
48
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scalequality/check",
3
- "version": "0.5.4",
3
+ "version": "0.5.5",
4
4
  "description": "ScaleQuality continuous code-maturity check for CI. Re-measures your repo on every build and fails the pipeline below your maturity line.",
5
5
  "type": "module",
6
6
  "bin": {