@cratis/pi 7.68.0 → 7.68.1
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.
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
import { spawnSync } from 'node:child_process';
|
|
6
6
|
import { createHash } from 'node:crypto';
|
|
7
|
-
import { mkdirSync, readFileSync, readdirSync, statSync, writeFileSync, renameSync } from 'node:fs';
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync, renameSync } from 'node:fs';
|
|
8
8
|
import { homedir } from 'node:os';
|
|
9
|
-
import { isAbsolute, join, resolve } from 'node:path';
|
|
9
|
+
import { dirname, isAbsolute, join, resolve } from 'node:path';
|
|
10
10
|
import { parseArgs } from 'node:util';
|
|
11
11
|
import { Script } from 'node:vm';
|
|
12
12
|
import { fileURLToPath } from 'node:url';
|
|
@@ -16,6 +16,7 @@ const commandTimeout = 15_000;
|
|
|
16
16
|
const reviewedRulesRef = '40125b4fcae388e62ed9471edfffd0e991422f0a';
|
|
17
17
|
const hookMode = process.argv[2] === '--hook';
|
|
18
18
|
let claudeHook = false;
|
|
19
|
+
let invocation = {};
|
|
19
20
|
const hookWarnings = [];
|
|
20
21
|
const warningLine = line => /^(::warning\b|::notice title=Release notes (?:drift )?not checked|Warning:)/.test(line);
|
|
21
22
|
const warning = message => {
|
|
@@ -25,6 +26,23 @@ const warning = message => {
|
|
|
25
26
|
const run = (command, args, options = {}) => spawnSync(command, args, {
|
|
26
27
|
encoding: 'utf8', timeout: commandTimeout, maxBuffer: 32 * 1024 * 1024, ...options,
|
|
27
28
|
});
|
|
29
|
+
// A bare ENOENT cannot be told apart from a path resolved against the wrong directory, a copy of this
|
|
30
|
+
// checker from another checkout, or a file that is not there yet. Naming all of those lets the next
|
|
31
|
+
// occurrence be diagnosed instead of retried.
|
|
32
|
+
function readBodyFile(value) {
|
|
33
|
+
const resolved = resolve(value);
|
|
34
|
+
try {
|
|
35
|
+
return readFileSync(resolved, 'utf8');
|
|
36
|
+
} catch (error) {
|
|
37
|
+
const parent = dirname(resolved);
|
|
38
|
+
const details = [`--body-file value: ${value}`, `path tried: ${resolved}`,
|
|
39
|
+
`parent directory exists: ${existsSync(parent)}`, `file exists now: ${existsSync(resolved)}`,
|
|
40
|
+
`checker working directory: ${process.cwd()}`,
|
|
41
|
+
...Object.entries(invocation).map(([name, detail]) => `${name}: ${detail}`),
|
|
42
|
+
`checker script: ${fileURLToPath(import.meta.url)}`];
|
|
43
|
+
throw new Error(`cannot read the pull-request body file (${error.code || error.message}); ${details.join('; ')}`, { cause: error });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
28
46
|
const gh = (args, options = {}) => {
|
|
29
47
|
const result = run('gh', args, options);
|
|
30
48
|
if (result.error || result.status !== 0) throw new Error(`gh ${args[0]} failed: ${result.stderr?.trim() || result.error?.message || result.status}`);
|
|
@@ -156,7 +174,7 @@ function check(argv, repositoryCallers, lookupOptions) {
|
|
|
156
174
|
for (const label of split(values['add-label'])) labels.add(label);
|
|
157
175
|
const intent = intents.filter(label => labels.has(label));
|
|
158
176
|
if (intent.length !== 1) throw new Error(`Exactly one release-intent label is required (major/minor/patch/no-release); found ${intent.join(', ') || 'none'}.`);
|
|
159
|
-
const body = values['body-file'] ?
|
|
177
|
+
const body = values['body-file'] ? readBodyFile(values['body-file']) : pull.body || '';
|
|
160
178
|
let repository = values.repo;
|
|
161
179
|
let defaultBranch = git(['symbolic-ref', '--short', 'refs/remotes/origin/HEAD']).replace(/^origin\//, '') || 'main';
|
|
162
180
|
try {
|
|
@@ -324,6 +342,7 @@ function hook() {
|
|
|
324
342
|
if (typeof text !== 'string' || !/\bgh\s+pr\s+(create|edit)\b/.test(text.replace(/\\\r?\n/g, ''))) return 0;
|
|
325
343
|
// Match each simple command, never the same text inside an echo/grep argument.
|
|
326
344
|
let cwd = payload.cwd || process.cwd();
|
|
345
|
+
invocation = { 'hook payload directory': payload.cwd || '(none)' };
|
|
327
346
|
let knownDirectory = true;
|
|
328
347
|
let parsed;
|
|
329
348
|
try { parsed = commands(text); } catch (error) { if (!optedIn(cwd)) return 0; throw error; }
|
|
@@ -386,6 +405,7 @@ function hook() {
|
|
|
386
405
|
if (targetedRepository) lookupEnvironment.GH_REPO = targetedRepository;
|
|
387
406
|
else delete lookupEnvironment.GH_REPO;
|
|
388
407
|
process.chdir(cwd);
|
|
408
|
+
invocation['command directory'] = cwd;
|
|
389
409
|
const code = check(args, repositoryCallers, { env: lookupEnvironment });
|
|
390
410
|
if (code !== 0 && code !== 3) throw new Error('The pull-request body or release intent failed cratis-check-pr. Fix the reported violations before retrying.');
|
|
391
411
|
}
|