mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-10 10:40:32 +01:00
* Add failing tests for repo-declared docs-only paths (GST-1974) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Let a repository name its own docs-only paths in its base ship policy (GST-1974) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Catch relative directory readers, missing docs tests and readers the base gained in the docs-only class Review-Finding: review/specialist-batched#1 reader=security Review-Finding: review/red-team#1 reader=red-team Review-Finding: review/red-team#2 reader=red-team Review-Finding: voices/adversarial-native#1 reader=adversarial-native Review-Finding: voices/adversarial-native#3 reader=adversarial-native Review-Finding: voices/adversarial-native#5 reader=adversarial-native Review-Finding: voices/outside-voice#1 reader=outside-voice Review-Finding: voices/outside-voice#2 reader=outside-voice Review-Finding: voices/outside-voice#3 reader=outside-voice Review-Finding: voices/outside-voice#4 reader=outside-voice Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Say in the changelog that a missing docs test or a new base reader keeps the full checks Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Describe the new directory-reader forms, the missing docs test refusal and land's base-reader check Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
30 lines
1.9 KiB
TypeScript
30 lines
1.9 KiB
TypeScript
/**
|
|
* land.docs_only_skip (R81; docs/pregate.md#docs-only). Its own module: lib/land-merged-checks.ts is imported by
|
|
* lib/ship-policy.ts, which lib/docs-only.ts imports, so the classifier cannot be imported there.
|
|
*/
|
|
import { spawnSync } from 'node:child_process';
|
|
import { classifyDocsOnly, directoryReaders, readDiff, readRepoDocs, referencesTo } from './docs-only';
|
|
|
|
/**
|
|
* The merged checks for `pin`: land.merged_checks without the commands land.docs_only_skip names when lib/docs-only.ts
|
|
* calls the pin's change since its merge base with `base` human docs only (R81; docs/pregate.md#docs-only), and no
|
|
* non-docs file at `base` names a changed path or reads its directory without doing so at the pin: land merges onto
|
|
* `base`, so a reader the base gained after the pin branched keeps the checks. Any git or classifier failure keeps every check.
|
|
*/
|
|
export function mergedChecksFor(root: string, land: { merged_checks?: string[]; docs_only_skip?: string[] } | null | undefined, base: string, pin: string): string[] {
|
|
const checks = land?.merged_checks ?? [];
|
|
const skip = land?.docs_only_skip ?? [];
|
|
if (!skip.length) return checks;
|
|
const mb = spawnSync('git', ['merge-base', base, pin], { cwd: root, encoding: 'utf8', timeout: 30_000 });
|
|
try {
|
|
if (mb.status !== 0 || !classifyDocsOnly({ root, base: mb.stdout.trim(), head: pin, policyRef: base }).docsOnly) return checks;
|
|
const changed = readDiff(root, mb.stdout.trim(), pin).flatMap(e => [e.path, ...(e.from ? [e.from] : [])]);
|
|
const repo = readRepoDocs(root, base);
|
|
if ('error' in repo) return checks;
|
|
const untied = { ...repo, tests: [] };
|
|
const atPin = new Set(changed.flatMap(p => directoryReaders(root, p, untied, pin)));
|
|
if (changed.some(p => referencesTo(root, p, base, repo).length || directoryReaders(root, p, untied, base).some(f => !atPin.has(f)))) return checks;
|
|
} catch { return checks; }
|
|
return checks.filter(c => !skip.includes(c));
|
|
}
|