From e311efca98c444edca3f35703e9fd981ad084d3b Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Thu, 26 Feb 2026 15:17:37 -0800 Subject: [PATCH 01/11] feat: support workflow_dispatch events --- actions/apidiff-go/src/event.ts | 11 ++++++++++- actions/apidiff-go/src/run.ts | 10 ++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/actions/apidiff-go/src/event.ts b/actions/apidiff-go/src/event.ts index 273e6d70..b93727e3 100644 --- a/actions/apidiff-go/src/event.ts +++ b/actions/apidiff-go/src/event.ts @@ -1,7 +1,7 @@ import * as github from "@actions/github"; import { PushEvent, PullRequestEvent } from "@octokit/webhooks-types"; -export type EventData = PullRequestEventData | PushEventData; +export type EventData = PullRequestEventData | PushEventData | WorkflowDispatchEventData; export interface PullRequestEventData { eventName: "pull_request"; @@ -16,6 +16,10 @@ export interface PushEventData { head: string; } +export interface WorkflowDispatchEventData { + eventName: "workflow_dispatch"; +} + /** * This determines the relevant event data from the event payload, used to determine the changed files. */ @@ -46,6 +50,11 @@ export function getEventData(): EventData { head: pushEvent.after, }; + case "workflow_dispatch": + return { + eventName: "workflow_dispatch", + }; + default: throw new Error(`Unsupported event type: ${context.eventName}`); } diff --git a/actions/apidiff-go/src/run.ts b/actions/apidiff-go/src/run.ts index 3c65a72b..6c7bfea4 100644 --- a/actions/apidiff-go/src/run.ts +++ b/actions/apidiff-go/src/run.ts @@ -30,6 +30,16 @@ export async function run(): Promise { await validateGitRepositoryRoot(inputs.repositoryRoot); + if (context.event.eventName === "workflow_dispatch") { + if (!inputs.headRefOverride) { + core.error("head-ref-override input is required for workflow_dispatch events."); + } + if (!inputs.baseRefOverride) { + core.error("base-ref-override input is required for workflow_dispatch events."); + } + throw new Error("Missing required inputs for workflow_dispatch event."); + }; + const qualifiedModuleDirectory = join( inputs.repositoryRoot, inputs.moduleDirectory, From 5f996ff62d5aebce070e53b4de7786321b720d96 Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Thu, 26 Feb 2026 15:35:23 -0800 Subject: [PATCH 02/11] feat: add ref and sha to summary output --- actions/apidiff-go/src/apidiff.ts | 4 +++- actions/apidiff-go/src/git.ts | 4 ++-- actions/apidiff-go/src/run.ts | 2 +- actions/apidiff-go/src/string-processor.ts | 19 +++++++++++++++++++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/actions/apidiff-go/src/apidiff.ts b/actions/apidiff-go/src/apidiff.ts index 90e2dbdb..545f3685 100644 --- a/actions/apidiff-go/src/apidiff.ts +++ b/actions/apidiff-go/src/apidiff.ts @@ -15,6 +15,7 @@ export type ExportFile = { path: string; normalizedRef: string; ref: string; + resolvedRef: string; }; export async function generateExportAtRef( @@ -27,7 +28,7 @@ export async function generateExportAtRef( `Generating export (${outFile}) for module at ${modulePath}, at ref ${ref}.`, ); - await checkoutRef(modulePath, ref); + const resolvedRef = await checkoutRef(modulePath, ref); await execa("apidiff", ["-m", "-w", outFile, "."], { cwd: modulePath, }); @@ -36,6 +37,7 @@ export async function generateExportAtRef( path: join(modulePath, outFile), normalizedRef, ref, + resolvedRef, }; } diff --git a/actions/apidiff-go/src/git.ts b/actions/apidiff-go/src/git.ts index 4b5e9900..f1fab899 100644 --- a/actions/apidiff-go/src/git.ts +++ b/actions/apidiff-go/src/git.ts @@ -105,14 +105,14 @@ async function isCommitSha(repoDir: string, ref: string): Promise { /** * Checks out the specified ref in the repository */ -export async function checkoutRef(repoDir: string, ref: string): Promise { +export async function checkoutRef(repoDir: string, ref: string): Promise { core.info(`Checking out ref: ${ref}`); try { const resolvedRef = await resolveRef(repoDir, ref); await execa("git", ["checkout", resolvedRef], { cwd: repoDir }); - core.info(`Successfully checked out: ${resolvedRef}`); + return resolvedRef; } catch (error) { throw new Error(`Failed to checkout ref ${ref}: ${error}`); } diff --git a/actions/apidiff-go/src/run.ts b/actions/apidiff-go/src/run.ts index 6c7bfea4..796238a6 100644 --- a/actions/apidiff-go/src/run.ts +++ b/actions/apidiff-go/src/run.ts @@ -107,7 +107,7 @@ export async function run(): Promise { // 4. Format and output results core.startGroup("Formatting and Outputting Results"); - formatApidiffJobSummary(parsedResult); + formatApidiffJobSummary(parsedResult, `${baseRef} (${baseExport.resolvedRef})`, `${headRef} (${headExport.resolvedRef})`); if (context.event.eventName === "pull_request") { const markdownOutputIncompatibleOnly = formatApidiffMarkdown( diff --git a/actions/apidiff-go/src/string-processor.ts b/actions/apidiff-go/src/string-processor.ts index e2742f0f..7408408c 100644 --- a/actions/apidiff-go/src/string-processor.ts +++ b/actions/apidiff-go/src/string-processor.ts @@ -152,6 +152,8 @@ export function formatApidiffMarkdown( */ export async function formatApidiffJobSummary( diff: ApiDiffResult, + baseRef: string, + headRef: string, ): Promise { const s = core.summary; @@ -164,6 +166,14 @@ export async function formatApidiffJobSummary( "
No changes detected for this module
", true, ); + s.addTable([ + [ + { data: "Ref", header: true }, + { data: "Value", header: true }, + ], + [{ data: "Base" }, { data: `${escapeHtml(baseRef)}` }], + [{ data: "Head" }, { data: `${escapeHtml(headRef)}` }], + ]); await s.write(); return; } @@ -171,6 +181,15 @@ export async function formatApidiffJobSummary( const statusEmoji = hasIncompat ? "⚠️" : "✅"; s.addHeading(`${statusEmoji} API Diff Results – ${diff.moduleName}`, 2); + s.addTable([ + [ + { data: "Ref", header: true }, + { data: "Value", header: true }, + ], + [{ data: "Base" }, { data: `${escapeHtml(baseRef)}` }], + [{ data: "Head" }, { data: `${escapeHtml(headRef)}` }], + ]); + // Top summary table for this module function simpleTableRow(title: string, content: number): { data: string }[] { return [{ data: title }, { data: `
${content}
` }]; From 56279df3ef6acfa84a96a43b654a682dacd69542 Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Thu, 26 Feb 2026 15:36:32 -0800 Subject: [PATCH 03/11] fix: simplify determination of head/base ref --- actions/apidiff-go/src/run.ts | 41 ++++++++++------------------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/actions/apidiff-go/src/run.ts b/actions/apidiff-go/src/run.ts index 796238a6..005218ee 100644 --- a/actions/apidiff-go/src/run.ts +++ b/actions/apidiff-go/src/run.ts @@ -30,16 +30,6 @@ export async function run(): Promise { await validateGitRepositoryRoot(inputs.repositoryRoot); - if (context.event.eventName === "workflow_dispatch") { - if (!inputs.headRefOverride) { - core.error("head-ref-override input is required for workflow_dispatch events."); - } - if (!inputs.baseRefOverride) { - core.error("base-ref-override input is required for workflow_dispatch events."); - } - throw new Error("Missing required inputs for workflow_dispatch event."); - }; - const qualifiedModuleDirectory = join( inputs.repositoryRoot, inputs.moduleDirectory, @@ -48,6 +38,10 @@ export async function run(): Promise { const moduleName = await getGoModuleName(qualifiedModuleDirectory); core.info(`Module name: ${moduleName}`); + const headRef = determineRef("head", context, inputs.headRefOverride); + const baseRef = determineRef("base", context, inputs.baseRefOverride); + core.info(`Head ref: ${headRef}, Base ref: ${baseRef}`); + core.endGroup(); // 2. Install apidiff tool @@ -57,14 +51,13 @@ export async function run(): Promise { // 3. Generate exports core.startGroup("Generating Exports"); - const headRef = inputs.headRefOverride || context.event.head; + const headExport = await generateExportAtRef( qualifiedModuleDirectory, headRef, ); core.info(`Generated head export at: ${headExport.path}`); - const baseRef = inputs.baseRefOverride || context.event.base; const baseExport = await generateExportAtRef( qualifiedModuleDirectory, baseRef, @@ -150,23 +143,13 @@ export async function run(): Promise { } } -// TODO: support comparing against latest tagged version (DX-2323) -async function generateExportForLatestVersion( - context: InvokeContext, - repositoryRoot: string, - moduleDirectory: string, -) { - if (context.event.eventName !== "push") { - return null; + +function determineRef(property: "head" | "base", context: ReturnType, override?: string) { + if (override) { + return override; } - core.info("Push event detected. Diffing with latest tagged version."); - const tags = await getRepoTags(repositoryRoot); - const latest = findLatestVersionFromTags(moduleDirectory, tags); - if (!latest) { - core.info("Latest version not found. Skipping export generation."); - return null; + if (context.event.eventName === "workflow_dispatch") { + throw new Error(`Missing required ${property}-ref-override input for workflow_dispatch event.`); } - - const qualifiedModuleDirectory = join(repositoryRoot, moduleDirectory); - return generateExportAtRef(qualifiedModuleDirectory, latest.tag); + return context.event[property]; } From 475110d9ca8a6ce98d26223ddaf40a8344f99e5a Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Thu, 26 Feb 2026 15:37:32 -0800 Subject: [PATCH 04/11] chore: cleanup unused stuff --- actions/apidiff-go/src/run.ts | 24 +++-------------------- actions/apidiff-go/src/util.ts | 35 ---------------------------------- 2 files changed, 3 insertions(+), 56 deletions(-) diff --git a/actions/apidiff-go/src/run.ts b/actions/apidiff-go/src/run.ts index 005218ee..e74b6a62 100644 --- a/actions/apidiff-go/src/run.ts +++ b/actions/apidiff-go/src/run.ts @@ -8,8 +8,9 @@ import { parseApidiffOutput, installApidiff, diffExports, + ApiDiffResult, } from "./apidiff"; -import { validateGitRepositoryRoot, getRepoTags } from "./git"; +import { validateGitRepositoryRoot } from "./git"; import { upsertPRComment } from "./github"; import { CL_LOCAL_DEBUG, getInputs, getInvokeContext } from "./run-inputs"; import { @@ -17,9 +18,8 @@ import { formatApidiffJobSummary, } from "./string-processor"; -import { findLatestVersionFromTags, getGoModuleName } from "./util"; +import { getGoModuleName } from "./util"; -import type { InvokeContext, RunInputs } from "./run-inputs"; export async function run(): Promise { try { // 1. Get inputs and context @@ -63,16 +63,6 @@ export async function run(): Promise { baseRef, ); core.info(`Generated base export at: ${baseExport.path}`); - - // TODO: support comparing against latest tagged version (DX-2323) - // const latestExport = await generateExportForLatestVersion( - // context, - // inputs.repositoryRoot, - // inputs.moduleDirectory, - // ); - // if (latestExport) { - // core.info(`Generated latest version export at: ${latestExport.path}`); - // } core.endGroup(); // 4. Diff and parse export @@ -80,14 +70,6 @@ export async function run(): Promise { core.info(`Diffing base (${baseExport.ref}) -> head (${headExport.ref})`); const baseHeadDiff = await diffExports(baseExport, headExport); - // TODO: support comparing against latest tagged version (DX-2323) - // let latestHeadDiff = null; - // if (latestExport) { - // core.info( - // `Diffing latest (${latestExport.ref}) -> head (${headExport.ref})`, - // ); - // latestHeadDiff = await diffExports(latestExport, headExport); - // } core.endGroup(); // 5. Parse apidiff outputs diff --git a/actions/apidiff-go/src/util.ts b/actions/apidiff-go/src/util.ts index 3b4d56e0..1d049c40 100644 --- a/actions/apidiff-go/src/util.ts +++ b/actions/apidiff-go/src/util.ts @@ -3,41 +3,6 @@ import * as semver from "semver"; import { basename, join } from "path"; import { readFileSync, existsSync } from "fs"; -export function findLatestVersionFromTags(modulePath: string, tags: string[]) { - const prefix = `${modulePath}/v`; - core.info( - `Finding latest version with prefix '${prefix}' from ${tags.length} tags.`, - ); - if (tags.length === 0) { - core.info("No tags found."); - return null; - } - - const filteredTags = tags.filter((tag) => tag.startsWith(prefix)); - core.info(`Filtered to ${filteredTags.length} tags with prefix '${prefix}'.`); - core.debug(`Filtered tags: ${filteredTags.join(", ")}`); - - const versions = filteredTags - .map((tag) => tag.slice(prefix.length)) - .filter((v: string) => semver.valid(v) !== null); - core.info(`Found ${versions.length} valid semantic versions for module.`); - core.debug(`Versions found: ${versions.join(", ")}`); - - if (versions.length === 0) { - core.info("No valid semantic versions found for module."); - return null; - } - - const sorted = versions.sort(semver.rcompare); - const latestVersion = sorted[0]; - core.info(`Latest version for module '${modulePath}' is: ${latestVersion}`); - - return { - version: latestVersion, - tag: `${modulePath}/v${latestVersion}`, - }; -} - /** * Extracts the module name from go.mod file */ From 12ee8cbbc54d6dac0301fe2aa0b6edbb614c36fe Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Thu, 26 Feb 2026 15:38:56 -0800 Subject: [PATCH 05/11] misc formatting --- actions/apidiff-go/src/event.ts | 5 ++++- actions/apidiff-go/src/git.ts | 5 ++++- actions/apidiff-go/src/run-inputs.ts | 2 +- actions/apidiff-go/src/run.ts | 22 ++++++++++++++++++---- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/actions/apidiff-go/src/event.ts b/actions/apidiff-go/src/event.ts index b93727e3..f5895b0d 100644 --- a/actions/apidiff-go/src/event.ts +++ b/actions/apidiff-go/src/event.ts @@ -1,7 +1,10 @@ import * as github from "@actions/github"; import { PushEvent, PullRequestEvent } from "@octokit/webhooks-types"; -export type EventData = PullRequestEventData | PushEventData | WorkflowDispatchEventData; +export type EventData = + | PullRequestEventData + | PushEventData + | WorkflowDispatchEventData; export interface PullRequestEventData { eventName: "pull_request"; diff --git a/actions/apidiff-go/src/git.ts b/actions/apidiff-go/src/git.ts index f1fab899..dcc42a5c 100644 --- a/actions/apidiff-go/src/git.ts +++ b/actions/apidiff-go/src/git.ts @@ -105,7 +105,10 @@ async function isCommitSha(repoDir: string, ref: string): Promise { /** * Checks out the specified ref in the repository */ -export async function checkoutRef(repoDir: string, ref: string): Promise { +export async function checkoutRef( + repoDir: string, + ref: string, +): Promise { core.info(`Checking out ref: ${ref}`); try { diff --git a/actions/apidiff-go/src/run-inputs.ts b/actions/apidiff-go/src/run-inputs.ts index 8461a81a..55504df9 100644 --- a/actions/apidiff-go/src/run-inputs.ts +++ b/actions/apidiff-go/src/run-inputs.ts @@ -53,7 +53,7 @@ export function getInvokeContext() { const event = getEventData(); core.info( - `Invoke context: ${JSON.stringify({ token: "****", owner, repo, event }, null, 2)}`, + `Invoke context: ${JSON.stringify({ token: "", owner, repo, event }, null, 2)}`, ); return { token, owner, repo, event }; diff --git a/actions/apidiff-go/src/run.ts b/actions/apidiff-go/src/run.ts index e74b6a62..9c2c6b9b 100644 --- a/actions/apidiff-go/src/run.ts +++ b/actions/apidiff-go/src/run.ts @@ -82,7 +82,16 @@ export async function run(): Promise { // 4. Format and output results core.startGroup("Formatting and Outputting Results"); - formatApidiffJobSummary(parsedResult, `${baseRef} (${baseExport.resolvedRef})`, `${headRef} (${headExport.resolvedRef})`); + + const formattedBaseRef = + baseRef === baseExport.resolvedRef + ? baseRef + : `${baseRef} (${baseExport.resolvedRef})`; + const formattedHeadRef = + headRef === headExport.resolvedRef + ? headRef + : `${headRef} (${headExport.resolvedRef})`; + formatApidiffJobSummary(parsedResult, formattedBaseRef, formattedHeadRef); if (context.event.eventName === "pull_request") { const markdownOutputIncompatibleOnly = formatApidiffMarkdown( @@ -125,13 +134,18 @@ export async function run(): Promise { } } - -function determineRef(property: "head" | "base", context: ReturnType, override?: string) { +function determineRef( + property: "head" | "base", + context: ReturnType, + override?: string, +) { if (override) { return override; } if (context.event.eventName === "workflow_dispatch") { - throw new Error(`Missing required ${property}-ref-override input for workflow_dispatch event.`); + throw new Error( + `Missing required ${property}-ref-override input for workflow_dispatch event.`, + ); } return context.event[property]; } From fd1339b4b6d2edf5c59d6c969353293ebcb4a7b1 Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Thu, 26 Feb 2026 15:40:57 -0800 Subject: [PATCH 06/11] fix: update summary output snapshots --- .../__snapshots__/string-processor.test.ts.snap | 16 ++++++++++++++++ .../src/__tests__/string-processor.test.ts | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/actions/apidiff-go/src/__tests__/__snapshots__/string-processor.test.ts.snap b/actions/apidiff-go/src/__tests__/__snapshots__/string-processor.test.ts.snap index 02df5e7d..c521966c 100644 --- a/actions/apidiff-go/src/__tests__/__snapshots__/string-processor.test.ts.snap +++ b/actions/apidiff-go/src/__tests__/__snapshots__/string-processor.test.ts.snap @@ -3,6 +3,10 @@ exports[`markdown comment & job summary > formats diff as job summary: compatible-1.txt 1`] = ` "# ✅ API Diff Results – compatible-1 TABLE: +Ref | Value +Base | head-ref +Head | base-ref +TABLE: Metric | Count Breaking changes |
0
Compatible changes |
2
@@ -20,6 +24,10 @@ Metadata entries |
0
exports[`markdown comment & job summary > formats diff as job summary: incompatible-1.txt 1`] = ` "# ⚠️ API Diff Results – incompatible-1 TABLE: +Ref | Value +Base | head-ref +Head | base-ref +TABLE: Metric | Count Breaking changes |
2
Compatible changes |
24
@@ -95,6 +103,10 @@ Metadata entries |
0
exports[`markdown comment & job summary > formats diff as job summary: incompatible-2.txt 1`] = ` "# ⚠️ API Diff Results – incompatible-2 TABLE: +Ref | Value +Base | head-ref +Head | base-ref +TABLE: Metric | Count Breaking changes |
56
Compatible changes |
146
@@ -1084,6 +1096,10 @@ error exports[`markdown comment & job summary > formats diff as job summary: incompatible-3.txt 1`] = ` "# ⚠️ API Diff Results – incompatible-3 TABLE: +Ref | Value +Base | head-ref +Head | base-ref +TABLE: Metric | Count Breaking changes |
1
Compatible changes |
6
diff --git a/actions/apidiff-go/src/__tests__/string-processor.test.ts b/actions/apidiff-go/src/__tests__/string-processor.test.ts index 8a4163c1..daa3822c 100644 --- a/actions/apidiff-go/src/__tests__/string-processor.test.ts +++ b/actions/apidiff-go/src/__tests__/string-processor.test.ts @@ -86,7 +86,7 @@ describe("markdown comment & job summary", () => { }); it(`formats diff as job summary: ${file}`, async () => { - await formatApidiffJobSummary(apiDiffResult); + await formatApidiffJobSummary(apiDiffResult, "head-ref", "base-ref"); // Join the collected summary parts into a single markdown string const content = summaryBuffer.join("\n"); From ae8307f8e997b15c331ceea782d7977b57789b0b Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Thu, 26 Feb 2026 15:53:54 -0800 Subject: [PATCH 07/11] feat: copy summary file, and output path --- actions/apidiff-go/action.yml | 6 ++++++ actions/apidiff-go/src/run.ts | 34 +++++++++++++++++++++++----------- actions/apidiff-go/src/util.ts | 17 ++++++++++++++++- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/actions/apidiff-go/action.yml b/actions/apidiff-go/action.yml index 281523a0..37bbf641 100644 --- a/actions/apidiff-go/action.yml +++ b/actions/apidiff-go/action.yml @@ -7,6 +7,12 @@ runs: using: "node20" main: "dist/index.js" +outputs: + + summary-path: + description: | + Path to the summary file generated by the action. This will be a copy of the ${GITHUB_STEP_SUMMARY} file. + inputs: # path inputs repository-root: diff --git a/actions/apidiff-go/src/run.ts b/actions/apidiff-go/src/run.ts index 9c2c6b9b..5b755cec 100644 --- a/actions/apidiff-go/src/run.ts +++ b/actions/apidiff-go/src/run.ts @@ -8,7 +8,6 @@ import { parseApidiffOutput, installApidiff, diffExports, - ApiDiffResult, } from "./apidiff"; import { validateGitRepositoryRoot } from "./git"; import { upsertPRComment } from "./github"; @@ -18,7 +17,11 @@ import { formatApidiffJobSummary, } from "./string-processor"; -import { getGoModuleName } from "./util"; +import { + getGoModuleName, + copySummaryOutputFile, + recommendVersionBump, +} from "./util"; export async function run(): Promise { try { @@ -83,15 +86,24 @@ export async function run(): Promise { // 4. Format and output results core.startGroup("Formatting and Outputting Results"); - const formattedBaseRef = - baseRef === baseExport.resolvedRef - ? baseRef - : `${baseRef} (${baseExport.resolvedRef})`; - const formattedHeadRef = - headRef === headExport.resolvedRef - ? headRef - : `${headRef} (${headExport.resolvedRef})`; - formatApidiffJobSummary(parsedResult, formattedBaseRef, formattedHeadRef); + const formatRef = (ref: string, resolvedRef: string) => + ref === resolvedRef ? ref : `${ref} (${resolvedRef})`; + + const formattedBaseRef = formatRef(baseRef, baseExport.resolvedRef); + const formattedHeadRef = formatRef(headRef, headExport.resolvedRef); + // await so when we copy the file, we know the summary has been written + const summaryPath = join( + inputs.repositoryRoot, + inputs.moduleDirectory, + "summary.md", + ); + await formatApidiffJobSummary( + parsedResult, + formattedBaseRef, + formattedHeadRef, + ); + copySummaryOutputFile(summaryPath); + core.setOutput("summary-path", summaryPath); if (context.event.eventName === "pull_request") { const markdownOutputIncompatibleOnly = formatApidiffMarkdown( diff --git a/actions/apidiff-go/src/util.ts b/actions/apidiff-go/src/util.ts index 1d049c40..54ad11b7 100644 --- a/actions/apidiff-go/src/util.ts +++ b/actions/apidiff-go/src/util.ts @@ -1,7 +1,7 @@ import * as core from "@actions/core"; import * as semver from "semver"; import { basename, join } from "path"; -import { readFileSync, existsSync } from "fs"; +import { readFileSync, existsSync, copyFileSync } from "fs"; /** * Extracts the module name from go.mod file @@ -58,3 +58,18 @@ export function normalizeRefForFilename(ref: string): string { return safe; } + +export function copySummaryOutputFile(destination: string) { + const filePath = process.env["GITHUB_STEP_SUMMARY"]; + if (!filePath) { + core.warning("GITHUB_STEP_SUMMARY environment variable is not set. Cannot copy summary output."); + return; + } + + try { + core.info(`Copying summary output from ${filePath} to ${destination}`); + copyFileSync(filePath, destination); + } catch (error) { + core.warning(`Failed to copy summary output: ${error}`); + } +} From bf6b87811638de5525b3c1f56ed391a8dea4f5f8 Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Thu, 26 Feb 2026 15:54:19 -0800 Subject: [PATCH 08/11] feat: simple version recommendation --- actions/apidiff-go/action.yml | 4 ++++ actions/apidiff-go/src/run.ts | 14 +++++++++++--- actions/apidiff-go/src/util.ts | 18 +++++++++++++++++- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/actions/apidiff-go/action.yml b/actions/apidiff-go/action.yml index 37bbf641..2cd3baff 100644 --- a/actions/apidiff-go/action.yml +++ b/actions/apidiff-go/action.yml @@ -8,6 +8,10 @@ runs: main: "dist/index.js" outputs: + version-recommendation: + description: | + A recommendation for the next version number based on the detected API + changes. Possible values are 'patch', 'minor', 'major'. summary-path: description: | diff --git a/actions/apidiff-go/src/run.ts b/actions/apidiff-go/src/run.ts index 5b755cec..d08713bf 100644 --- a/actions/apidiff-go/src/run.ts +++ b/actions/apidiff-go/src/run.ts @@ -130,10 +130,18 @@ export async function run(): Promise { } core.endGroup(); - const incompatibleCount = [parsedResult].reduce( - (sum, diff) => sum + diff.incompatible.length, - 0, + const compatibleCount = parsedResult.compatible.length; + const incompatibleCount = parsedResult.incompatible.length; + const metaCount = parsedResult.meta.length; + core.info( + `Detected ${compatibleCount} compatible, ${incompatibleCount} incompatible, and ${metaCount} metadata changes.`, ); + + core.setOutput( + "version-recommendation", + recommendVersionBump(parsedResult), + ); + core.info(`Total incompatible changes: ${incompatibleCount}`); if (inputs.enforceCompatible && incompatibleCount > 0) { core.setFailed( diff --git a/actions/apidiff-go/src/util.ts b/actions/apidiff-go/src/util.ts index 54ad11b7..67f27180 100644 --- a/actions/apidiff-go/src/util.ts +++ b/actions/apidiff-go/src/util.ts @@ -62,7 +62,9 @@ export function normalizeRefForFilename(ref: string): string { export function copySummaryOutputFile(destination: string) { const filePath = process.env["GITHUB_STEP_SUMMARY"]; if (!filePath) { - core.warning("GITHUB_STEP_SUMMARY environment variable is not set. Cannot copy summary output."); + core.warning( + "GITHUB_STEP_SUMMARY environment variable is not set. Cannot copy summary output.", + ); return; } @@ -73,3 +75,17 @@ export function copySummaryOutputFile(destination: string) { core.warning(`Failed to copy summary output: ${error}`); } } + +export function recommendVersionBump(diff: { + incompatible: any[]; + compatible: any[]; +}): "patch" | "minor" | "major" { + // Simple heuristic based on gorelease: https://pkg.go.dev/golang.org/x/exp/cmd/gorelease + if (diff.incompatible.length > 0) { + return "major"; + } else if (diff.compatible.length > 0) { + return "minor"; + } else { + return "patch"; + } +} From 7574867e59a5e675dcf4f2395105de4d21bea7b1 Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Thu, 26 Feb 2026 15:58:40 -0800 Subject: [PATCH 09/11] chore: update dist, readme --- actions/apidiff-go/README.md | 10 + actions/apidiff-go/dist/index.js | 2049 ++--------------------- actions/apidiff-go/scripts/payload.json | 6 + actions/apidiff-go/scripts/test.sh | 8 +- 4 files changed, 121 insertions(+), 1952 deletions(-) diff --git a/actions/apidiff-go/README.md b/actions/apidiff-go/README.md index 3049eaf0..ac4df704 100644 --- a/actions/apidiff-go/README.md +++ b/actions/apidiff-go/README.md @@ -36,6 +36,16 @@ Github event triggered the invocation. [event payload](https://docs.github.com/en/webhooks/webhook-events-and-payloads?actionType=synchronize#pull_request). - `push` - uses the `before`/`after` from the [event payload](https://docs.github.com/en/webhooks/webhook-events-and-payloads#push) +- `workflow_dispatch` events require `base-ref-override` and `head-ref-override` + inputs. + +#### Outputs + +1. `version-recommendation` - based on the changes, this will output `patch`, + `minor`, or `major` +2. `summary-path` - a copy of the summary, written to disk. To be used for + release notes if needed + - This should be written to a `summary.md` at the root of the module ### Example Workflow diff --git a/actions/apidiff-go/dist/index.js b/actions/apidiff-go/dist/index.js index 7df6d4c8..57d44d0b 100644 --- a/actions/apidiff-go/dist/index.js +++ b/actions/apidiff-go/dist/index.js @@ -393,7 +393,7 @@ var require_tunnel = __commonJS({ connectOptions.headers = connectOptions.headers || {}; connectOptions.headers["Proxy-Authorization"] = "Basic " + new Buffer(connectOptions.proxyAuth).toString("base64"); } - debug3("making CONNECT request"); + debug2("making CONNECT request"); var connectReq = self.request(connectOptions); connectReq.useChunkedEncodingByDefault = false; connectReq.once("response", onResponse); @@ -413,7 +413,7 @@ var require_tunnel = __commonJS({ connectReq.removeAllListeners(); socket.removeAllListeners(); if (res.statusCode !== 200) { - debug3( + debug2( "tunneling socket could not be established, statusCode=%d", res.statusCode ); @@ -425,7 +425,7 @@ var require_tunnel = __commonJS({ return; } if (head.length > 0) { - debug3("got illegal response body from proxy"); + debug2("got illegal response body from proxy"); socket.destroy(); var error = new Error("got illegal response body from proxy"); error.code = "ECONNRESET"; @@ -433,13 +433,13 @@ var require_tunnel = __commonJS({ self.removeSocket(placeholder); return; } - debug3("tunneling connection has established"); + debug2("tunneling connection has established"); self.sockets[self.sockets.indexOf(placeholder)] = socket; return cb(socket); } function onError(cause) { connectReq.removeAllListeners(); - debug3( + debug2( "tunneling socket could not be established, cause=%s\n", cause.message, cause.stack @@ -501,9 +501,9 @@ var require_tunnel = __commonJS({ } return target; } - var debug3; + var debug2; if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { - debug3 = function() { + debug2 = function() { var args = Array.prototype.slice.call(arguments); if (typeof args[0] === "string") { args[0] = "TUNNEL: " + args[0]; @@ -513,10 +513,10 @@ var require_tunnel = __commonJS({ console.error.apply(console, args); }; } else { - debug3 = function() { + debug2 = function() { }; } - exports2.debug = debug3; + exports2.debug = debug2; } }); @@ -19698,7 +19698,7 @@ var require_core = __commonJS({ Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); } exports2.getBooleanInput = getBooleanInput2; - function setOutput(name, value) { + function setOutput2(name, value) { const filePath = process.env["GITHUB_OUTPUT"] || ""; if (filePath) { return (0, file_command_1.issueFileCommand)("OUTPUT", (0, file_command_1.prepareKeyValueMessage)(name, value)); @@ -19706,7 +19706,7 @@ Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); process.stdout.write(os.EOL); (0, command_1.issueCommand)("set-output", { name }, (0, utils_1.toCommandValue)(value)); } - exports2.setOutput = setOutput; + exports2.setOutput = setOutput2; function setCommandEcho(enabled) { (0, command_1.issue)("echo", enabled ? "on" : "off"); } @@ -19720,10 +19720,10 @@ Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); return process.env["RUNNER_DEBUG"] === "1"; } exports2.isDebug = isDebug2; - function debug3(message) { + function debug2(message) { (0, command_1.issueCommand)("debug", {}, message); } - exports2.debug = debug3; + exports2.debug = debug2; function error(message, properties = {}) { (0, command_1.issueCommand)("error", (0, utils_1.toCommandProperties)(properties), message instanceof Error ? message.toString() : message); } @@ -24370,1930 +24370,6 @@ var require_cross_spawn = __commonJS({ } }); -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/constants.js -var require_constants6 = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/constants.js"(exports2, module2) { - "use strict"; - var SEMVER_SPEC_VERSION = "2.0.0"; - var MAX_LENGTH = 256; - var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || /* istanbul ignore next */ - 9007199254740991; - var MAX_SAFE_COMPONENT_LENGTH = 16; - var MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6; - var RELEASE_TYPES = [ - "major", - "premajor", - "minor", - "preminor", - "patch", - "prepatch", - "prerelease" - ]; - module2.exports = { - MAX_LENGTH, - MAX_SAFE_COMPONENT_LENGTH, - MAX_SAFE_BUILD_LENGTH, - MAX_SAFE_INTEGER, - RELEASE_TYPES, - SEMVER_SPEC_VERSION, - FLAG_INCLUDE_PRERELEASE: 1, - FLAG_LOOSE: 2 - }; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/debug.js -var require_debug = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/debug.js"(exports2, module2) { - "use strict"; - var debug3 = typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG) ? (...args) => console.error("SEMVER", ...args) : () => { - }; - module2.exports = debug3; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/re.js -var require_re = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/re.js"(exports2, module2) { - "use strict"; - var { - MAX_SAFE_COMPONENT_LENGTH, - MAX_SAFE_BUILD_LENGTH, - MAX_LENGTH - } = require_constants6(); - var debug3 = require_debug(); - exports2 = module2.exports = {}; - var re = exports2.re = []; - var safeRe = exports2.safeRe = []; - var src = exports2.src = []; - var safeSrc = exports2.safeSrc = []; - var t = exports2.t = {}; - var R = 0; - var LETTERDASHNUMBER = "[a-zA-Z0-9-]"; - var safeRegexReplacements = [ - ["\\s", 1], - ["\\d", MAX_LENGTH], - [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH] - ]; - var makeSafeRegex = (value) => { - for (const [token, max] of safeRegexReplacements) { - value = value.split(`${token}*`).join(`${token}{0,${max}}`).split(`${token}+`).join(`${token}{1,${max}}`); - } - return value; - }; - var createToken = (name, value, isGlobal) => { - const safe = makeSafeRegex(value); - const index = R++; - debug3(name, index, value); - t[name] = index; - src[index] = value; - safeSrc[index] = safe; - re[index] = new RegExp(value, isGlobal ? "g" : void 0); - safeRe[index] = new RegExp(safe, isGlobal ? "g" : void 0); - }; - createToken("NUMERICIDENTIFIER", "0|[1-9]\\d*"); - createToken("NUMERICIDENTIFIERLOOSE", "\\d+"); - createToken("NONNUMERICIDENTIFIER", `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`); - createToken("MAINVERSION", `(${src[t.NUMERICIDENTIFIER]})\\.(${src[t.NUMERICIDENTIFIER]})\\.(${src[t.NUMERICIDENTIFIER]})`); - createToken("MAINVERSIONLOOSE", `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.(${src[t.NUMERICIDENTIFIERLOOSE]})\\.(${src[t.NUMERICIDENTIFIERLOOSE]})`); - createToken("PRERELEASEIDENTIFIER", `(?:${src[t.NONNUMERICIDENTIFIER]}|${src[t.NUMERICIDENTIFIER]})`); - createToken("PRERELEASEIDENTIFIERLOOSE", `(?:${src[t.NONNUMERICIDENTIFIER]}|${src[t.NUMERICIDENTIFIERLOOSE]})`); - createToken("PRERELEASE", `(?:-(${src[t.PRERELEASEIDENTIFIER]}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`); - createToken("PRERELEASELOOSE", `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`); - createToken("BUILDIDENTIFIER", `${LETTERDASHNUMBER}+`); - createToken("BUILD", `(?:\\+(${src[t.BUILDIDENTIFIER]}(?:\\.${src[t.BUILDIDENTIFIER]})*))`); - createToken("FULLPLAIN", `v?${src[t.MAINVERSION]}${src[t.PRERELEASE]}?${src[t.BUILD]}?`); - createToken("FULL", `^${src[t.FULLPLAIN]}$`); - createToken("LOOSEPLAIN", `[v=\\s]*${src[t.MAINVERSIONLOOSE]}${src[t.PRERELEASELOOSE]}?${src[t.BUILD]}?`); - createToken("LOOSE", `^${src[t.LOOSEPLAIN]}$`); - createToken("GTLT", "((?:<|>)?=?)"); - createToken("XRANGEIDENTIFIERLOOSE", `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`); - createToken("XRANGEIDENTIFIER", `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`); - createToken("XRANGEPLAIN", `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})(?:\\.(${src[t.XRANGEIDENTIFIER]})(?:\\.(${src[t.XRANGEIDENTIFIER]})(?:${src[t.PRERELEASE]})?${src[t.BUILD]}?)?)?`); - createToken("XRANGEPLAINLOOSE", `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})(?:${src[t.PRERELEASELOOSE]})?${src[t.BUILD]}?)?)?`); - createToken("XRANGE", `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`); - createToken("XRANGELOOSE", `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`); - createToken("COERCEPLAIN", `${"(^|[^\\d])(\\d{1,"}${MAX_SAFE_COMPONENT_LENGTH}})(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`); - createToken("COERCE", `${src[t.COERCEPLAIN]}(?:$|[^\\d])`); - createToken("COERCEFULL", src[t.COERCEPLAIN] + `(?:${src[t.PRERELEASE]})?(?:${src[t.BUILD]})?(?:$|[^\\d])`); - createToken("COERCERTL", src[t.COERCE], true); - createToken("COERCERTLFULL", src[t.COERCEFULL], true); - createToken("LONETILDE", "(?:~>?)"); - createToken("TILDETRIM", `(\\s*)${src[t.LONETILDE]}\\s+`, true); - exports2.tildeTrimReplace = "$1~"; - createToken("TILDE", `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`); - createToken("TILDELOOSE", `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`); - createToken("LONECARET", "(?:\\^)"); - createToken("CARETTRIM", `(\\s*)${src[t.LONECARET]}\\s+`, true); - exports2.caretTrimReplace = "$1^"; - createToken("CARET", `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`); - createToken("CARETLOOSE", `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`); - createToken("COMPARATORLOOSE", `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`); - createToken("COMPARATOR", `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`); - createToken("COMPARATORTRIM", `(\\s*)${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true); - exports2.comparatorTrimReplace = "$1$2$3"; - createToken("HYPHENRANGE", `^\\s*(${src[t.XRANGEPLAIN]})\\s+-\\s+(${src[t.XRANGEPLAIN]})\\s*$`); - createToken("HYPHENRANGELOOSE", `^\\s*(${src[t.XRANGEPLAINLOOSE]})\\s+-\\s+(${src[t.XRANGEPLAINLOOSE]})\\s*$`); - createToken("STAR", "(<|>)?=?\\s*\\*"); - createToken("GTE0", "^\\s*>=\\s*0\\.0\\.0\\s*$"); - createToken("GTE0PRE", "^\\s*>=\\s*0\\.0\\.0-0\\s*$"); - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/parse-options.js -var require_parse_options = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/parse-options.js"(exports2, module2) { - "use strict"; - var looseOption = Object.freeze({ loose: true }); - var emptyOpts = Object.freeze({}); - var parseOptions = (options) => { - if (!options) { - return emptyOpts; - } - if (typeof options !== "object") { - return looseOption; - } - return options; - }; - module2.exports = parseOptions; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/identifiers.js -var require_identifiers = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/identifiers.js"(exports2, module2) { - "use strict"; - var numeric = /^[0-9]+$/; - var compareIdentifiers = (a2, b) => { - if (typeof a2 === "number" && typeof b === "number") { - return a2 === b ? 0 : a2 < b ? -1 : 1; - } - const anum = numeric.test(a2); - const bnum = numeric.test(b); - if (anum && bnum) { - a2 = +a2; - b = +b; - } - return a2 === b ? 0 : anum && !bnum ? -1 : bnum && !anum ? 1 : a2 < b ? -1 : 1; - }; - var rcompareIdentifiers = (a2, b) => compareIdentifiers(b, a2); - module2.exports = { - compareIdentifiers, - rcompareIdentifiers - }; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/classes/semver.js -var require_semver = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/classes/semver.js"(exports2, module2) { - "use strict"; - var debug3 = require_debug(); - var { MAX_LENGTH, MAX_SAFE_INTEGER } = require_constants6(); - var { safeRe: re, t } = require_re(); - var parseOptions = require_parse_options(); - var { compareIdentifiers } = require_identifiers(); - var SemVer = class _SemVer { - constructor(version, options) { - options = parseOptions(options); - if (version instanceof _SemVer) { - if (version.loose === !!options.loose && version.includePrerelease === !!options.includePrerelease) { - return version; - } else { - version = version.version; - } - } else if (typeof version !== "string") { - throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`); - } - if (version.length > MAX_LENGTH) { - throw new TypeError( - `version is longer than ${MAX_LENGTH} characters` - ); - } - debug3("SemVer", version, options); - this.options = options; - this.loose = !!options.loose; - this.includePrerelease = !!options.includePrerelease; - const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]); - if (!m) { - throw new TypeError(`Invalid Version: ${version}`); - } - this.raw = version; - this.major = +m[1]; - this.minor = +m[2]; - this.patch = +m[3]; - if (this.major > MAX_SAFE_INTEGER || this.major < 0) { - throw new TypeError("Invalid major version"); - } - if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { - throw new TypeError("Invalid minor version"); - } - if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { - throw new TypeError("Invalid patch version"); - } - if (!m[4]) { - this.prerelease = []; - } else { - this.prerelease = m[4].split(".").map((id) => { - if (/^[0-9]+$/.test(id)) { - const num = +id; - if (num >= 0 && num < MAX_SAFE_INTEGER) { - return num; - } - } - return id; - }); - } - this.build = m[5] ? m[5].split(".") : []; - this.format(); - } - format() { - this.version = `${this.major}.${this.minor}.${this.patch}`; - if (this.prerelease.length) { - this.version += `-${this.prerelease.join(".")}`; - } - return this.version; - } - toString() { - return this.version; - } - compare(other) { - debug3("SemVer.compare", this.version, this.options, other); - if (!(other instanceof _SemVer)) { - if (typeof other === "string" && other === this.version) { - return 0; - } - other = new _SemVer(other, this.options); - } - if (other.version === this.version) { - return 0; - } - return this.compareMain(other) || this.comparePre(other); - } - compareMain(other) { - if (!(other instanceof _SemVer)) { - other = new _SemVer(other, this.options); - } - if (this.major < other.major) { - return -1; - } - if (this.major > other.major) { - return 1; - } - if (this.minor < other.minor) { - return -1; - } - if (this.minor > other.minor) { - return 1; - } - if (this.patch < other.patch) { - return -1; - } - if (this.patch > other.patch) { - return 1; - } - return 0; - } - comparePre(other) { - if (!(other instanceof _SemVer)) { - other = new _SemVer(other, this.options); - } - if (this.prerelease.length && !other.prerelease.length) { - return -1; - } else if (!this.prerelease.length && other.prerelease.length) { - return 1; - } else if (!this.prerelease.length && !other.prerelease.length) { - return 0; - } - let i2 = 0; - do { - const a2 = this.prerelease[i2]; - const b = other.prerelease[i2]; - debug3("prerelease compare", i2, a2, b); - if (a2 === void 0 && b === void 0) { - return 0; - } else if (b === void 0) { - return 1; - } else if (a2 === void 0) { - return -1; - } else if (a2 === b) { - continue; - } else { - return compareIdentifiers(a2, b); - } - } while (++i2); - } - compareBuild(other) { - if (!(other instanceof _SemVer)) { - other = new _SemVer(other, this.options); - } - let i2 = 0; - do { - const a2 = this.build[i2]; - const b = other.build[i2]; - debug3("build compare", i2, a2, b); - if (a2 === void 0 && b === void 0) { - return 0; - } else if (b === void 0) { - return 1; - } else if (a2 === void 0) { - return -1; - } else if (a2 === b) { - continue; - } else { - return compareIdentifiers(a2, b); - } - } while (++i2); - } - // preminor will bump the version up to the next minor release, and immediately - // down to pre-release. premajor and prepatch work the same way. - inc(release, identifier, identifierBase) { - if (release.startsWith("pre")) { - if (!identifier && identifierBase === false) { - throw new Error("invalid increment argument: identifier is empty"); - } - if (identifier) { - const match = `-${identifier}`.match(this.options.loose ? re[t.PRERELEASELOOSE] : re[t.PRERELEASE]); - if (!match || match[1] !== identifier) { - throw new Error(`invalid identifier: ${identifier}`); - } - } - } - switch (release) { - case "premajor": - this.prerelease.length = 0; - this.patch = 0; - this.minor = 0; - this.major++; - this.inc("pre", identifier, identifierBase); - break; - case "preminor": - this.prerelease.length = 0; - this.patch = 0; - this.minor++; - this.inc("pre", identifier, identifierBase); - break; - case "prepatch": - this.prerelease.length = 0; - this.inc("patch", identifier, identifierBase); - this.inc("pre", identifier, identifierBase); - break; - case "prerelease": - if (this.prerelease.length === 0) { - this.inc("patch", identifier, identifierBase); - } - this.inc("pre", identifier, identifierBase); - break; - case "release": - if (this.prerelease.length === 0) { - throw new Error(`version ${this.raw} is not a prerelease`); - } - this.prerelease.length = 0; - break; - case "major": - if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) { - this.major++; - } - this.minor = 0; - this.patch = 0; - this.prerelease = []; - break; - case "minor": - if (this.patch !== 0 || this.prerelease.length === 0) { - this.minor++; - } - this.patch = 0; - this.prerelease = []; - break; - case "patch": - if (this.prerelease.length === 0) { - this.patch++; - } - this.prerelease = []; - break; - case "pre": { - const base = Number(identifierBase) ? 1 : 0; - if (this.prerelease.length === 0) { - this.prerelease = [base]; - } else { - let i2 = this.prerelease.length; - while (--i2 >= 0) { - if (typeof this.prerelease[i2] === "number") { - this.prerelease[i2]++; - i2 = -2; - } - } - if (i2 === -1) { - if (identifier === this.prerelease.join(".") && identifierBase === false) { - throw new Error("invalid increment argument: identifier already exists"); - } - this.prerelease.push(base); - } - } - if (identifier) { - let prerelease = [identifier, base]; - if (identifierBase === false) { - prerelease = [identifier]; - } - if (compareIdentifiers(this.prerelease[0], identifier) === 0) { - if (isNaN(this.prerelease[1])) { - this.prerelease = prerelease; - } - } else { - this.prerelease = prerelease; - } - } - break; - } - default: - throw new Error(`invalid increment argument: ${release}`); - } - this.raw = this.format(); - if (this.build.length) { - this.raw += `+${this.build.join(".")}`; - } - return this; - } - }; - module2.exports = SemVer; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/parse.js -var require_parse3 = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/parse.js"(exports2, module2) { - "use strict"; - var SemVer = require_semver(); - var parse = (version, options, throwErrors = false) => { - if (version instanceof SemVer) { - return version; - } - try { - return new SemVer(version, options); - } catch (er) { - if (!throwErrors) { - return null; - } - throw er; - } - }; - module2.exports = parse; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/valid.js -var require_valid = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/valid.js"(exports2, module2) { - "use strict"; - var parse = require_parse3(); - var valid2 = (version, options) => { - const v = parse(version, options); - return v ? v.version : null; - }; - module2.exports = valid2; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/clean.js -var require_clean = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/clean.js"(exports2, module2) { - "use strict"; - var parse = require_parse3(); - var clean = (version, options) => { - const s = parse(version.trim().replace(/^[=v]+/, ""), options); - return s ? s.version : null; - }; - module2.exports = clean; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/inc.js -var require_inc = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/inc.js"(exports2, module2) { - "use strict"; - var SemVer = require_semver(); - var inc = (version, release, options, identifier, identifierBase) => { - if (typeof options === "string") { - identifierBase = identifier; - identifier = options; - options = void 0; - } - try { - return new SemVer( - version instanceof SemVer ? version.version : version, - options - ).inc(release, identifier, identifierBase).version; - } catch (er) { - return null; - } - }; - module2.exports = inc; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/diff.js -var require_diff = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/diff.js"(exports2, module2) { - "use strict"; - var parse = require_parse3(); - var diff = (version1, version2) => { - const v1 = parse(version1, null, true); - const v2 = parse(version2, null, true); - const comparison = v1.compare(v2); - if (comparison === 0) { - return null; - } - const v1Higher = comparison > 0; - const highVersion = v1Higher ? v1 : v2; - const lowVersion = v1Higher ? v2 : v1; - const highHasPre = !!highVersion.prerelease.length; - const lowHasPre = !!lowVersion.prerelease.length; - if (lowHasPre && !highHasPre) { - if (!lowVersion.patch && !lowVersion.minor) { - return "major"; - } - if (lowVersion.compareMain(highVersion) === 0) { - if (lowVersion.minor && !lowVersion.patch) { - return "minor"; - } - return "patch"; - } - } - const prefix = highHasPre ? "pre" : ""; - if (v1.major !== v2.major) { - return prefix + "major"; - } - if (v1.minor !== v2.minor) { - return prefix + "minor"; - } - if (v1.patch !== v2.patch) { - return prefix + "patch"; - } - return "prerelease"; - }; - module2.exports = diff; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/major.js -var require_major = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/major.js"(exports2, module2) { - "use strict"; - var SemVer = require_semver(); - var major = (a2, loose) => new SemVer(a2, loose).major; - module2.exports = major; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/minor.js -var require_minor = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/minor.js"(exports2, module2) { - "use strict"; - var SemVer = require_semver(); - var minor = (a2, loose) => new SemVer(a2, loose).minor; - module2.exports = minor; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/patch.js -var require_patch = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/patch.js"(exports2, module2) { - "use strict"; - var SemVer = require_semver(); - var patch = (a2, loose) => new SemVer(a2, loose).patch; - module2.exports = patch; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/prerelease.js -var require_prerelease = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/prerelease.js"(exports2, module2) { - "use strict"; - var parse = require_parse3(); - var prerelease = (version, options) => { - const parsed = parse(version, options); - return parsed && parsed.prerelease.length ? parsed.prerelease : null; - }; - module2.exports = prerelease; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/compare.js -var require_compare = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/compare.js"(exports2, module2) { - "use strict"; - var SemVer = require_semver(); - var compare = (a2, b, loose) => new SemVer(a2, loose).compare(new SemVer(b, loose)); - module2.exports = compare; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/rcompare.js -var require_rcompare = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/rcompare.js"(exports2, module2) { - "use strict"; - var compare = require_compare(); - var rcompare2 = (a2, b, loose) => compare(b, a2, loose); - module2.exports = rcompare2; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/compare-loose.js -var require_compare_loose = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/compare-loose.js"(exports2, module2) { - "use strict"; - var compare = require_compare(); - var compareLoose = (a2, b) => compare(a2, b, true); - module2.exports = compareLoose; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/compare-build.js -var require_compare_build = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/compare-build.js"(exports2, module2) { - "use strict"; - var SemVer = require_semver(); - var compareBuild = (a2, b, loose) => { - const versionA = new SemVer(a2, loose); - const versionB = new SemVer(b, loose); - return versionA.compare(versionB) || versionA.compareBuild(versionB); - }; - module2.exports = compareBuild; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/sort.js -var require_sort = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/sort.js"(exports2, module2) { - "use strict"; - var compareBuild = require_compare_build(); - var sort = (list, loose) => list.sort((a2, b) => compareBuild(a2, b, loose)); - module2.exports = sort; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/rsort.js -var require_rsort = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/rsort.js"(exports2, module2) { - "use strict"; - var compareBuild = require_compare_build(); - var rsort = (list, loose) => list.sort((a2, b) => compareBuild(b, a2, loose)); - module2.exports = rsort; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/gt.js -var require_gt = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/gt.js"(exports2, module2) { - "use strict"; - var compare = require_compare(); - var gt = (a2, b, loose) => compare(a2, b, loose) > 0; - module2.exports = gt; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/lt.js -var require_lt = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/lt.js"(exports2, module2) { - "use strict"; - var compare = require_compare(); - var lt = (a2, b, loose) => compare(a2, b, loose) < 0; - module2.exports = lt; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/eq.js -var require_eq = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/eq.js"(exports2, module2) { - "use strict"; - var compare = require_compare(); - var eq = (a2, b, loose) => compare(a2, b, loose) === 0; - module2.exports = eq; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/neq.js -var require_neq = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/neq.js"(exports2, module2) { - "use strict"; - var compare = require_compare(); - var neq = (a2, b, loose) => compare(a2, b, loose) !== 0; - module2.exports = neq; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/gte.js -var require_gte = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/gte.js"(exports2, module2) { - "use strict"; - var compare = require_compare(); - var gte = (a2, b, loose) => compare(a2, b, loose) >= 0; - module2.exports = gte; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/lte.js -var require_lte = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/lte.js"(exports2, module2) { - "use strict"; - var compare = require_compare(); - var lte = (a2, b, loose) => compare(a2, b, loose) <= 0; - module2.exports = lte; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/cmp.js -var require_cmp = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/cmp.js"(exports2, module2) { - "use strict"; - var eq = require_eq(); - var neq = require_neq(); - var gt = require_gt(); - var gte = require_gte(); - var lt = require_lt(); - var lte = require_lte(); - var cmp = (a2, op, b, loose) => { - switch (op) { - case "===": - if (typeof a2 === "object") { - a2 = a2.version; - } - if (typeof b === "object") { - b = b.version; - } - return a2 === b; - case "!==": - if (typeof a2 === "object") { - a2 = a2.version; - } - if (typeof b === "object") { - b = b.version; - } - return a2 !== b; - case "": - case "=": - case "==": - return eq(a2, b, loose); - case "!=": - return neq(a2, b, loose); - case ">": - return gt(a2, b, loose); - case ">=": - return gte(a2, b, loose); - case "<": - return lt(a2, b, loose); - case "<=": - return lte(a2, b, loose); - default: - throw new TypeError(`Invalid operator: ${op}`); - } - }; - module2.exports = cmp; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/coerce.js -var require_coerce = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/coerce.js"(exports2, module2) { - "use strict"; - var SemVer = require_semver(); - var parse = require_parse3(); - var { safeRe: re, t } = require_re(); - var coerce = (version, options) => { - if (version instanceof SemVer) { - return version; - } - if (typeof version === "number") { - version = String(version); - } - if (typeof version !== "string") { - return null; - } - options = options || {}; - let match = null; - if (!options.rtl) { - match = version.match(options.includePrerelease ? re[t.COERCEFULL] : re[t.COERCE]); - } else { - const coerceRtlRegex = options.includePrerelease ? re[t.COERCERTLFULL] : re[t.COERCERTL]; - let next; - while ((next = coerceRtlRegex.exec(version)) && (!match || match.index + match[0].length !== version.length)) { - if (!match || next.index + next[0].length !== match.index + match[0].length) { - match = next; - } - coerceRtlRegex.lastIndex = next.index + next[1].length + next[2].length; - } - coerceRtlRegex.lastIndex = -1; - } - if (match === null) { - return null; - } - const major = match[2]; - const minor = match[3] || "0"; - const patch = match[4] || "0"; - const prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : ""; - const build = options.includePrerelease && match[6] ? `+${match[6]}` : ""; - return parse(`${major}.${minor}.${patch}${prerelease}${build}`, options); - }; - module2.exports = coerce; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/lrucache.js -var require_lrucache = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/lrucache.js"(exports2, module2) { - "use strict"; - var LRUCache = class { - constructor() { - this.max = 1e3; - this.map = /* @__PURE__ */ new Map(); - } - get(key) { - const value = this.map.get(key); - if (value === void 0) { - return void 0; - } else { - this.map.delete(key); - this.map.set(key, value); - return value; - } - } - delete(key) { - return this.map.delete(key); - } - set(key, value) { - const deleted = this.delete(key); - if (!deleted && value !== void 0) { - if (this.map.size >= this.max) { - const firstKey = this.map.keys().next().value; - this.delete(firstKey); - } - this.map.set(key, value); - } - return this; - } - }; - module2.exports = LRUCache; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/classes/range.js -var require_range = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/classes/range.js"(exports2, module2) { - "use strict"; - var SPACE_CHARACTERS = /\s+/g; - var Range = class _Range { - constructor(range, options) { - options = parseOptions(options); - if (range instanceof _Range) { - if (range.loose === !!options.loose && range.includePrerelease === !!options.includePrerelease) { - return range; - } else { - return new _Range(range.raw, options); - } - } - if (range instanceof Comparator) { - this.raw = range.value; - this.set = [[range]]; - this.formatted = void 0; - return this; - } - this.options = options; - this.loose = !!options.loose; - this.includePrerelease = !!options.includePrerelease; - this.raw = range.trim().replace(SPACE_CHARACTERS, " "); - this.set = this.raw.split("||").map((r) => this.parseRange(r.trim())).filter((c3) => c3.length); - if (!this.set.length) { - throw new TypeError(`Invalid SemVer Range: ${this.raw}`); - } - if (this.set.length > 1) { - const first = this.set[0]; - this.set = this.set.filter((c3) => !isNullSet(c3[0])); - if (this.set.length === 0) { - this.set = [first]; - } else if (this.set.length > 1) { - for (const c3 of this.set) { - if (c3.length === 1 && isAny(c3[0])) { - this.set = [c3]; - break; - } - } - } - } - this.formatted = void 0; - } - get range() { - if (this.formatted === void 0) { - this.formatted = ""; - for (let i2 = 0; i2 < this.set.length; i2++) { - if (i2 > 0) { - this.formatted += "||"; - } - const comps = this.set[i2]; - for (let k = 0; k < comps.length; k++) { - if (k > 0) { - this.formatted += " "; - } - this.formatted += comps[k].toString().trim(); - } - } - } - return this.formatted; - } - format() { - return this.range; - } - toString() { - return this.range; - } - parseRange(range) { - const memoOpts = (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | (this.options.loose && FLAG_LOOSE); - const memoKey = memoOpts + ":" + range; - const cached = cache.get(memoKey); - if (cached) { - return cached; - } - const loose = this.options.loose; - const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE]; - range = range.replace(hr, hyphenReplace(this.options.includePrerelease)); - debug3("hyphen replace", range); - range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace); - debug3("comparator trim", range); - range = range.replace(re[t.TILDETRIM], tildeTrimReplace); - debug3("tilde trim", range); - range = range.replace(re[t.CARETTRIM], caretTrimReplace); - debug3("caret trim", range); - let rangeList = range.split(" ").map((comp) => parseComparator(comp, this.options)).join(" ").split(/\s+/).map((comp) => replaceGTE0(comp, this.options)); - if (loose) { - rangeList = rangeList.filter((comp) => { - debug3("loose invalid filter", comp, this.options); - return !!comp.match(re[t.COMPARATORLOOSE]); - }); - } - debug3("range list", rangeList); - const rangeMap = /* @__PURE__ */ new Map(); - const comparators = rangeList.map((comp) => new Comparator(comp, this.options)); - for (const comp of comparators) { - if (isNullSet(comp)) { - return [comp]; - } - rangeMap.set(comp.value, comp); - } - if (rangeMap.size > 1 && rangeMap.has("")) { - rangeMap.delete(""); - } - const result = [...rangeMap.values()]; - cache.set(memoKey, result); - return result; - } - intersects(range, options) { - if (!(range instanceof _Range)) { - throw new TypeError("a Range is required"); - } - return this.set.some((thisComparators) => { - return isSatisfiable(thisComparators, options) && range.set.some((rangeComparators) => { - return isSatisfiable(rangeComparators, options) && thisComparators.every((thisComparator) => { - return rangeComparators.every((rangeComparator) => { - return thisComparator.intersects(rangeComparator, options); - }); - }); - }); - }); - } - // if ANY of the sets match ALL of its comparators, then pass - test(version) { - if (!version) { - return false; - } - if (typeof version === "string") { - try { - version = new SemVer(version, this.options); - } catch (er) { - return false; - } - } - for (let i2 = 0; i2 < this.set.length; i2++) { - if (testSet(this.set[i2], version, this.options)) { - return true; - } - } - return false; - } - }; - module2.exports = Range; - var LRU = require_lrucache(); - var cache = new LRU(); - var parseOptions = require_parse_options(); - var Comparator = require_comparator(); - var debug3 = require_debug(); - var SemVer = require_semver(); - var { - safeRe: re, - t, - comparatorTrimReplace, - tildeTrimReplace, - caretTrimReplace - } = require_re(); - var { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = require_constants6(); - var isNullSet = (c3) => c3.value === "<0.0.0-0"; - var isAny = (c3) => c3.value === ""; - var isSatisfiable = (comparators, options) => { - let result = true; - const remainingComparators = comparators.slice(); - let testComparator = remainingComparators.pop(); - while (result && remainingComparators.length) { - result = remainingComparators.every((otherComparator) => { - return testComparator.intersects(otherComparator, options); - }); - testComparator = remainingComparators.pop(); - } - return result; - }; - var parseComparator = (comp, options) => { - comp = comp.replace(re[t.BUILD], ""); - debug3("comp", comp, options); - comp = replaceCarets(comp, options); - debug3("caret", comp); - comp = replaceTildes(comp, options); - debug3("tildes", comp); - comp = replaceXRanges(comp, options); - debug3("xrange", comp); - comp = replaceStars(comp, options); - debug3("stars", comp); - return comp; - }; - var isX = (id) => !id || id.toLowerCase() === "x" || id === "*"; - var replaceTildes = (comp, options) => { - return comp.trim().split(/\s+/).map((c3) => replaceTilde(c3, options)).join(" "); - }; - var replaceTilde = (comp, options) => { - const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE]; - return comp.replace(r, (_, M, m, p, pr) => { - debug3("tilde", comp, _, M, m, p, pr); - let ret; - if (isX(M)) { - ret = ""; - } else if (isX(m)) { - ret = `>=${M}.0.0 <${+M + 1}.0.0-0`; - } else if (isX(p)) { - ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0`; - } else if (pr) { - debug3("replaceTilde pr", pr); - ret = `>=${M}.${m}.${p}-${pr} <${M}.${+m + 1}.0-0`; - } else { - ret = `>=${M}.${m}.${p} <${M}.${+m + 1}.0-0`; - } - debug3("tilde return", ret); - return ret; - }); - }; - var replaceCarets = (comp, options) => { - return comp.trim().split(/\s+/).map((c3) => replaceCaret(c3, options)).join(" "); - }; - var replaceCaret = (comp, options) => { - debug3("caret", comp, options); - const r = options.loose ? re[t.CARETLOOSE] : re[t.CARET]; - const z = options.includePrerelease ? "-0" : ""; - return comp.replace(r, (_, M, m, p, pr) => { - debug3("caret", comp, _, M, m, p, pr); - let ret; - if (isX(M)) { - ret = ""; - } else if (isX(m)) { - ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0`; - } else if (isX(p)) { - if (M === "0") { - ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0`; - } else { - ret = `>=${M}.${m}.0${z} <${+M + 1}.0.0-0`; - } - } else if (pr) { - debug3("replaceCaret pr", pr); - if (M === "0") { - if (m === "0") { - ret = `>=${M}.${m}.${p}-${pr} <${M}.${m}.${+p + 1}-0`; - } else { - ret = `>=${M}.${m}.${p}-${pr} <${M}.${+m + 1}.0-0`; - } - } else { - ret = `>=${M}.${m}.${p}-${pr} <${+M + 1}.0.0-0`; - } - } else { - debug3("no pr"); - if (M === "0") { - if (m === "0") { - ret = `>=${M}.${m}.${p}${z} <${M}.${m}.${+p + 1}-0`; - } else { - ret = `>=${M}.${m}.${p}${z} <${M}.${+m + 1}.0-0`; - } - } else { - ret = `>=${M}.${m}.${p} <${+M + 1}.0.0-0`; - } - } - debug3("caret return", ret); - return ret; - }); - }; - var replaceXRanges = (comp, options) => { - debug3("replaceXRanges", comp, options); - return comp.split(/\s+/).map((c3) => replaceXRange(c3, options)).join(" "); - }; - var replaceXRange = (comp, options) => { - comp = comp.trim(); - const r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE]; - return comp.replace(r, (ret, gtlt, M, m, p, pr) => { - debug3("xRange", comp, ret, gtlt, M, m, p, pr); - const xM = isX(M); - const xm = xM || isX(m); - const xp = xm || isX(p); - const anyX = xp; - if (gtlt === "=" && anyX) { - gtlt = ""; - } - pr = options.includePrerelease ? "-0" : ""; - if (xM) { - if (gtlt === ">" || gtlt === "<") { - ret = "<0.0.0-0"; - } else { - ret = "*"; - } - } else if (gtlt && anyX) { - if (xm) { - m = 0; - } - p = 0; - if (gtlt === ">") { - gtlt = ">="; - if (xm) { - M = +M + 1; - m = 0; - p = 0; - } else { - m = +m + 1; - p = 0; - } - } else if (gtlt === "<=") { - gtlt = "<"; - if (xm) { - M = +M + 1; - } else { - m = +m + 1; - } - } - if (gtlt === "<") { - pr = "-0"; - } - ret = `${gtlt + M}.${m}.${p}${pr}`; - } else if (xm) { - ret = `>=${M}.0.0${pr} <${+M + 1}.0.0-0`; - } else if (xp) { - ret = `>=${M}.${m}.0${pr} <${M}.${+m + 1}.0-0`; - } - debug3("xRange return", ret); - return ret; - }); - }; - var replaceStars = (comp, options) => { - debug3("replaceStars", comp, options); - return comp.trim().replace(re[t.STAR], ""); - }; - var replaceGTE0 = (comp, options) => { - debug3("replaceGTE0", comp, options); - return comp.trim().replace(re[options.includePrerelease ? t.GTE0PRE : t.GTE0], ""); - }; - var hyphenReplace = (incPr) => ($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr) => { - if (isX(fM)) { - from = ""; - } else if (isX(fm)) { - from = `>=${fM}.0.0${incPr ? "-0" : ""}`; - } else if (isX(fp)) { - from = `>=${fM}.${fm}.0${incPr ? "-0" : ""}`; - } else if (fpr) { - from = `>=${from}`; - } else { - from = `>=${from}${incPr ? "-0" : ""}`; - } - if (isX(tM)) { - to = ""; - } else if (isX(tm)) { - to = `<${+tM + 1}.0.0-0`; - } else if (isX(tp)) { - to = `<${tM}.${+tm + 1}.0-0`; - } else if (tpr) { - to = `<=${tM}.${tm}.${tp}-${tpr}`; - } else if (incPr) { - to = `<${tM}.${tm}.${+tp + 1}-0`; - } else { - to = `<=${to}`; - } - return `${from} ${to}`.trim(); - }; - var testSet = (set, version, options) => { - for (let i2 = 0; i2 < set.length; i2++) { - if (!set[i2].test(version)) { - return false; - } - } - if (version.prerelease.length && !options.includePrerelease) { - for (let i2 = 0; i2 < set.length; i2++) { - debug3(set[i2].semver); - if (set[i2].semver === Comparator.ANY) { - continue; - } - if (set[i2].semver.prerelease.length > 0) { - const allowed = set[i2].semver; - if (allowed.major === version.major && allowed.minor === version.minor && allowed.patch === version.patch) { - return true; - } - } - } - return false; - } - return true; - }; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/classes/comparator.js -var require_comparator = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/classes/comparator.js"(exports2, module2) { - "use strict"; - var ANY = Symbol("SemVer ANY"); - var Comparator = class _Comparator { - static get ANY() { - return ANY; - } - constructor(comp, options) { - options = parseOptions(options); - if (comp instanceof _Comparator) { - if (comp.loose === !!options.loose) { - return comp; - } else { - comp = comp.value; - } - } - comp = comp.trim().split(/\s+/).join(" "); - debug3("comparator", comp, options); - this.options = options; - this.loose = !!options.loose; - this.parse(comp); - if (this.semver === ANY) { - this.value = ""; - } else { - this.value = this.operator + this.semver.version; - } - debug3("comp", this); - } - parse(comp) { - const r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR]; - const m = comp.match(r); - if (!m) { - throw new TypeError(`Invalid comparator: ${comp}`); - } - this.operator = m[1] !== void 0 ? m[1] : ""; - if (this.operator === "=") { - this.operator = ""; - } - if (!m[2]) { - this.semver = ANY; - } else { - this.semver = new SemVer(m[2], this.options.loose); - } - } - toString() { - return this.value; - } - test(version) { - debug3("Comparator.test", version, this.options.loose); - if (this.semver === ANY || version === ANY) { - return true; - } - if (typeof version === "string") { - try { - version = new SemVer(version, this.options); - } catch (er) { - return false; - } - } - return cmp(version, this.operator, this.semver, this.options); - } - intersects(comp, options) { - if (!(comp instanceof _Comparator)) { - throw new TypeError("a Comparator is required"); - } - if (this.operator === "") { - if (this.value === "") { - return true; - } - return new Range(comp.value, options).test(this.value); - } else if (comp.operator === "") { - if (comp.value === "") { - return true; - } - return new Range(this.value, options).test(comp.semver); - } - options = parseOptions(options); - if (options.includePrerelease && (this.value === "<0.0.0-0" || comp.value === "<0.0.0-0")) { - return false; - } - if (!options.includePrerelease && (this.value.startsWith("<0.0.0") || comp.value.startsWith("<0.0.0"))) { - return false; - } - if (this.operator.startsWith(">") && comp.operator.startsWith(">")) { - return true; - } - if (this.operator.startsWith("<") && comp.operator.startsWith("<")) { - return true; - } - if (this.semver.version === comp.semver.version && this.operator.includes("=") && comp.operator.includes("=")) { - return true; - } - if (cmp(this.semver, "<", comp.semver, options) && this.operator.startsWith(">") && comp.operator.startsWith("<")) { - return true; - } - if (cmp(this.semver, ">", comp.semver, options) && this.operator.startsWith("<") && comp.operator.startsWith(">")) { - return true; - } - return false; - } - }; - module2.exports = Comparator; - var parseOptions = require_parse_options(); - var { safeRe: re, t } = require_re(); - var cmp = require_cmp(); - var debug3 = require_debug(); - var SemVer = require_semver(); - var Range = require_range(); - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/satisfies.js -var require_satisfies = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/satisfies.js"(exports2, module2) { - "use strict"; - var Range = require_range(); - var satisfies = (version, range, options) => { - try { - range = new Range(range, options); - } catch (er) { - return false; - } - return range.test(version); - }; - module2.exports = satisfies; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/to-comparators.js -var require_to_comparators = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/to-comparators.js"(exports2, module2) { - "use strict"; - var Range = require_range(); - var toComparators = (range, options) => new Range(range, options).set.map((comp) => comp.map((c3) => c3.value).join(" ").trim().split(" ")); - module2.exports = toComparators; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/max-satisfying.js -var require_max_satisfying = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/max-satisfying.js"(exports2, module2) { - "use strict"; - var SemVer = require_semver(); - var Range = require_range(); - var maxSatisfying = (versions, range, options) => { - let max = null; - let maxSV = null; - let rangeObj = null; - try { - rangeObj = new Range(range, options); - } catch (er) { - return null; - } - versions.forEach((v) => { - if (rangeObj.test(v)) { - if (!max || maxSV.compare(v) === -1) { - max = v; - maxSV = new SemVer(max, options); - } - } - }); - return max; - }; - module2.exports = maxSatisfying; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/min-satisfying.js -var require_min_satisfying = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/min-satisfying.js"(exports2, module2) { - "use strict"; - var SemVer = require_semver(); - var Range = require_range(); - var minSatisfying = (versions, range, options) => { - let min = null; - let minSV = null; - let rangeObj = null; - try { - rangeObj = new Range(range, options); - } catch (er) { - return null; - } - versions.forEach((v) => { - if (rangeObj.test(v)) { - if (!min || minSV.compare(v) === 1) { - min = v; - minSV = new SemVer(min, options); - } - } - }); - return min; - }; - module2.exports = minSatisfying; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/min-version.js -var require_min_version = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/min-version.js"(exports2, module2) { - "use strict"; - var SemVer = require_semver(); - var Range = require_range(); - var gt = require_gt(); - var minVersion = (range, loose) => { - range = new Range(range, loose); - let minver = new SemVer("0.0.0"); - if (range.test(minver)) { - return minver; - } - minver = new SemVer("0.0.0-0"); - if (range.test(minver)) { - return minver; - } - minver = null; - for (let i2 = 0; i2 < range.set.length; ++i2) { - const comparators = range.set[i2]; - let setMin = null; - comparators.forEach((comparator) => { - const compver = new SemVer(comparator.semver.version); - switch (comparator.operator) { - case ">": - if (compver.prerelease.length === 0) { - compver.patch++; - } else { - compver.prerelease.push(0); - } - compver.raw = compver.format(); - case "": - case ">=": - if (!setMin || gt(compver, setMin)) { - setMin = compver; - } - break; - case "<": - case "<=": - break; - default: - throw new Error(`Unexpected operation: ${comparator.operator}`); - } - }); - if (setMin && (!minver || gt(minver, setMin))) { - minver = setMin; - } - } - if (minver && range.test(minver)) { - return minver; - } - return null; - }; - module2.exports = minVersion; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/valid.js -var require_valid2 = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/valid.js"(exports2, module2) { - "use strict"; - var Range = require_range(); - var validRange = (range, options) => { - try { - return new Range(range, options).range || "*"; - } catch (er) { - return null; - } - }; - module2.exports = validRange; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/outside.js -var require_outside = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/outside.js"(exports2, module2) { - "use strict"; - var SemVer = require_semver(); - var Comparator = require_comparator(); - var { ANY } = Comparator; - var Range = require_range(); - var satisfies = require_satisfies(); - var gt = require_gt(); - var lt = require_lt(); - var lte = require_lte(); - var gte = require_gte(); - var outside = (version, range, hilo, options) => { - version = new SemVer(version, options); - range = new Range(range, options); - let gtfn, ltefn, ltfn, comp, ecomp; - switch (hilo) { - case ">": - gtfn = gt; - ltefn = lte; - ltfn = lt; - comp = ">"; - ecomp = ">="; - break; - case "<": - gtfn = lt; - ltefn = gte; - ltfn = gt; - comp = "<"; - ecomp = "<="; - break; - default: - throw new TypeError('Must provide a hilo val of "<" or ">"'); - } - if (satisfies(version, range, options)) { - return false; - } - for (let i2 = 0; i2 < range.set.length; ++i2) { - const comparators = range.set[i2]; - let high = null; - let low = null; - comparators.forEach((comparator) => { - if (comparator.semver === ANY) { - comparator = new Comparator(">=0.0.0"); - } - high = high || comparator; - low = low || comparator; - if (gtfn(comparator.semver, high.semver, options)) { - high = comparator; - } else if (ltfn(comparator.semver, low.semver, options)) { - low = comparator; - } - }); - if (high.operator === comp || high.operator === ecomp) { - return false; - } - if ((!low.operator || low.operator === comp) && ltefn(version, low.semver)) { - return false; - } else if (low.operator === ecomp && ltfn(version, low.semver)) { - return false; - } - } - return true; - }; - module2.exports = outside; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/gtr.js -var require_gtr = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/gtr.js"(exports2, module2) { - "use strict"; - var outside = require_outside(); - var gtr = (version, range, options) => outside(version, range, ">", options); - module2.exports = gtr; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/ltr.js -var require_ltr = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/ltr.js"(exports2, module2) { - "use strict"; - var outside = require_outside(); - var ltr = (version, range, options) => outside(version, range, "<", options); - module2.exports = ltr; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/intersects.js -var require_intersects = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/intersects.js"(exports2, module2) { - "use strict"; - var Range = require_range(); - var intersects = (r1, r2, options) => { - r1 = new Range(r1, options); - r2 = new Range(r2, options); - return r1.intersects(r2, options); - }; - module2.exports = intersects; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/simplify.js -var require_simplify = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/simplify.js"(exports2, module2) { - "use strict"; - var satisfies = require_satisfies(); - var compare = require_compare(); - module2.exports = (versions, range, options) => { - const set = []; - let first = null; - let prev = null; - const v = versions.sort((a2, b) => compare(a2, b, options)); - for (const version of v) { - const included = satisfies(version, range, options); - if (included) { - prev = version; - if (!first) { - first = version; - } - } else { - if (prev) { - set.push([first, prev]); - } - prev = null; - first = null; - } - } - if (first) { - set.push([first, null]); - } - const ranges = []; - for (const [min, max] of set) { - if (min === max) { - ranges.push(min); - } else if (!max && min === v[0]) { - ranges.push("*"); - } else if (!max) { - ranges.push(`>=${min}`); - } else if (min === v[0]) { - ranges.push(`<=${max}`); - } else { - ranges.push(`${min} - ${max}`); - } - } - const simplified = ranges.join(" || "); - const original = typeof range.raw === "string" ? range.raw : String(range); - return simplified.length < original.length ? simplified : range; - }; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/subset.js -var require_subset = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/subset.js"(exports2, module2) { - "use strict"; - var Range = require_range(); - var Comparator = require_comparator(); - var { ANY } = Comparator; - var satisfies = require_satisfies(); - var compare = require_compare(); - var subset = (sub, dom, options = {}) => { - if (sub === dom) { - return true; - } - sub = new Range(sub, options); - dom = new Range(dom, options); - let sawNonNull = false; - OUTER: for (const simpleSub of sub.set) { - for (const simpleDom of dom.set) { - const isSub = simpleSubset(simpleSub, simpleDom, options); - sawNonNull = sawNonNull || isSub !== null; - if (isSub) { - continue OUTER; - } - } - if (sawNonNull) { - return false; - } - } - return true; - }; - var minimumVersionWithPreRelease = [new Comparator(">=0.0.0-0")]; - var minimumVersion = [new Comparator(">=0.0.0")]; - var simpleSubset = (sub, dom, options) => { - if (sub === dom) { - return true; - } - if (sub.length === 1 && sub[0].semver === ANY) { - if (dom.length === 1 && dom[0].semver === ANY) { - return true; - } else if (options.includePrerelease) { - sub = minimumVersionWithPreRelease; - } else { - sub = minimumVersion; - } - } - if (dom.length === 1 && dom[0].semver === ANY) { - if (options.includePrerelease) { - return true; - } else { - dom = minimumVersion; - } - } - const eqSet = /* @__PURE__ */ new Set(); - let gt, lt; - for (const c3 of sub) { - if (c3.operator === ">" || c3.operator === ">=") { - gt = higherGT(gt, c3, options); - } else if (c3.operator === "<" || c3.operator === "<=") { - lt = lowerLT(lt, c3, options); - } else { - eqSet.add(c3.semver); - } - } - if (eqSet.size > 1) { - return null; - } - let gtltComp; - if (gt && lt) { - gtltComp = compare(gt.semver, lt.semver, options); - if (gtltComp > 0) { - return null; - } else if (gtltComp === 0 && (gt.operator !== ">=" || lt.operator !== "<=")) { - return null; - } - } - for (const eq of eqSet) { - if (gt && !satisfies(eq, String(gt), options)) { - return null; - } - if (lt && !satisfies(eq, String(lt), options)) { - return null; - } - for (const c3 of dom) { - if (!satisfies(eq, String(c3), options)) { - return false; - } - } - return true; - } - let higher, lower; - let hasDomLT, hasDomGT; - let needDomLTPre = lt && !options.includePrerelease && lt.semver.prerelease.length ? lt.semver : false; - let needDomGTPre = gt && !options.includePrerelease && gt.semver.prerelease.length ? gt.semver : false; - if (needDomLTPre && needDomLTPre.prerelease.length === 1 && lt.operator === "<" && needDomLTPre.prerelease[0] === 0) { - needDomLTPre = false; - } - for (const c3 of dom) { - hasDomGT = hasDomGT || c3.operator === ">" || c3.operator === ">="; - hasDomLT = hasDomLT || c3.operator === "<" || c3.operator === "<="; - if (gt) { - if (needDomGTPre) { - if (c3.semver.prerelease && c3.semver.prerelease.length && c3.semver.major === needDomGTPre.major && c3.semver.minor === needDomGTPre.minor && c3.semver.patch === needDomGTPre.patch) { - needDomGTPre = false; - } - } - if (c3.operator === ">" || c3.operator === ">=") { - higher = higherGT(gt, c3, options); - if (higher === c3 && higher !== gt) { - return false; - } - } else if (gt.operator === ">=" && !satisfies(gt.semver, String(c3), options)) { - return false; - } - } - if (lt) { - if (needDomLTPre) { - if (c3.semver.prerelease && c3.semver.prerelease.length && c3.semver.major === needDomLTPre.major && c3.semver.minor === needDomLTPre.minor && c3.semver.patch === needDomLTPre.patch) { - needDomLTPre = false; - } - } - if (c3.operator === "<" || c3.operator === "<=") { - lower = lowerLT(lt, c3, options); - if (lower === c3 && lower !== lt) { - return false; - } - } else if (lt.operator === "<=" && !satisfies(lt.semver, String(c3), options)) { - return false; - } - } - if (!c3.operator && (lt || gt) && gtltComp !== 0) { - return false; - } - } - if (gt && hasDomLT && !lt && gtltComp !== 0) { - return false; - } - if (lt && hasDomGT && !gt && gtltComp !== 0) { - return false; - } - if (needDomGTPre || needDomLTPre) { - return false; - } - return true; - }; - var higherGT = (a2, b, options) => { - if (!a2) { - return b; - } - const comp = compare(a2.semver, b.semver, options); - return comp > 0 ? a2 : comp < 0 ? b : b.operator === ">" && a2.operator === ">=" ? b : a2; - }; - var lowerLT = (a2, b, options) => { - if (!a2) { - return b; - } - const comp = compare(a2.semver, b.semver, options); - return comp < 0 ? a2 : comp > 0 ? b : b.operator === "<" && a2.operator === "<=" ? b : a2; - }; - module2.exports = subset; - } -}); - -// node_modules/.pnpm/semver@7.7.3/node_modules/semver/index.js -var require_semver2 = __commonJS({ - "node_modules/.pnpm/semver@7.7.3/node_modules/semver/index.js"(exports2, module2) { - "use strict"; - var internalRe = require_re(); - var constants4 = require_constants6(); - var SemVer = require_semver(); - var identifiers = require_identifiers(); - var parse = require_parse3(); - var valid2 = require_valid(); - var clean = require_clean(); - var inc = require_inc(); - var diff = require_diff(); - var major = require_major(); - var minor = require_minor(); - var patch = require_patch(); - var prerelease = require_prerelease(); - var compare = require_compare(); - var rcompare2 = require_rcompare(); - var compareLoose = require_compare_loose(); - var compareBuild = require_compare_build(); - var sort = require_sort(); - var rsort = require_rsort(); - var gt = require_gt(); - var lt = require_lt(); - var eq = require_eq(); - var neq = require_neq(); - var gte = require_gte(); - var lte = require_lte(); - var cmp = require_cmp(); - var coerce = require_coerce(); - var Comparator = require_comparator(); - var Range = require_range(); - var satisfies = require_satisfies(); - var toComparators = require_to_comparators(); - var maxSatisfying = require_max_satisfying(); - var minSatisfying = require_min_satisfying(); - var minVersion = require_min_version(); - var validRange = require_valid2(); - var outside = require_outside(); - var gtr = require_gtr(); - var ltr = require_ltr(); - var intersects = require_intersects(); - var simplifyRange = require_simplify(); - var subset = require_subset(); - module2.exports = { - parse, - valid: valid2, - clean, - inc, - diff, - major, - minor, - patch, - prerelease, - compare, - rcompare: rcompare2, - compareLoose, - compareBuild, - sort, - rsort, - gt, - lt, - eq, - neq, - gte, - lte, - cmp, - coerce, - Comparator, - Range, - satisfies, - toComparators, - maxSatisfying, - minSatisfying, - minVersion, - validRange, - outside, - gtr, - ltr, - intersects, - simplifyRange, - subset, - SemVer, - re: internalRe.re, - src: internalRe.src, - tokens: internalRe.t, - SEMVER_SPEC_VERSION: constants4.SEMVER_SPEC_VERSION, - RELEASE_TYPES: constants4.RELEASE_TYPES, - compareIdentifiers: identifiers.compareIdentifiers, - rcompareIdentifiers: identifiers.rcompareIdentifiers - }; - } -}); - // actions/apidiff-go/src/run.ts var core7 = __toESM(require_core()); var github3 = __toESM(require_github()); @@ -33081,7 +31157,6 @@ var fs2 = __toESM(require("fs")); // actions/apidiff-go/src/util.ts var core = __toESM(require_core()); -var semver = __toESM(require_semver2()); var import_path = require("path"); var import_fs = require("fs"); async function getGoModuleName(moduleDir) { @@ -33119,6 +31194,30 @@ function normalizeRefForFilename(ref) { } return safe; } +function copySummaryOutputFile(destination) { + const filePath = process.env["GITHUB_STEP_SUMMARY"]; + if (!filePath) { + core.warning( + "GITHUB_STEP_SUMMARY environment variable is not set. Cannot copy summary output." + ); + return; + } + try { + core.info(`Copying summary output from ${filePath} to ${destination}`); + (0, import_fs.copyFileSync)(filePath, destination); + } catch (error) { + core.warning(`Failed to copy summary output: ${error}`); + } +} +function recommendVersionBump(diff) { + if (diff.incompatible.length > 0) { + return "major"; + } else if (diff.compatible.length > 0) { + return "minor"; + } else { + return "patch"; + } +} // actions/apidiff-go/src/run-inputs.ts var core2 = __toESM(require_core()); @@ -33150,6 +31249,10 @@ function getEventData() { base: pushEvent.before, head: pushEvent.after }; + case "workflow_dispatch": + return { + eventName: "workflow_dispatch" + }; default: throw new Error(`Unsupported event type: ${context2.eventName}`); } @@ -33183,7 +31286,7 @@ function getInvokeContext() { } const event = getEventData(); core2.info( - `Invoke context: ${JSON.stringify({ token: "****", owner, repo, event }, null, 2)}` + `Invoke context: ${JSON.stringify({ token: "", owner, repo, event }, null, 2)}` ); return { token, owner, repo, event }; } @@ -33301,6 +31404,7 @@ async function checkoutRef(repoDir, ref) { const resolvedRef = await resolveRef(repoDir, ref); await execa("git", ["checkout", resolvedRef], { cwd: repoDir }); core3.info(`Successfully checked out: ${resolvedRef}`); + return resolvedRef; } catch (error) { throw new Error(`Failed to checkout ref ${ref}: ${error}`); } @@ -33313,14 +31417,15 @@ async function generateExportAtRef(modulePath, ref) { core4.info( `Generating export (${outFile}) for module at ${modulePath}, at ref ${ref}.` ); - await checkoutRef(modulePath, ref); + const resolvedRef = await checkoutRef(modulePath, ref); await execa("apidiff", ["-m", "-w", outFile, "."], { cwd: modulePath }); return { path: (0, import_path2.join)(modulePath, outFile), normalizedRef, - ref + ref, + resolvedRef }; } async function diffExports(baseExport, headExport) { @@ -33976,7 +32081,7 @@ function formatApidiffMarkdown(diff, summaryUrl, includeFullOutput = false) { lines.push(`---`, "", `\u{1F4C4} [View full apidiff report](${summaryUrl})`, ""); return lines.join("\n"); } -async function formatApidiffJobSummary(diff) { +async function formatApidiffJobSummary(diff, baseRef, headRef) { const s = core6.summary; const hasIncompat = diff.incompatible.length > 0; const hasCompat = diff.compatible.length > 0; @@ -33986,11 +32091,27 @@ async function formatApidiffJobSummary(diff) { "
No changes detected for this module
", true ); + s.addTable([ + [ + { data: "Ref", header: true }, + { data: "Value", header: true } + ], + [{ data: "Base" }, { data: `${escapeHtml2(baseRef)}` }], + [{ data: "Head" }, { data: `${escapeHtml2(headRef)}` }] + ]); await s.write(); return; } const statusEmoji = hasIncompat ? "\u26A0\uFE0F" : "\u2705"; s.addHeading(`${statusEmoji} API Diff Results \u2013 ${diff.moduleName}`, 2); + s.addTable([ + [ + { data: "Ref", header: true }, + { data: "Value", header: true } + ], + [{ data: "Base" }, { data: `${escapeHtml2(baseRef)}` }], + [{ data: "Head" }, { data: `${escapeHtml2(headRef)}` }] + ]); function simpleTableRow(title, content) { return [{ data: title }, { data: `
${content}
` }]; } @@ -34073,18 +32194,19 @@ async function run() { core7.info(`Qualified module directory: ${qualifiedModuleDirectory}`); const moduleName = await getGoModuleName(qualifiedModuleDirectory); core7.info(`Module name: ${moduleName}`); + const headRef = determineRef("head", context2, inputs.headRefOverride); + const baseRef = determineRef("base", context2, inputs.baseRefOverride); + core7.info(`Head ref: ${headRef}, Base ref: ${baseRef}`); core7.endGroup(); core7.startGroup("Installing apidiff"); await installApidiff(qualifiedModuleDirectory, inputs.apidiffVersion); core7.endGroup(); core7.startGroup("Generating Exports"); - const headRef = inputs.headRefOverride || context2.event.head; const headExport = await generateExportAtRef( qualifiedModuleDirectory, headRef ); core7.info(`Generated head export at: ${headExport.path}`); - const baseRef = inputs.baseRefOverride || context2.event.base; const baseExport = await generateExportAtRef( qualifiedModuleDirectory, baseRef @@ -34101,7 +32223,21 @@ async function run() { core7.debug(JSON.stringify(parsedResult)); } core7.startGroup("Formatting and Outputting Results"); - formatApidiffJobSummary(parsedResult); + const formatRef = (ref, resolvedRef) => ref === resolvedRef ? ref : `${ref} (${resolvedRef})`; + const formattedBaseRef = formatRef(baseRef, baseExport.resolvedRef); + const formattedHeadRef = formatRef(headRef, headExport.resolvedRef); + const summaryPath = (0, import_path3.join)( + inputs.repositoryRoot, + inputs.moduleDirectory, + "summary.md" + ); + await formatApidiffJobSummary( + parsedResult, + formattedBaseRef, + formattedHeadRef + ); + copySummaryOutputFile(summaryPath); + core7.setOutput("summary-path", summaryPath); if (context2.event.eventName === "pull_request") { const markdownOutputIncompatibleOnly = formatApidiffMarkdown( parsedResult, @@ -34124,9 +32260,15 @@ async function run() { } } core7.endGroup(); - const incompatibleCount = [parsedResult].reduce( - (sum, diff) => sum + diff.incompatible.length, - 0 + const compatibleCount = parsedResult.compatible.length; + const incompatibleCount = parsedResult.incompatible.length; + const metaCount = parsedResult.meta.length; + core7.info( + `Detected ${compatibleCount} compatible, ${incompatibleCount} incompatible, and ${metaCount} metadata changes.` + ); + core7.setOutput( + "version-recommendation", + recommendVersionBump(parsedResult) ); core7.info(`Total incompatible changes: ${incompatibleCount}`); if (inputs.enforceCompatible && incompatibleCount > 0) { @@ -34139,6 +32281,17 @@ async function run() { core7.setFailed(`Action failed: ${error}`); } } +function determineRef(property, context2, override) { + if (override) { + return override; + } + if (context2.event.eventName === "workflow_dispatch") { + throw new Error( + `Missing required ${property}-ref-override input for workflow_dispatch event.` + ); + } + return context2.event[property]; +} // actions/apidiff-go/src/index.ts run(); diff --git a/actions/apidiff-go/scripts/payload.json b/actions/apidiff-go/scripts/payload.json index ffe9cb47..1e692354 100644 --- a/actions/apidiff-go/scripts/payload.json +++ b/actions/apidiff-go/scripts/payload.json @@ -3,5 +3,11 @@ "base": { "sha": "6cbcde243424db8b7727e03425d844bb419515cb" }, "head": { "sha": "fdbfd5296201bb866be71999072df34999c47f96" }, "number": 1716 + }, + "before": "8dae71deabf8466740f29c0f101ad82d46ba52ed", + "after": "e60172063307fe26e73a56e0c3d747775bdc9e12", + "push": { + "before": "8dae71deabf8466740f29c0f101ad82d46ba52ed", + "after": "e60172063307fe26e73a56e0c3d747775bdc9e12" } } diff --git a/actions/apidiff-go/scripts/test.sh b/actions/apidiff-go/scripts/test.sh index 0b0182e1..8f3ead50 100755 --- a/actions/apidiff-go/scripts/test.sh +++ b/actions/apidiff-go/scripts/test.sh @@ -4,16 +4,16 @@ pnpm nx build apidiff-go export GITHUB_TOKEN=$(gh auth token) export GITHUB_REPOSITORY="smartcontractkit/chainlink-common" -export GITHUB_EVENT_NAME="pull_request" +export GITHUB_EVENT_NAME="workflow_dispatch" export GITHUB_EVENT_PATH="actions/apidiff-go/scripts/payload.json" tmp_file=$(mktemp) export GITHUB_STEP_SUMMARY="$tmp_file" export INPUT_REPOSITORY_ROOT="/Users/erik/Documents/repos/chainlink-common" -export INPUT_MODULE_DIRECTORY="./pkg/chipingress" -export INPUT_BASE_REF_OVERRIDE="pkg/chipingress/v0.0.7" -export INPUT_HEAD_REF_OVERRIDE="pkg/chipingress/v0.0.8" +export INPUT_MODULE_DIRECTORY="." +export INPUT_BASE_REF_OVERRIDE="v0.10.0" +export INPUT_HEAD_REF_OVERRIDE="main" export INPUT_ENFORCE_COMPATIBLE="true" export INPUT_POST_COMMENT="false" export INPUT_APIDIFF_VERSION="latest" From 091a4bbd5c535ffc3edbd0beb9cb6fe853f6db34 Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Thu, 26 Feb 2026 16:04:38 -0800 Subject: [PATCH 10/11] add changesets --- .changeset/fuzzy-lambs-bow.md | 5 +++++ .changeset/ripe-foxes-fix.md | 5 +++++ .changeset/simple-flames-grin.md | 5 +++++ .changeset/stale-sparks-heal.md | 5 +++++ 4 files changed, 20 insertions(+) create mode 100644 .changeset/fuzzy-lambs-bow.md create mode 100644 .changeset/ripe-foxes-fix.md create mode 100644 .changeset/simple-flames-grin.md create mode 100644 .changeset/stale-sparks-heal.md diff --git a/.changeset/fuzzy-lambs-bow.md b/.changeset/fuzzy-lambs-bow.md new file mode 100644 index 00000000..283d96ec --- /dev/null +++ b/.changeset/fuzzy-lambs-bow.md @@ -0,0 +1,5 @@ +--- +"apidiff-go": minor +--- + +feat: support workflow_dispatch events, forcing base/head ref override inputs diff --git a/.changeset/ripe-foxes-fix.md b/.changeset/ripe-foxes-fix.md new file mode 100644 index 00000000..8f6330c6 --- /dev/null +++ b/.changeset/ripe-foxes-fix.md @@ -0,0 +1,5 @@ +--- +"apidiff-go": minor +--- + +feat: add version recommendations (patch/minor/major) based on api changes diff --git a/.changeset/simple-flames-grin.md b/.changeset/simple-flames-grin.md new file mode 100644 index 00000000..beec141f --- /dev/null +++ b/.changeset/simple-flames-grin.md @@ -0,0 +1,5 @@ +--- +"apidiff-go": minor +--- + +feat: copy github step summary file, and add summary-path as an action output diff --git a/.changeset/stale-sparks-heal.md b/.changeset/stale-sparks-heal.md new file mode 100644 index 00000000..25db91e5 --- /dev/null +++ b/.changeset/stale-sparks-heal.md @@ -0,0 +1,5 @@ +--- +"apidiff-go": patch +--- + +feat: add ref, and resolved ref to summary output From a392b35083c3a29de5ca4e74ada1a85094ed82e1 Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Thu, 26 Feb 2026 18:10:12 -0800 Subject: [PATCH 11/11] fix: add github-token input --- actions/apidiff-go/action.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/actions/apidiff-go/action.yml b/actions/apidiff-go/action.yml index 2cd3baff..e6374f93 100644 --- a/actions/apidiff-go/action.yml +++ b/actions/apidiff-go/action.yml @@ -67,6 +67,11 @@ inputs: default: "latest" # misc inputs - dont touch these + github-token: + description: "GitHub token to use for authentication" + default: ${{ github.token }} + required: true + summary-url: description: "URL linking to the full apidiff report. This is included in the comment