From ecda14243becf8f80edc97cbd544509d7123cee2 Mon Sep 17 00:00:00 2001 From: Jimmy Ho Date: Wed, 23 Sep 2026 10:14:45 -0500 Subject: [PATCH] fix: drop audit from the standalone starter's release gate The bare starter (#503, "simplify init to one bare starter") scaffolds with zero example routes by design. urlcode audit refuses "ready" for any project with no active routes regardless of --expect-routes, so npm run audit can never pass for it. This made the "pin starter to new core version" step of every release fail after a successful npm publish (observed pinning 0.5.8: #512). validate and test still gate the pin; audit still works fine run standalone. Co-Authored-By: Claude Sonnet 5 --- docs/DEVELOPMENT-PIPELINE.md | 4 +++- scripts/release-template.ts | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/DEVELOPMENT-PIPELINE.md b/docs/DEVELOPMENT-PIPELINE.md index 60cd897c..0909eaad 100644 --- a/docs/DEVELOPMENT-PIPELINE.md +++ b/docs/DEVELOPMENT-PIPELINE.md @@ -352,7 +352,9 @@ schema/docs links, then copies the initializer's application files, generated agent guide, skills and local MCP registration from the installed published core package. The committed generated-file manifest also removes app files deleted from the initializer. Template-owned packaging, CI and onboarding files remain -untouched. It then runs validation/tests/audit/benchmark, +untouched. It then runs validation/tests/benchmark (not `audit`: the bare +starter ships with zero example routes by design, and `urlcode audit` refuses +"ready" for any project with no active routes regardless of `--expect-routes`), and opens a resumable PR. The coordinator waits for checks and merges it, checking for a newer template pin immediately before merge. `--skip-template` explicitly leaves this follow-up to the maintainer. To run only that follow-up: diff --git a/scripts/release-template.ts b/scripts/release-template.ts index a69228f2..d873a054 100644 --- a/scripts/release-template.ts +++ b/scripts/release-template.ts @@ -178,13 +178,16 @@ export async function updateTemplate(version: string, options: { execute?: boole assertTemplateLock(version, JSON.parse(await readFile(join(directory, 'package-lock.json'), 'utf8'))); run('npm', ['ci', '--ignore-scripts', '--registry=https://registry.npmjs.org']); await copyPublishedTemplateGuide(directory, version); - for (const script of ['validate', 'test', 'audit']) run('npm', ['run', script]); + // Not `audit`: the bare starter (#503) ships with zero example routes by design, and + // `urlcode audit` refuses "ready" for any project with no active routes regardless of + // --expect-routes, so it can never pass here. `npm run audit` still works standalone. + for (const script of ['validate', 'test']) run('npm', ['run', script]); run('npm', ['run', 'benchmark', '--', '--requests', '50', '--concurrency', '2']); run('git', ['add', '--all']); if (run('git', ['status', '--porcelain']).trim()) run('git', [...releaseIdentity, 'commit', '-m', `Pin starter runtime to ${version}`]); run('git', ['push', 'origin', branch]); // Never force an existing branch. const body = join(directory, '.git', 'release-pr.md'); - await writeFile(body, `Pin the standalone starter to @jimhoyd/urlcode@${version}, refresh its lockfile and matching schema/documentation references, and synchronize the generated authoring guide, skills and MCP registration.\n\nValidation: npm ci, validate, test, audit and a 50-request benchmark passed against the published package.\n`); + await writeFile(body, `Pin the standalone starter to @jimhoyd/urlcode@${version}, refresh its lockfile and matching schema/documentation references, and synchronize the generated authoring guide, skills and MCP registration.\n\nValidation: npm ci, validate, test and a 50-request benchmark passed against the published package.\n`); const url = run('gh', ['pr', 'create', '--repo', repository, '--head', branch, '--base', 'main', '--title', `Pin starter runtime to ${version}`, '--body-file', body]).trim(); const pr = JSON.parse(gh(['pr', 'view', url, '--repo', repository, '--json', 'url,number,headRefOid'])) as { url: string; number: number; headRefOid: string }; return { url: pr.url, number: pr.number, head: pr.headRefOid };