breakage 0.0.0 → 0.8.2

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.
@@ -1 +0,0 @@
1
- {"version":3,"file":"breakage-D_nc-zEK.js","names":["latestReleaseTag","selectLatestReleaseTag"],"sources":["../src/directory-lock.ts","../src/release-tag.ts","../src/test-file-state.ts","../src/breakage.ts"],"sourcesContent":["import { mkdir, rmdir } from \"node:fs/promises\"\nimport { setTimeout } from \"node:timers/promises\"\n\nexport async function withDirectoryLock<T>(\n\tlock: string,\n\taction: () => Promise<T>,\n\twaitForCleanup = false,\n): Promise<T> {\n\tconst deadline = Date.now() + 60_000\n\tfor (;;) {\n\t\ttry {\n\t\t\tawait mkdir(lock)\n\t\t\tbreak\n\t\t} catch (thrown) {\n\t\t\tif ((thrown as NodeJS.ErrnoException).code !== `EEXIST`) throw thrown\n\t\t\tif (!waitForCleanup && Date.now() >= deadline) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Timed out waiting for ${lock}. Check for an interrupted operation before removing this lock.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tawait setTimeout(20)\n\t\t}\n\t}\n\ttry {\n\t\treturn await action()\n\t} finally {\n\t\tawait rmdir(lock)\n\t}\n}\n","type Release = { ref: string; core: string[]; prerelease: string[] }\n\nfunction compareInteger(a: string, b: string): number {\n\treturn a.length - b.length || (a > b ? 1 : a < b ? -1 : 0)\n}\n\nfunction compareRelease(a: Release, b: Release): number {\n\tfor (let index = 0; index < 3; index++) {\n\t\tconst difference = compareInteger(a.core[index]!, b.core[index]!)\n\t\tif (difference) return difference\n\t}\n\tif (!a.prerelease.length || !b.prerelease.length) {\n\t\treturn Number(!a.prerelease.length) - Number(!b.prerelease.length)\n\t}\n\tfor (\n\t\tlet index = 0;\n\t\tindex < Math.min(a.prerelease.length, b.prerelease.length);\n\t\tindex++\n\t) {\n\t\tconst left = a.prerelease[index]!\n\t\tconst right = b.prerelease[index]!\n\t\tconst leftNumeric = /^\\d+$/.test(left)\n\t\tconst rightNumeric = /^\\d+$/.test(right)\n\t\tconst difference =\n\t\t\tleftNumeric && rightNumeric\n\t\t\t\t? compareInteger(left, right)\n\t\t\t\t: leftNumeric !== rightNumeric\n\t\t\t\t\t? Number(rightNumeric) - Number(leftNumeric)\n\t\t\t\t\t: left > right\n\t\t\t\t\t\t? 1\n\t\t\t\t\t\t: left < right\n\t\t\t\t\t\t\t? -1\n\t\t\t\t\t\t\t: 0\n\t\tif (difference) return difference\n\t}\n\treturn a.prerelease.length - b.prerelease.length\n}\n\nexport function latestReleaseTag(\n\tremoteTags: string,\n\ttagPattern?: string,\n): string | undefined {\n\tconst pattern = tagPattern ? new RegExp(tagPattern) : undefined\n\tlet latest: Release | undefined\n\tfor (const line of remoteTags.split(`\\n`)) {\n\t\tif (pattern && !pattern.test(line)) continue\n\t\tconst ref = line.split(`\\t`)[1]?.replace(/\\^\\{\\}$/, ``)\n\t\tif (!ref?.startsWith(`refs/tags/`)) continue\n\t\tconst name = ref.slice(`refs/tags/`.length)\n\t\tconst version = name.slice(name.lastIndexOf(`@`) + 1)\n\t\tconst match =\n\t\t\t/^v?(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/.exec(\n\t\t\t\tversion,\n\t\t\t)\n\t\tif (!match) continue\n\t\tconst prerelease = match[4]?.split(`.`) ?? []\n\t\tif (prerelease.some((identifier) => /^0\\d+$/.test(identifier))) continue\n\t\tconst release: Release = { ref, core: match.slice(1, 4), prerelease }\n\t\tif (!latest || compareRelease(release, latest) > 0) latest = release\n\t}\n\treturn latest?.ref\n}\n","import { randomUUID } from \"node:crypto\"\nimport {\n\tchmod,\n\tlstat,\n\tmkdir,\n\treaddir,\n\treadFile,\n\trealpath,\n\trename,\n\trm,\n\twriteFile,\n} from \"node:fs/promises\"\nimport path from \"node:path\"\n\nimport type { SimpleGit } from \"simple-git\"\nimport { simpleGit } from \"simple-git\"\n\nimport { withDirectoryLock } from \"./directory-lock.ts\"\n\ntype ActiveCheck = {\n\tpid: number\n\tpaths: string[]\n\thead: string\n\trecoveryRequired?: boolean\n}\n\nfunction isActiveCheck(value: unknown): value is ActiveCheck {\n\tif (typeof value !== `object` || value === null) return false\n\tconst record = value as Partial<ActiveCheck>\n\treturn (\n\t\ttypeof record.pid === `number` &&\n\t\tNumber.isSafeInteger(record.pid) &&\n\t\trecord.pid > 0 &&\n\t\ttypeof record.head === `string` &&\n\t\t/^[a-f0-9]{40}(?:[a-f0-9]{24})?$/.test(record.head) &&\n\t\t(record.recoveryRequired === undefined ||\n\t\t\ttypeof record.recoveryRequired === `boolean`) &&\n\t\tArray.isArray(record.paths) &&\n\t\trecord.paths.length > 0 &&\n\t\trecord.paths.every(\n\t\t\t(file) =>\n\t\t\t\ttypeof file === `string` &&\n\t\t\t\t!path.isAbsolute(file) &&\n\t\t\t\t!path.win32.isAbsolute(file) &&\n\t\t\t\tfile\n\t\t\t\t\t.split(`/`)\n\t\t\t\t\t.every((part) => part !== `` && part !== `.` && part !== `..`),\n\t\t)\n\t)\n}\n\nasync function readRecoveryRecord(recordPath: string): Promise<ActiveCheck> {\n\ttry {\n\t\tconst record: unknown = JSON.parse(await readFile(recordPath, `utf8`))\n\t\tif (!isActiveCheck(record))\n\t\t\tthrow new TypeError(`Invalid recovery record fields`)\n\t\treturn record\n\t} catch (cause) {\n\t\tthrow new Error(\n\t\t\t`A breakage run needs recovery. The record ${recordPath} is unreadable or invalid. Verify no check is running and recover its test files before removing this record.`,\n\t\t\t{ cause },\n\t\t)\n\t}\n}\n\nasync function writeRecoveryRecord(\n\trecordPath: string,\n\trecord: ActiveCheck,\n): Promise<void> {\n\tconst temporaryPath = `${recordPath}.${randomUUID()}.tmp`\n\ttry {\n\t\tawait writeFile(temporaryPath, JSON.stringify(record), { flag: `wx` })\n\t\tawait rename(temporaryPath, recordPath)\n\t} finally {\n\t\tawait rm(temporaryPath, { force: true })\n\t}\n}\n\ntype TestFileState = {\n\tisClean: () => Promise<boolean>\n\treplaceTests: (\n\t\trelease: string,\n\t\tfiles: string[],\n\t) => Promise<() => Promise<void>>\n}\n\nfunction assertContained(root: string, filename: string): void {\n\tconst relative = path.relative(root, filename)\n\tif (\n\t\trelative === `..` ||\n\t\trelative.startsWith(`..${path.sep}`) ||\n\t\tpath.isAbsolute(relative)\n\t) {\n\t\tthrow new Error(`Cannot replace tests outside the worktree: ${filename}.`)\n\t}\n}\n\nasync function validateParents(\n\troot: string,\n\tfilenames: string[],\n): Promise<void> {\n\tconst checked = new Set<string>()\n\tfor (const filename of filenames) {\n\t\tassertContained(root, filename)\n\t\tfor (let parent = path.dirname(filename); ; parent = path.dirname(parent)) {\n\t\t\tif (checked.has(parent)) break\n\t\t\tconst stats = await lstat(parent).catch(\n\t\t\t\t(thrown: NodeJS.ErrnoException) => {\n\t\t\t\t\tif (thrown.code !== `ENOENT`) throw thrown\n\t\t\t\t},\n\t\t\t)\n\t\t\tif (stats && !stats.isDirectory())\n\t\t\t\tthrow new Error(`Cannot replace tests through ${parent}.`)\n\t\t\tchecked.add(parent)\n\t\t\tif (parent === root) break\n\t\t}\n\t}\n}\n\n// This lock covers Git setup and restoration only. Commands run after it is released.\nexport async function withTestFileState<T>(\n\tgit: SimpleGit,\n\tbaseDirname: string,\n\taction: (state: TestFileState) => Promise<T>,\n): Promise<T> {\n\tconst root = await realpath(await git.revparse([`--show-toplevel`]))\n\tbaseDirname = await realpath(baseDirname)\n\tassertContained(root, baseDirname)\n\tconst stateDirectory = path.join(\n\t\tawait git.revparse([`--absolute-git-dir`]),\n\t\t`breakage`,\n\t)\n\tawait mkdir(stateDirectory, { recursive: true })\n\tconst lock = path.join(stateDirectory, `lock`)\n\treturn withDirectoryLock(lock, async () => {\n\t\tconst activeChecks: ActiveCheck[] = []\n\t\tfor (const entry of await readdir(stateDirectory)) {\n\t\t\tif (!entry.endsWith(`.json`)) continue\n\t\t\tconst recordPath = path.join(stateDirectory, entry)\n\t\t\tconst record = await readRecoveryRecord(recordPath)\n\t\t\tlet interrupted = record.recoveryRequired\n\t\t\ttry {\n\t\t\t\tprocess.kill(record.pid, 0)\n\t\t\t} catch (thrown) {\n\t\t\t\tif ((thrown as NodeJS.ErrnoException).code !== `EPERM`)\n\t\t\t\t\tinterrupted = true\n\t\t\t}\n\t\t\tif (interrupted)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`A breakage run needs recovery. Restore the test paths recorded in ${recordPath} before removing that record.`,\n\t\t\t\t)\n\t\t\tactiveChecks.push(record)\n\t\t}\n\t\tconst activePaths = activeChecks.flatMap((record) => record.paths)\n\t\treturn action({\n\t\t\tisClean: async () =>\n\t\t\t\t!(await simpleGit(root).raw([\n\t\t\t\t\t`--no-optional-locks`,\n\t\t\t\t\t`status`,\n\t\t\t\t\t`--porcelain`,\n\t\t\t\t\t`--untracked-files=all`,\n\t\t\t\t\t`--`,\n\t\t\t\t\t`.`,\n\t\t\t\t\t...activePaths.map((file) => `:(top,literal,exclude)${file}`),\n\t\t\t\t])),\n\t\t\treplaceTests: async (release, files) => {\n\t\t\t\tconst paths = files.map((file) =>\n\t\t\t\t\tpath\n\t\t\t\t\t\t.relative(root, path.resolve(baseDirname, file))\n\t\t\t\t\t\t.split(path.sep)\n\t\t\t\t\t\t.join(`/`),\n\t\t\t\t)\n\t\t\t\tfor (const file of paths) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tactivePaths.some(\n\t\t\t\t\t\t\t(active) =>\n\t\t\t\t\t\t\t\tfile === active ||\n\t\t\t\t\t\t\t\tfile.startsWith(`${active}/`) ||\n\t\t\t\t\t\t\t\tactive.startsWith(`${file}/`),\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Another breakage run is using ${file}. Concurrent checks must use disjoint test paths.`,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst head = await git.revparse([`HEAD`])\n\t\t\t\tconst currentFiles = new Set(\n\t\t\t\t\t(await git.raw([`ls-tree`, `-r`, `--name-only`, `-z`, head]))\n\t\t\t\t\t\t.split(`\\0`)\n\t\t\t\t\t\t.filter(Boolean),\n\t\t\t\t)\n\t\t\t\tconst existing = files.filter((file) => currentFiles.has(file))\n\t\t\t\tconst absent = files.filter((file) => !currentFiles.has(file))\n\t\t\t\tconst modes = new Map<string, number>()\n\t\t\t\tconst filenames = files.map((file) => path.resolve(baseDirname, file))\n\t\t\t\tawait validateParents(root, filenames)\n\t\t\t\tfor (const file of files) {\n\t\t\t\t\tconst filename = path.resolve(baseDirname, file)\n\n\t\t\t\t\tconst stats = await lstat(filename).catch(\n\t\t\t\t\t\t(thrown: NodeJS.ErrnoException) => {\n\t\t\t\t\t\t\tif (thrown.code !== `ENOENT`) throw thrown\n\t\t\t\t\t\t},\n\t\t\t\t\t)\n\t\t\t\t\tif (!currentFiles.has(file) && stats)\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Cannot overwrite the existing untracked path ${filename}.`,\n\t\t\t\t\t\t)\n\t\t\t\t\tif (stats?.isFile()) modes.set(filename, stats.mode)\n\t\t\t\t}\n\t\t\t\tconst recordPath = path.join(stateDirectory, `${randomUUID()}.json`)\n\t\t\t\tconst record: ActiveCheck = { pid: process.pid, paths, head }\n\t\t\t\tawait writeRecoveryRecord(recordPath, record)\n\t\t\t\tconst restore = async () => {\n\t\t\t\t\tawait writeRecoveryRecord(recordPath, {\n\t\t\t\t\t\t...record,\n\t\t\t\t\t\trecoveryRequired: true,\n\t\t\t\t\t})\n\t\t\t\t\tawait validateParents(root, filenames)\n\t\t\t\t\tif (existing.length)\n\t\t\t\t\t\tawait git.raw([\n\t\t\t\t\t\t\t`--literal-pathspecs`,\n\t\t\t\t\t\t\t`restore`,\n\t\t\t\t\t\t\t`--source=${head}`,\n\t\t\t\t\t\t\t`--worktree`,\n\t\t\t\t\t\t\t`--`,\n\t\t\t\t\t\t\t...existing,\n\t\t\t\t\t\t])\n\t\t\t\t\tfor (const file of absent)\n\t\t\t\t\t\tawait rm(path.resolve(baseDirname, file), { force: true })\n\t\t\t\t\tfor (const [filename, mode] of modes) await chmod(filename, mode)\n\t\t\t\t\tawait rm(recordPath)\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tawait git.raw([\n\t\t\t\t\t\t`--literal-pathspecs`,\n\t\t\t\t\t\t`restore`,\n\t\t\t\t\t\t`--source=${release}`,\n\t\t\t\t\t\t`--worktree`,\n\t\t\t\t\t\t`--`,\n\t\t\t\t\t\t...files,\n\t\t\t\t\t])\n\t\t\t\t} catch (thrown) {\n\t\t\t\t\tawait restore()\n\t\t\t\t\tthrow thrown\n\t\t\t\t}\n\t\t\t\treturn () => withDirectoryLock(lock, restore, true)\n\t\t\t},\n\t\t})\n\t})\n}\n","import { exec } from \"node:child_process\"\nimport path from \"node:path\"\n\nimport { minimatch } from \"minimatch\"\nimport { simpleGit } from \"simple-git\"\nimport type { Chronicle } from \"takua\"\nimport logger from \"takua\"\n\nimport { withDirectoryLock } from \"./directory-lock.ts\"\nimport { latestReleaseTag as selectLatestReleaseTag } from \"./release-tag.ts\"\nimport { withTestFileState } from \"./test-file-state.ts\"\n\nexport type BreakageOptions = {\n\ttagPattern?: string | undefined\n\ttestPattern: string\n\ttestCommand: string\n\tcertifyCommand: string\n\tbaseDirname?: string\n\tverbose?: boolean | undefined\n}\n\nexport type BreakageOutcome =\n\t| { gitWasClean: false }\n\t| {\n\t\t\tgitWasClean: true\n\t\t\tlastReleaseFound: false\n\t }\n\t| {\n\t\t\tgitWasClean: true\n\t\t\tlastReleaseFound: true\n\t\t\tlastReleaseTag: string\n\t\t\ttestsWereFound: false\n\t }\n\t| {\n\t\t\tgitWasClean: true\n\t\t\tlastReleaseFound: true\n\t\t\tlastReleaseTag: string\n\t\t\ttestsWereFound: true\n\t\t\ttestsFound: string[]\n\t\t\tbreakingChangesFound: false\n\t }\n\t| {\n\t\t\tgitWasClean: true\n\t\t\tlastReleaseFound: true\n\t\t\tlastReleaseTag: string\n\t\t\ttestsWereFound: true\n\t\t\ttestsFound: string[]\n\t\t\tbreakingChangesFound: true\n\t\t\ttestResult: string\n\t\t\tbreakingChangesCertified: boolean\n\t\t\tcertificationStdout: string\n\t\t\tcertificationStderr: string\n\t }\n\nexport async function breakage({\n\ttagPattern,\n\ttestPattern,\n\ttestCommand,\n\tcertifyCommand,\n\tbaseDirname = process.cwd(),\n\tverbose = false,\n}: BreakageOptions): Promise<BreakageOutcome & { summary: string }> {\n\tlet mark: Chronicle[`mark`] | undefined\n\tlet logMarks: Chronicle[`logMarks`] | undefined\n\tif (verbose) {\n\t\tconst chronicle = logger.makeChronicle()\n\t\tmark = chronicle.mark\n\t\tlogMarks = chronicle.logMarks\n\t}\n\tmark?.(`breakage`)\n\tconst git = simpleGit(baseDirname)\n\tmark?.(`spawn git`)\n\tconst isGitRepo = await git.checkIsRepo()\n\tmark?.(`is git repository`)\n\tif (!isGitRepo) {\n\t\treturn {\n\t\t\tsummary: `The git repository must be clean to run this command.`,\n\t\t\tgitWasClean: false,\n\t\t}\n\t}\n\tif (\n\t\t!(await withTestFileState(git, baseDirname, (state) => state.isClean()))\n\t) {\n\t\treturn {\n\t\t\tsummary: `The git repository must be clean to run this command.`,\n\t\t\tgitWasClean: false,\n\t\t}\n\t}\n\tconst tagsRemote = await git.listRemote([`--tags`, `origin`])\n\n\tmark?.(`list remote tags`)\n\tconst latestReleaseTag = selectLatestReleaseTag(tagsRemote, tagPattern)\n\tmark?.(`found latest release tag`)\n\tif (!latestReleaseTag) {\n\t\treturn {\n\t\t\tsummary: `No tags found matching the pattern \"${tagPattern}\".`,\n\t\t\tgitWasClean: true,\n\t\t\tlastReleaseFound: false,\n\t\t} as const\n\t}\n\tconst commonGitDirectory = await git.revparse([\n\t\t`--path-format=absolute`,\n\t\t`--git-common-dir`,\n\t])\n\tawait withDirectoryLock(\n\t\tpath.join(commonGitDirectory, `breakage-fetch.lock`),\n\t\t() =>\n\t\t\tgit.fetch([\n\t\t\t\t`origin`,\n\t\t\t\t`${latestReleaseTag}:${latestReleaseTag}`,\n\t\t\t\t`--no-tags`,\n\t\t\t\t`--no-write-fetch-head`,\n\t\t\t]),\n\t)\n\n\tmark?.(`fetched latest release tag`)\n\n\tlet productionFiles: string[]\n\ttry {\n\t\tproductionFiles = (\n\t\t\tawait git.raw([`ls-tree`, `-r`, `--name-only`, `-z`, latestReleaseTag])\n\t\t)\n\t\t\t.split(`\\0`)\n\t\t\t.filter(Boolean)\n\t} catch (thrown) {\n\t\tmark?.(`failed to list production files`)\n\t\tconst message =\n\t\t\tthrown instanceof Error\n\t\t\t\t? thrown.message\n\t\t\t\t: typeof thrown === `string`\n\t\t\t\t\t? thrown\n\t\t\t\t\t: undefined\n\t\tconst summary = `Failed to list production files${\n\t\t\tmessage ? `: ${message}` : `.`\n\t\t}`\n\t\treturn {\n\t\t\tsummary,\n\t\t\tgitWasClean: true,\n\t\t\tlastReleaseFound: true,\n\t\t\tlastReleaseTag: latestReleaseTag,\n\t\t\ttestsWereFound: false,\n\t\t} as const\n\t}\n\tmark?.(`listed all files checked into git`)\n\tconst productionTestFiles = productionFiles.filter((file) =>\n\t\tminimatch(file, testPattern),\n\t)\n\tmark?.(`filtered to public test files`)\n\n\tconst prepared = await withTestFileState(git, baseDirname, async (state) => {\n\t\tif (!(await state.isClean())) {\n\t\t\treturn {\n\t\t\t\tsummary: `The git repository must be clean to run this command.`,\n\t\t\t\tgitWasClean: false,\n\t\t\t} as const\n\t\t}\n\n\t\tif (productionTestFiles.length === 0) {\n\t\t\treturn {\n\t\t\t\tsummary: `No tests were found matching the pattern \"${testPattern}\".`,\n\t\t\t\tgitWasClean: true,\n\t\t\t\tlastReleaseFound: true,\n\t\t\t\tlastReleaseTag: latestReleaseTag,\n\t\t\t\ttestsWereFound: false,\n\t\t\t} as const\n\t\t}\n\t\tconst restore = await state.replaceTests(\n\t\t\tlatestReleaseTag,\n\t\t\tproductionTestFiles,\n\t\t)\n\t\tmark?.(`restored public tests from latest release tag`)\n\t\treturn { latestReleaseTag, productionTestFiles, restore }\n\t})\n\tif (prepared.summary !== undefined) return prepared\n\tconst { restore } = prepared\n\n\ttry {\n\t\tconst noBreakingChangesDetected = await new Promise<\n\t\t\tBreakageOutcome & { summary: string }\n\t\t>((resolve, reject) => {\n\t\t\tconst result = exec(\n\t\t\t\ttestCommand,\n\t\t\t\t{ cwd: baseDirname },\n\t\t\t\t(_, __, stderr) => {\n\t\t\t\t\tif (result.exitCode === 0) {\n\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\tsummary: `No breaking changes were detected.`,\n\t\t\t\t\t\t\tgitWasClean: true,\n\t\t\t\t\t\t\tlastReleaseFound: true,\n\t\t\t\t\t\t\tlastReleaseTag: latestReleaseTag,\n\t\t\t\t\t\t\ttestsWereFound: true,\n\t\t\t\t\t\t\ttestsFound: productionTestFiles,\n\t\t\t\t\t\t\tbreakingChangesFound: false,\n\t\t\t\t\t\t})\n\t\t\t\t\t} else {\n\t\t\t\t\t\treject(stderr)\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t)\n\t\t})\n\t\tmark?.(`passed tests`)\n\t\treturn noBreakingChangesDetected\n\t} catch (thrown) {\n\t\tmark?.(`failed tests`)\n\t\tconst breakingChangesCertified = await new Promise<\n\t\t\tBreakageOutcome & { summary: string }\n\t\t>((resolve) => {\n\t\t\tconst result = exec(\n\t\t\t\tcertifyCommand,\n\t\t\t\t{ cwd: baseDirname },\n\t\t\t\t(_, stdout, stderr) => {\n\t\t\t\t\tconst wereCertified = result.exitCode === 0\n\t\t\t\t\tmark?.(`${wereCertified ? `passed` : `failed`} certification`)\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tsummary: wereCertified\n\t\t\t\t\t\t\t? `Breaking changes were found and certified.`\n\t\t\t\t\t\t\t: `Breaking changes were found, but not certified.`,\n\t\t\t\t\t\tgitWasClean: true,\n\t\t\t\t\t\tlastReleaseFound: true,\n\t\t\t\t\t\tlastReleaseTag: latestReleaseTag,\n\t\t\t\t\t\ttestsWereFound: true,\n\t\t\t\t\t\ttestsFound: productionTestFiles,\n\t\t\t\t\t\tbreakingChangesFound: true,\n\t\t\t\t\t\ttestResult: thrown as string,\n\t\t\t\t\t\tbreakingChangesCertified: wereCertified,\n\t\t\t\t\t\tcertificationStdout: stdout,\n\t\t\t\t\t\tcertificationStderr: stderr,\n\t\t\t\t\t})\n\t\t\t\t},\n\t\t\t)\n\t\t})\n\t\treturn breakingChangesCertified\n\t} finally {\n\t\tawait restore()\n\t\tmark?.(`restored original public tests`)\n\t\tlogMarks?.()\n\t}\n}\n"],"mappings":"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"}