Files
orca/config/scripts/ci/unit-selection/dependency-graph/ci-unit-input-ownership.mjs
Neil 9bd6272fdf refactor(tooling): organize build, CI, and test owners (#38130)
* refactor(tooling): organize test runtime and maintenance owners

* test(tooling): preserve relocated runtime fixture dependency edges

* refactor(tooling): preserve xterm routing owner checks

* ci(tooling): include routing owner in sparse checkout

* test(tooling): preserve copied workflow dependency closures

* fix(tooling): normalize hashed JSON assets in release parity

* fix(tooling): distinguish asset aliases from literal references

* fix(tooling): frame normalized asset reference payloads

* fix(tooling): normalize decoded JSON asset references

* refactor(tooling): organize build, CI and release owners

* fix(tooling): align moved generator and workflow path contracts

* fix(tooling): update generated plugin bundle owner banners

* test(tooling): create relocated mobile verifier fixture directories

* test(tooling): copy headless detector dependency closure

* test(tooling): align native batch policy fixtures with owner path

* fix(tooling): link moved reliability command to historical evidence

* fix(tooling): preserve nested sandbox owners and canonical guide source

* fix(tooling): target release version owners in checkout fixture
2026-11-04 21:08:19 -08:00

87 lines
2.4 KiB
JavaScript

import { createHash } from 'node:crypto'
import { readFileSync } from 'node:fs'
import { join } from 'node:path'
export function unitInputSourceDigest(sources) {
return createHash('sha256')
.update(JSON.stringify([...sources].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))))
.digest('hex')
}
function repositoryInput(path) {
return (
typeof path === 'string' &&
/^(?:src|config|tests)\//.test(path) &&
!/[\\*?[\]{}]/.test(path) &&
path
.split('/')
.every((part, index, parts) =>
part === '' ? index === parts.length - 1 : part !== '.' && part !== '..'
)
)
}
export function readUnitInputOwnership(root) {
try {
const manifest = JSON.parse(
readFileSync(
join(
root,
'config/scripts/ci/unit-selection/dependency-graph/ci-unit-input-ownership.json'
),
'utf8'
)
)
return manifest?.version === 1 && Array.isArray(manifest.records) ? manifest.records : []
} catch {
return []
}
}
export function checkUnitInputOwnership(
records,
sourceClosure,
env = process.env,
contextSha256 = unitInputSourceDigest(new Map())
) {
const checked = new Map()
if (!Array.isArray(records)) {
return checked
}
const counts = new Map()
for (const record of records) {
if (typeof record?.file === 'string') {
counts.set(record.file, (counts.get(record.file) ?? 0) + 1)
}
}
for (const record of records) {
if (!record || typeof record !== 'object') {
continue
}
const { file, inputs, emptyEnv, sourceClosureSha256, reason } = record
if (
counts.get(file) !== 1 ||
!repositoryInput(file) ||
file.endsWith('/') ||
!Array.isArray(inputs) ||
!inputs.every(repositoryInput) ||
!Array.isArray(emptyEnv) ||
!emptyEnv.every((name) => typeof name === 'string' && /^[A-Z][A-Z0-9_]*$/.test(name)) ||
emptyEnv.some((name) => Boolean(env[name])) ||
typeof reason !== 'string' ||
!reason.trim() ||
typeof sourceClosureSha256 !== 'string' ||
!/^[a-f0-9]{64}$/.test(sourceClosureSha256) ||
record.contextSha256 !== contextSha256
) {
continue
}
const sources = sourceClosure(file)
if (!sources || !sources.has(file) || unitInputSourceDigest(sources) !== sourceClosureSha256) {
continue
}
checked.set(file, { inputs })
}
return checked
}