@assembly-js/app-foundation 0.0.38 → 0.0.39
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-crons.mjs +36 -5
- package/package.json +1 -1
package/bin/check-crons.mjs
CHANGED
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
// cronWiringChangedThisTurn). Everything else — a template clone, a Vercel
|
|
14
14
|
// build, an update turn that never touched the cron — gets the same findings
|
|
15
15
|
// as warnings: those paths have no agent who can act on a failure, so failing
|
|
16
|
-
// them would only strand an app that already worked.
|
|
16
|
+
// them would only strand an app that already worked. A below-floor schedule
|
|
17
|
+
// the app shipped before the turn stays a warning even then (see
|
|
18
|
+
// baselineCronSchedules).
|
|
17
19
|
import { readFileSync, readdirSync, existsSync } from 'node:fs';
|
|
18
20
|
import { spawnSync } from 'node:child_process';
|
|
19
21
|
import { join, relative, sep } from 'node:path';
|
|
@@ -65,6 +67,30 @@ function isCronWiringPath(file) {
|
|
|
65
67
|
return CRON_WIRING_PATHS.some((p) => (p.endsWith('/') ? file.startsWith(p) : file === p));
|
|
66
68
|
}
|
|
67
69
|
|
|
70
|
+
// The cron entries vercel.json carried at the turn baseline, keyed by path and
|
|
71
|
+
// schedule. A schedule the app already shipped is product behavior the turn has
|
|
72
|
+
// no mandate to change, so its interval finding stays a warning even when the
|
|
73
|
+
// turn rewired the route behind it. An unreadable baseline yields an empty set,
|
|
74
|
+
// which keeps every interval finding fatal.
|
|
75
|
+
function baselineCronSchedules() {
|
|
76
|
+
const baseline = (process.env[TURN_BASELINE_ENV] ?? '').trim();
|
|
77
|
+
const schedules = new Set();
|
|
78
|
+
if (!baseline) return schedules;
|
|
79
|
+
const result = spawnSync('git', ['show', `${baseline}:vercel.json`], { cwd: ROOT, encoding: 'utf8' });
|
|
80
|
+
if (result.status !== 0) return schedules;
|
|
81
|
+
try {
|
|
82
|
+
const crons = JSON.parse(result.stdout).crons;
|
|
83
|
+
if (Array.isArray(crons)) for (const c of crons) schedules.add(cronKey(c));
|
|
84
|
+
} catch {
|
|
85
|
+
// An unparseable baseline file shipped no schedule this turn could preserve.
|
|
86
|
+
}
|
|
87
|
+
return schedules;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function cronKey(entry) {
|
|
91
|
+
return `${entry?.path}\n${typeof entry?.schedule === 'string' ? entry.schedule.trim() : ''}`;
|
|
92
|
+
}
|
|
93
|
+
|
|
68
94
|
// Whether this turn changed vercel.json or a cron route: commits since the
|
|
69
95
|
// baseline plus whatever is still uncommitted. No baseline means no turn (a
|
|
70
96
|
// Vercel build, a clone bootstrap), so nothing is the agent's to fix. A git
|
|
@@ -226,6 +252,8 @@ if (crons !== undefined && !Array.isArray(crons)) {
|
|
|
226
252
|
}
|
|
227
253
|
const entries = Array.isArray(crons) ? crons : [];
|
|
228
254
|
const coveredRoutes = new Set();
|
|
255
|
+
const shippedSchedules = baselineCronSchedules();
|
|
256
|
+
const preexistingIntervals = [];
|
|
229
257
|
|
|
230
258
|
entries.forEach((entry, i) => {
|
|
231
259
|
const label = `vercel.json crons[${i}]`;
|
|
@@ -251,10 +279,12 @@ entries.forEach((entry, i) => {
|
|
|
251
279
|
if (interval === null) {
|
|
252
280
|
problems.push(`${label} (${entry.path}): "${entry.schedule}" is not a valid 5-field cron expression.`);
|
|
253
281
|
} else if (interval < MIN_INTERVAL_MINUTES) {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
282
|
+
const finding = `${label} (${entry.path}): "${entry.schedule}" fires every ${interval} minutes; the floor is every ${MIN_INTERVAL_MINUTES}.`;
|
|
283
|
+
if (shippedSchedules.has(cronKey(entry))) {
|
|
284
|
+
preexistingIntervals.push(`${finding} The app already shipped this schedule, so leave it unchanged.`);
|
|
285
|
+
} else {
|
|
286
|
+
problems.push(`${finding} Use "*/30 * * * *" and keep per-action cadences in the app's schedule table.`);
|
|
287
|
+
}
|
|
258
288
|
}
|
|
259
289
|
});
|
|
260
290
|
|
|
@@ -281,4 +311,5 @@ if (entries.length > 0) {
|
|
|
281
311
|
}
|
|
282
312
|
}
|
|
283
313
|
|
|
314
|
+
if (preexistingIntervals.length > 0) report(preexistingIntervals, { fatal: false });
|
|
284
315
|
if (problems.length > 0) report(problems, { fatal: cronWiringChangedThisTurn() });
|