diff --git a/cli/lib/cross-store.ts b/cli/lib/cross-store.ts index af8e504..c35043f 100644 --- a/cli/lib/cross-store.ts +++ b/cli/lib/cross-store.ts @@ -84,7 +84,7 @@ export function textMentions(text: string, o: { store: CrossStore; locale: strin const add = (term: string): void => { out.push({ store: o.store, locale: o.locale, field: o.field, line: i + 1, term, text: line.slice(0, 200), fix: fixFor(o.store, o.field) }); }; const tag = OTHER_TAG[o.store].exec(line); if (tag) add(`[${tag[1]}]`); - for (const { term, re } of COMPILED[o.store]) { + for (const { re } of COMPILED[o.store]) { re.lastIndex = 0; for (let m = re.exec(line); m; m = re.exec(line)) { const s = m.index, e = s + m[0].length; diff --git a/tools/release.ts b/tools/release.ts index 41b7dc3..8a3d884 100644 --- a/tools/release.ts +++ b/tools/release.ts @@ -291,6 +291,10 @@ async function main(): Promise { const t = await mainTests(); if (t.state === 'red') say(`WARNING: background tests are red on ${t.sha.slice(0, 10)} (${t.failed.join(', ')}): ${t.run}; releasing anyway, fix it in the next patch`); } catch (e) { say(`background tests: not read (${(e as Error).message.slice(0, 120)})`); } + // the desktop's own typecheck (stricter: unused locals) runs in tauri's beforeBuildCommand: catch it before the tag + // (0.8.14's Mac build stopped on an unused variable after the tag was pushed) + { const t = spawnSync('bunx', ['tsc', '--noEmit', '-p', 'apps/desktop'], { cwd: ROOT, encoding: 'utf8', timeout: 180_000 }); + if (t.status !== 0) fail(`the desktop typecheck fails (the Mac build would stop on it):\n${(t.stdout + t.stderr).trim().split('\n').slice(0, 8).join('\n')}`); } // the dry run catches what the bump would refuse if (!rehearsal && !resume) { try { cutChangelog(readFileSync(join(ROOT, 'CHANGELOG.md'), 'utf8'), version, '2000-01-01'); } catch (e) { fail((e as Error).message); } } if (!yes) { console.log('\ndry run: nothing changed (--yes to release)'); return; } @@ -431,6 +435,9 @@ async function npmRelease(version: string, token: string): Promise { const who = npmRun(['whoami'], token); if (who.code !== 0) fail(`npm token refused (npm whoami): ${who.out.trim().split('\n').slice(-2).join(' ')}; make a new one: bun tools/release.ts npm-token`); const pub = npmRun(['publish'], token); + // npm stages a token publish for the maintainer's approval on npmjs.com (409 "previously staged version" on a retry): + // nothing to wait for here, the owner approves it once + if (/staged/i.test(pub.out)) { say(`npm: ${version} is staged and waits for the maintainer's approval: https://www.npmjs.com/package/storebound (approve it there; then deprecate runs with: bun tools/release.ts npm-publish)`); return; } if (pub.code !== 0 && !/previously published|cannot publish over/i.test(pub.out)) fail(`npm publish failed: ${pub.out.trim().split('\n').slice(-4).join(' ')}`); // the registry lags a little after a publish; wait (timeout, heartbeat) until it serves the version as latest const end = Date.now() + 5 * 60_000;