From dd0865930e9c2c5c8247f860fe54b70c3dcb5ecb Mon Sep 17 00:00:00 2001 From: Humphrey Shotton <1696213+Humpheh@users.noreply.github.com> Date: Wed, 15 Oct 2025 16:22:04 +0100 Subject: [PATCH 01/13] Add optional working directory input --- action.yml | 3 +++ src/main.ts | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 1b27b6a..ffe637b 100644 --- a/action.yml +++ b/action.yml @@ -44,6 +44,9 @@ inputs: description: 'Detect modules which have community suggested alternatives' required: false default: true + work-dir: + description: 'Working directory' + required: false runs: using: node24 diff --git a/src/main.ts b/src/main.ts index 23084ce..11b01b2 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,6 +2,7 @@ import * as process from 'process'; import * as core from '@actions/core'; import * as github from '@actions/github'; import type {PackageJson} from 'pkg-types'; +import {join} from 'node:path'; import {parse as parseLockfile, type ParsedLockFile} from 'lockparse'; import {detectLockfile, computeDependencyVersions} from './lockfile.js'; import {getFileFromRef, getBaseRef, tryGetJSONFromRef} from './git.js'; @@ -19,7 +20,10 @@ const COMMENT_TAG = ''; async function run(): Promise { try { - const workspacePath = process.env.GITHUB_WORKSPACE || process.cwd(); + const baseWorkspace = process.env.GITHUB_WORKSPACE || process.cwd(); + const workDir = core.getInput('work-dir', { }); + const workspacePath = workDir ? join(baseWorkspace, workDir) : baseWorkspace; + const baseRef = getBaseRef(); const currentRef = github.context.sha; const lockfilePath = detectLockfile(workspacePath); From 07f204071546eb0a6ec89a2e8c3b5665e8e0ba0f Mon Sep 17 00:00:00 2001 From: Humphrey Shotton <1696213+Humpheh@users.noreply.github.com> Date: Wed, 15 Oct 2025 16:27:53 +0100 Subject: [PATCH 02/13] Add some logging --- src/main.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main.ts b/src/main.ts index 11b01b2..14ea3a1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -23,10 +23,13 @@ async function run(): Promise { const baseWorkspace = process.env.GITHUB_WORKSPACE || process.cwd(); const workDir = core.getInput('work-dir', { }); const workspacePath = workDir ? join(baseWorkspace, workDir) : baseWorkspace; + core.info(`Workspace path is ${workspacePath}`); const baseRef = getBaseRef(); const currentRef = github.context.sha; const lockfilePath = detectLockfile(workspacePath); + core.info(`Detected lockfile ${lockfilePath}`); + const token = core.getInput('github-token', {required: true}); const prNumber = parseInt(core.getInput('pr-number', {required: true}), 10); const detectReplacements = core.getBooleanInput('detect-replacements'); From 28d44a5879d0961d6ec94e148d58c433a0d03fad Mon Sep 17 00:00:00 2001 From: Humphrey Shotton <1696213+Humpheh@users.noreply.github.com> Date: Wed, 15 Oct 2025 16:30:57 +0100 Subject: [PATCH 03/13] Commit build --- build/main.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/build/main.js b/build/main.js index f0d55a0..ad418e2 100644 --- a/build/main.js +++ b/build/main.js @@ -23889,6 +23889,7 @@ var require_github = __commonJS({ var core7 = __toESM(require_core(), 1); var github2 = __toESM(require_github(), 1); import * as process2 from "process"; +import { join as join2 } from "node:path"; // node_modules/lockparse/lib/types.js var dependencyTypes = [ @@ -25084,10 +25085,14 @@ ${packRows}` var COMMENT_TAG = ""; async function run() { try { - const workspacePath = process2.env.GITHUB_WORKSPACE || process2.cwd(); + const baseWorkspace = process2.env.GITHUB_WORKSPACE || process2.cwd(); + const workDir = core7.getInput("work-dir", {}); + const workspacePath = workDir ? join2(baseWorkspace, workDir) : baseWorkspace; + core7.info(`Workspace path is ${workspacePath}`); const baseRef = getBaseRef(); const currentRef = github2.context.sha; const lockfilePath = detectLockfile(workspacePath); + core7.info(`Detected lockfile ${lockfilePath}`); const token = core7.getInput("github-token", { required: true }); const prNumber = parseInt(core7.getInput("pr-number", { required: true }), 10); const detectReplacements = core7.getBooleanInput("detect-replacements"); From 858b809040f11fad0c2e2ca99da01c721b7892ef Mon Sep 17 00:00:00 2001 From: Humphrey Shotton <1696213+Humpheh@users.noreply.github.com> Date: Wed, 15 Oct 2025 16:48:58 +0100 Subject: [PATCH 04/13] Added more logging --- src/main.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.ts b/src/main.ts index 14ea3a1..f9ec2cf 100644 --- a/src/main.ts +++ b/src/main.ts @@ -104,6 +104,7 @@ async function run(): Promise { lockfilePath, currentPackageJson ?? undefined ); + core.info(`Parsed current lockfile with ${parsedCurrentLock.packages.length} packages`); } catch (err) { core.setFailed(`Failed to parse current lockfile: ${err}`); return; @@ -114,6 +115,7 @@ async function run(): Promise { lockfilePath, basePackageJson ?? undefined ); + core.info(`Parsed base lockfile with ${parsedBaseLock.packages.length} packages`); } catch (err) { core.setFailed(`Failed to parse base lockfile: ${err}`); return; From b1a1b08b3c5cfe4157b2cdd08c345df4e937a275 Mon Sep 17 00:00:00 2001 From: Humphrey Shotton <1696213+Humpheh@users.noreply.github.com> Date: Wed, 15 Oct 2025 16:51:20 +0100 Subject: [PATCH 05/13] Build --- build/main.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/main.js b/build/main.js index ad418e2..2de6cee 100644 --- a/build/main.js +++ b/build/main.js @@ -25159,6 +25159,7 @@ async function run() { lockfilePath, currentPackageJson ?? void 0 ); + core7.info(`Parsed current lockfile with ${parsedCurrentLock.packages.length} packages`); } catch (err) { core7.setFailed(`Failed to parse current lockfile: ${err}`); return; @@ -25169,6 +25170,7 @@ async function run() { lockfilePath, basePackageJson ?? void 0 ); + core7.info(`Parsed base lockfile with ${parsedBaseLock.packages.length} packages`); } catch (err) { core7.setFailed(`Failed to parse base lockfile: ${err}`); return; From e5b6d04e91ba55483d8cb1d1b0276f95bead200a Mon Sep 17 00:00:00 2001 From: Humphrey Shotton <1696213+Humpheh@users.noreply.github.com> Date: Wed, 15 Oct 2025 16:54:16 +0100 Subject: [PATCH 06/13] More logging --- build/main.js | 8 +++++--- src/main.ts | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/build/main.js b/build/main.js index 2de6cee..2e3e52d 100644 --- a/build/main.js +++ b/build/main.js @@ -25121,7 +25121,7 @@ async function run() { return; } core7.info( - `Comparing package-lock.json between ${baseRef} and ${currentRef}` + `Comparing package lockfiles between ${baseRef} and ${currentRef}` ); const basePackageLock = getFileFromRef( baseRef, @@ -25129,18 +25129,20 @@ async function run() { workspacePath ); if (!basePackageLock) { - core7.info("No package-lock.json found in base ref"); + core7.info("No package lockfile found in base ref"); return; } + core7.info(`Found package lockfile in base ref: ${basePackageLock}`); const currentPackageLock = getFileFromRef( currentRef, lockfilePath, workspacePath ); if (!currentPackageLock) { - core7.info("No package-lock.json found in current ref"); + core7.info("No package lockfile found in current ref"); return; } + core7.info(`Found package lockfile in current ref: ${currentPackageLock}`); const basePackageJson = tryGetJSONFromRef( baseRef, "package.json", diff --git a/src/main.ts b/src/main.ts index f9ec2cf..7459836 100644 --- a/src/main.ts +++ b/src/main.ts @@ -61,7 +61,7 @@ async function run(): Promise { } core.info( - `Comparing package-lock.json between ${baseRef} and ${currentRef}` + `Comparing package lockfiles between ${baseRef} and ${currentRef}` ); const basePackageLock = getFileFromRef( @@ -70,9 +70,10 @@ async function run(): Promise { workspacePath ); if (!basePackageLock) { - core.info('No package-lock.json found in base ref'); + core.info('No package lockfile found in base ref'); return; } + core.info(`Found package lockfile in base ref: ${basePackageLock}`); const currentPackageLock = getFileFromRef( currentRef, @@ -80,9 +81,10 @@ async function run(): Promise { workspacePath ); if (!currentPackageLock) { - core.info('No package-lock.json found in current ref'); + core.info('No package lockfile found in current ref'); return; } + core.info(`Found package lockfile in current ref: ${currentPackageLock}`); const basePackageJson = tryGetJSONFromRef( baseRef, From c418f7577df701a860f46155e90f1d6b3dfc87ca Mon Sep 17 00:00:00 2001 From: Humphrey Shotton <1696213+Humpheh@users.noreply.github.com> Date: Wed, 15 Oct 2025 17:02:18 +0100 Subject: [PATCH 07/13] Try something else --- build/main.js | 14 +++++++------- src/main.ts | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/build/main.js b/build/main.js index 2e3e52d..ee1d590 100644 --- a/build/main.js +++ b/build/main.js @@ -25091,8 +25091,8 @@ async function run() { core7.info(`Workspace path is ${workspacePath}`); const baseRef = getBaseRef(); const currentRef = github2.context.sha; - const lockfilePath = detectLockfile(workspacePath); - core7.info(`Detected lockfile ${lockfilePath}`); + const lockfileFilename = detectLockfile(workspacePath); + core7.info(`Detected lockfile ${lockfileFilename}`); const token = core7.getInput("github-token", { required: true }); const prNumber = parseInt(core7.getInput("pr-number", { required: true }), 10); const detectReplacements = core7.getBooleanInput("detect-replacements"); @@ -25116,10 +25116,12 @@ async function run() { core7.info("No valid pull request number was found. Skipping."); return; } - if (!lockfilePath) { + if (!lockfileFilename) { core7.info("No lockfile detected in the workspace. Exiting."); return; } + const lockfilePath = workDir ? join2(workDir, lockfileFilename || "") : lockfileFilename; + core7.info(`Using lockfile: ${lockfilePath}`); core7.info( `Comparing package lockfiles between ${baseRef} and ${currentRef}` ); @@ -25132,7 +25134,6 @@ async function run() { core7.info("No package lockfile found in base ref"); return; } - core7.info(`Found package lockfile in base ref: ${basePackageLock}`); const currentPackageLock = getFileFromRef( currentRef, lockfilePath, @@ -25142,7 +25143,6 @@ async function run() { core7.info("No package lockfile found in current ref"); return; } - core7.info(`Found package lockfile in current ref: ${currentPackageLock}`); const basePackageJson = tryGetJSONFromRef( baseRef, "package.json", @@ -25158,7 +25158,7 @@ async function run() { try { parsedCurrentLock = await parse( currentPackageLock, - lockfilePath, + lockfileFilename, currentPackageJson ?? void 0 ); core7.info(`Parsed current lockfile with ${parsedCurrentLock.packages.length} packages`); @@ -25169,7 +25169,7 @@ async function run() { try { parsedBaseLock = await parse( basePackageLock, - lockfilePath, + lockfileFilename, basePackageJson ?? void 0 ); core7.info(`Parsed base lockfile with ${parsedBaseLock.packages.length} packages`); diff --git a/src/main.ts b/src/main.ts index 7459836..b670f5f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -27,8 +27,8 @@ async function run(): Promise { const baseRef = getBaseRef(); const currentRef = github.context.sha; - const lockfilePath = detectLockfile(workspacePath); - core.info(`Detected lockfile ${lockfilePath}`); + const lockfileFilename = detectLockfile(workspacePath); + core.info(`Detected lockfile ${lockfileFilename}`); const token = core.getInput('github-token', {required: true}); const prNumber = parseInt(core.getInput('pr-number', {required: true}), 10); @@ -55,10 +55,12 @@ async function run(): Promise { return; } - if (!lockfilePath) { + if (!lockfileFilename) { core.info('No lockfile detected in the workspace. Exiting.'); return; } + const lockfilePath = workDir ? join(workDir, lockfileFilename || '') : lockfileFilename; + core.info(`Using lockfile: ${lockfilePath}`); core.info( `Comparing package lockfiles between ${baseRef} and ${currentRef}` @@ -73,7 +75,6 @@ async function run(): Promise { core.info('No package lockfile found in base ref'); return; } - core.info(`Found package lockfile in base ref: ${basePackageLock}`); const currentPackageLock = getFileFromRef( currentRef, @@ -84,7 +85,6 @@ async function run(): Promise { core.info('No package lockfile found in current ref'); return; } - core.info(`Found package lockfile in current ref: ${currentPackageLock}`); const basePackageJson = tryGetJSONFromRef( baseRef, @@ -103,7 +103,7 @@ async function run(): Promise { try { parsedCurrentLock = await parseLockfile( currentPackageLock, - lockfilePath, + lockfileFilename, currentPackageJson ?? undefined ); core.info(`Parsed current lockfile with ${parsedCurrentLock.packages.length} packages`); @@ -114,7 +114,7 @@ async function run(): Promise { try { parsedBaseLock = await parseLockfile( basePackageLock, - lockfilePath, + lockfileFilename, basePackageJson ?? undefined ); core.info(`Parsed base lockfile with ${parsedBaseLock.packages.length} packages`); From 08ad4df895aac509b7e9fbd9c07cafc55aef3997 Mon Sep 17 00:00:00 2001 From: Humphrey Shotton <1696213+Humpheh@users.noreply.github.com> Date: Wed, 15 Oct 2025 17:04:42 +0100 Subject: [PATCH 08/13] Test --- build/main.js | 4 ++-- src/main.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/main.js b/build/main.js index ee1d590..e1adb8b 100644 --- a/build/main.js +++ b/build/main.js @@ -25128,7 +25128,7 @@ async function run() { const basePackageLock = getFileFromRef( baseRef, lockfilePath, - workspacePath + baseWorkspace ); if (!basePackageLock) { core7.info("No package lockfile found in base ref"); @@ -25137,7 +25137,7 @@ async function run() { const currentPackageLock = getFileFromRef( currentRef, lockfilePath, - workspacePath + baseWorkspace ); if (!currentPackageLock) { core7.info("No package lockfile found in current ref"); diff --git a/src/main.ts b/src/main.ts index b670f5f..c2f6c87 100644 --- a/src/main.ts +++ b/src/main.ts @@ -69,7 +69,7 @@ async function run(): Promise { const basePackageLock = getFileFromRef( baseRef, lockfilePath, - workspacePath + baseWorkspace ); if (!basePackageLock) { core.info('No package lockfile found in base ref'); @@ -79,7 +79,7 @@ async function run(): Promise { const currentPackageLock = getFileFromRef( currentRef, lockfilePath, - workspacePath + baseWorkspace ); if (!currentPackageLock) { core.info('No package lockfile found in current ref'); From e81bf26041b7c93bc320ba4000d2e99fc7eb2d83 Mon Sep 17 00:00:00 2001 From: Humphrey Shotton <1696213+Humpheh@users.noreply.github.com> Date: Wed, 15 Oct 2025 17:21:43 +0100 Subject: [PATCH 09/13] No max buffer size --- build/main.js | 3 ++- src/git.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/build/main.js b/build/main.js index e1adb8b..f14a269 100644 --- a/build/main.js +++ b/build/main.js @@ -24463,7 +24463,8 @@ function getFileFromRef(ref, filePath, cwd2) { const content = execFileSync("git", ["show", `${ref}:${filePath}`], { encoding: "utf8", cwd: cwd2, - stdio: "pipe" + stdio: "pipe", + maxBuffer: 1e10 }); return content; } catch { diff --git a/src/git.ts b/src/git.ts index 9678e8e..971478e 100644 --- a/src/git.ts +++ b/src/git.ts @@ -11,7 +11,8 @@ export function getFileFromRef( const content = execFileSync('git', ['show', `${ref}:${filePath}`], { encoding: 'utf8', cwd, - stdio: 'pipe' + stdio: 'pipe', + maxBuffer: 10000000000 }); return content; } catch { From d9f1487cb4683cb72dc1d63df8d8a375e0b92918 Mon Sep 17 00:00:00 2001 From: Humphrey Shotton <1696213+Humpheh@users.noreply.github.com> Date: Wed, 15 Oct 2025 20:22:06 +0100 Subject: [PATCH 10/13] Tidy --- README.md | 25 +++---- action.yml | 4 +- build/main.js | 186 +++++++++++++++++++++++++------------------------- src/git.ts | 8 ++- src/main.ts | 6 +- 5 files changed, 117 insertions(+), 112 deletions(-) diff --git a/README.md b/README.md index ae55447..fcdb742 100644 --- a/README.md +++ b/README.md @@ -37,18 +37,19 @@ jobs: ## Inputs -| Name | Description | Required | Default | -|------|-------------|----------|---------| -| `base-ref` | Base ref to compare against (defaults to main or PR target) | No | Auto-detected from PR or `main` | -| `github-token` | The GitHub token for authentication | Yes | `${{ github.token }}` | -| `pr-number` | The number of the pull request to comment on | Yes | `${{ github.event.pull_request.number }}` | -| `dependency-threshold` | Threshold for warning about significant increase in number of dependencies | No | `10` | -| `size-threshold` | Threshold (in bytes) for warning about significant increase in package size | No | `100000` | -| `duplicate-threshold` | Threshold for warning about packages with multiple versions | No | `1` | -| `base-packages` | Glob pattern for base branch pack files (e.g., `"./base-packs/*.tgz"`) | No | None | -| `source-packages` | Glob pattern for source branch pack files (e.g., `"./source-packs/*.tgz"`) | No | None | -| `pack-size-threshold` | Threshold (in bytes) for warning about significant increase in total pack size | No | `50000` | -| `detect-replacements` | Detect modules which have community suggested alternatives | No | `true` | +| Name | Description | Required | Default | +|------------------------|--------------------------------------------------------------------------------|----------|-------------------------------------------| +| `base-ref` | Base ref to compare against (defaults to main or PR target) | No | Auto-detected from PR or `main` | +| `github-token` | The GitHub token for authentication | Yes | `${{ github.token }}` | +| `pr-number` | The number of the pull request to comment on | Yes | `${{ github.event.pull_request.number }}` | +| `dependency-threshold` | Threshold for warning about significant increase in number of dependencies | No | `10` | +| `size-threshold` | Threshold (in bytes) for warning about significant increase in package size | No | `100000` | +| `duplicate-threshold` | Threshold for warning about packages with multiple versions | No | `1` | +| `base-packages` | Glob pattern for base branch pack files (e.g., `"./base-packs/*.tgz"`) | No | None | +| `source-packages` | Glob pattern for source branch pack files (e.g., `"./source-packs/*.tgz"`) | No | None | +| `pack-size-threshold` | Threshold (in bytes) for warning about significant increase in total pack size | No | `50000` | +| `detect-replacements` | Detect modules which have community suggested alternatives | No | `true` | +| `working-directory` | Working directory to scan for package lock file | No | None | ## Example with custom inputs diff --git a/action.yml b/action.yml index ffe637b..9c4c9b4 100644 --- a/action.yml +++ b/action.yml @@ -44,8 +44,8 @@ inputs: description: 'Detect modules which have community suggested alternatives' required: false default: true - work-dir: - description: 'Working directory' + working-directory: + description: 'Working directory to scan for package lock file' required: false runs: diff --git a/build/main.js b/build/main.js index f14a269..a4018a7 100644 --- a/build/main.js +++ b/build/main.js @@ -426,18 +426,18 @@ var require_tunnel = __commonJS({ res.statusCode ); socket.destroy(); - var error = new Error("tunneling socket could not be established, statusCode=" + res.statusCode); - error.code = "ECONNRESET"; - options.request.emit("error", error); + var error2 = new Error("tunneling socket could not be established, statusCode=" + res.statusCode); + error2.code = "ECONNRESET"; + options.request.emit("error", error2); self.removeSocket(placeholder); return; } if (head.length > 0) { debug("got illegal response body from proxy"); socket.destroy(); - var error = new Error("got illegal response body from proxy"); - error.code = "ECONNRESET"; - options.request.emit("error", error); + var error2 = new Error("got illegal response body from proxy"); + error2.code = "ECONNRESET"; + options.request.emit("error", error2); self.removeSocket(placeholder); return; } @@ -452,9 +452,9 @@ var require_tunnel = __commonJS({ cause.message, cause.stack ); - var error = new Error("tunneling socket could not be established, cause=" + cause.message); - error.code = "ECONNRESET"; - options.request.emit("error", error); + var error2 = new Error("tunneling socket could not be established, cause=" + cause.message); + error2.code = "ECONNRESET"; + options.request.emit("error", error2); self.removeSocket(placeholder); } }; @@ -5582,7 +5582,7 @@ Content-Type: ${value.type || "application/octet-stream"}\r throw new TypeError("Body is unusable"); } const promise = createDeferredPromise(); - const errorSteps = (error) => promise.reject(error); + const errorSteps = (error2) => promise.reject(error2); const successSteps = (data) => { try { promise.resolve(convertBytesToJSValue(data)); @@ -5868,16 +5868,16 @@ var require_request = __commonJS({ this.onError(err); } } - onError(error) { + onError(error2) { this.onFinally(); if (channels.error.hasSubscribers) { - channels.error.publish({ request: this, error }); + channels.error.publish({ request: this, error: error2 }); } if (this.aborted) { return; } this.aborted = true; - return this[kHandler].onError(error); + return this[kHandler].onError(error2); } onFinally() { if (this.errorHandler) { @@ -6740,8 +6740,8 @@ var require_RedirectHandler = __commonJS({ onUpgrade(statusCode, headers, socket) { this.handler.onUpgrade(statusCode, headers, socket); } - onError(error) { - this.handler.onError(error); + onError(error2) { + this.handler.onError(error2); } onHeaders(statusCode, headers, resume, statusText) { this.location = this.history.length >= this.maxRedirections || util.isDisturbed(this.opts.body) ? null : parseLocation(statusCode, headers); @@ -8882,7 +8882,7 @@ var require_pool = __commonJS({ this[kOptions] = { ...util.deepClone(options), connect, allowH2 }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kFactory] = factory; - this.on("connectionError", (origin2, targets, error) => { + this.on("connectionError", (origin2, targets, error2) => { for (const target of targets) { const idx = this[kClients].indexOf(target); if (idx !== -1) { @@ -10491,13 +10491,13 @@ var require_mock_utils = __commonJS({ if (mockDispatch2.data.callback) { mockDispatch2.data = { ...mockDispatch2.data, ...mockDispatch2.data.callback(opts) }; } - const { data: { statusCode, data, headers, trailers, error }, delay, persist } = mockDispatch2; + const { data: { statusCode, data, headers, trailers, error: error2 }, delay, persist } = mockDispatch2; const { timesInvoked, times } = mockDispatch2; mockDispatch2.consumed = !persist && timesInvoked >= times; mockDispatch2.pending = timesInvoked < times; - if (error !== null) { + if (error2 !== null) { deleteMockDispatch(this[kDispatches], key); - handler.onError(error); + handler.onError(error2); return true; } if (typeof delay === "number" && delay > 0) { @@ -10535,19 +10535,19 @@ var require_mock_utils = __commonJS({ if (agent.isMockActive) { try { mockDispatch.call(this, opts, handler); - } catch (error) { - if (error instanceof MockNotMatchedError) { + } catch (error2) { + if (error2 instanceof MockNotMatchedError) { const netConnect = agent[kGetNetConnect](); if (netConnect === false) { - throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect disabled)`); + throw new MockNotMatchedError(`${error2.message}: subsequent request to origin ${origin} was not allowed (net.connect disabled)`); } if (checkNetConnect(netConnect, origin)) { originalDispatch.call(this, opts, handler); } else { - throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect is not enabled for this origin)`); + throw new MockNotMatchedError(`${error2.message}: subsequent request to origin ${origin} was not allowed (net.connect is not enabled for this origin)`); } } else { - throw error; + throw error2; } } } else { @@ -10710,11 +10710,11 @@ var require_mock_interceptor = __commonJS({ /** * Mock an undici request with a defined error. */ - replyWithError(error) { - if (typeof error === "undefined") { + replyWithError(error2) { + if (typeof error2 === "undefined") { throw new InvalidArgumentError("error must be defined"); } - const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], { error }); + const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], { error: error2 }); return new MockScope(newMockDispatch); } /** @@ -13041,17 +13041,17 @@ var require_fetch = __commonJS({ this.emit("terminated", reason); } // https://fetch.spec.whatwg.org/#fetch-controller-abort - abort(error) { + abort(error2) { if (this.state !== "ongoing") { return; } this.state = "aborted"; - if (!error) { - error = new DOMException2("The operation was aborted.", "AbortError"); + if (!error2) { + error2 = new DOMException2("The operation was aborted.", "AbortError"); } - this.serializedAbortReason = error; - this.connection?.destroy(error); - this.emit("terminated", error); + this.serializedAbortReason = error2; + this.connection?.destroy(error2); + this.emit("terminated", error2); } }; function fetch2(input, init = {}) { @@ -13155,13 +13155,13 @@ var require_fetch = __commonJS({ performance.markResourceTiming(timingInfo, originalURL.href, initiatorType, globalThis2, cacheState); } } - function abortFetch(p, request, responseObject, error) { - if (!error) { - error = new DOMException2("The operation was aborted.", "AbortError"); + function abortFetch(p, request, responseObject, error2) { + if (!error2) { + error2 = new DOMException2("The operation was aborted.", "AbortError"); } - p.reject(error); + p.reject(error2); if (request.body != null && isReadable(request.body?.stream)) { - request.body.stream.cancel(error).catch((err) => { + request.body.stream.cancel(error2).catch((err) => { if (err.code === "ERR_INVALID_STATE") { return; } @@ -13173,7 +13173,7 @@ var require_fetch = __commonJS({ } const response = responseObject[kState]; if (response.body != null && isReadable(response.body?.stream)) { - response.body.stream.cancel(error).catch((err) => { + response.body.stream.cancel(error2).catch((err) => { if (err.code === "ERR_INVALID_STATE") { return; } @@ -13953,13 +13953,13 @@ var require_fetch = __commonJS({ fetchParams.controller.ended = true; this.body.push(null); }, - onError(error) { + onError(error2) { if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - this.body?.destroy(error); - fetchParams.controller.terminate(error); - reject(error); + this.body?.destroy(error2); + fetchParams.controller.terminate(error2); + reject(error2); }, onUpgrade(status, headersList, socket) { if (status !== 101) { @@ -14425,8 +14425,8 @@ var require_util4 = __commonJS({ } fr[kResult] = result; fireAProgressEvent("load", fr); - } catch (error) { - fr[kError] = error; + } catch (error2) { + fr[kError] = error2; fireAProgressEvent("error", fr); } if (fr[kState] !== "loading") { @@ -14435,13 +14435,13 @@ var require_util4 = __commonJS({ }); break; } - } catch (error) { + } catch (error2) { if (fr[kAborted]) { return; } queueMicrotask(() => { fr[kState] = "done"; - fr[kError] = error; + fr[kError] = error2; fireAProgressEvent("error", fr); if (fr[kState] !== "loading") { fireAProgressEvent("loadend", fr); @@ -16441,11 +16441,11 @@ var require_connection = __commonJS({ }); } } - function onSocketError(error) { + function onSocketError(error2) { const { ws } = this; ws[kReadyState] = states.CLOSING; if (channels.socketError.hasSubscribers) { - channels.socketError.publish(error); + channels.socketError.publish(error2); } this.destroy(); } @@ -18077,12 +18077,12 @@ var require_oidc_utils = __commonJS({ var _a; return __awaiter(this, void 0, void 0, function* () { const httpclient = _OidcClient.createHttpClient(); - const res = yield httpclient.getJson(id_token_url).catch((error) => { + const res = yield httpclient.getJson(id_token_url).catch((error2) => { throw new Error(`Failed to get ID Token. - Error Code : ${error.statusCode} + Error Code : ${error2.statusCode} - Error Message: ${error.message}`); + Error Message: ${error2.message}`); }); const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value; if (!id_token) { @@ -18103,8 +18103,8 @@ var require_oidc_utils = __commonJS({ const id_token = yield _OidcClient.getCall(id_token_url); (0, core_1.setSecret)(id_token); return id_token; - } catch (error) { - throw new Error(`Error message: ${error.message}`); + } catch (error2) { + throw new Error(`Error message: ${error2.message}`); } }); } @@ -19226,7 +19226,7 @@ var require_toolrunner = __commonJS({ this._debug(`STDIO streams have closed for tool '${this.toolPath}'`); state.CheckComplete(); }); - state.on("done", (error, exitCode) => { + state.on("done", (error2, exitCode) => { if (stdbuffer.length > 0) { this.emit("stdline", stdbuffer); } @@ -19234,8 +19234,8 @@ var require_toolrunner = __commonJS({ this.emit("errline", errbuffer); } cp.removeAllListeners(); - if (error) { - reject(error); + if (error2) { + reject(error2); } else { resolve(exitCode); } @@ -19330,14 +19330,14 @@ var require_toolrunner = __commonJS({ this.emit("debug", message); } _setResult() { - let error; + let error2; if (this.processExited) { if (this.processError) { - error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`); + error2 = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`); } else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) { - error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`); + error2 = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`); } else if (this.processStderr && this.options.failOnStdErr) { - error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`); + error2 = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`); } } if (this.timeout) { @@ -19345,7 +19345,7 @@ var require_toolrunner = __commonJS({ this.timeout = null; } this.done = true; - this.emit("done", error, this.processExitCode); + this.emit("done", error2, this.processExitCode); } static HandleTimeout(state) { if (state.done) { @@ -19728,7 +19728,7 @@ Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); exports.setCommandEcho = setCommandEcho; function setFailed2(message) { process.exitCode = ExitCode.Failure; - error(message); + error2(message); } exports.setFailed = setFailed2; function isDebug() { @@ -19739,10 +19739,10 @@ Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); (0, command_1.issueCommand)("debug", {}, message); } exports.debug = debug; - function error(message, properties = {}) { + function error2(message, properties = {}) { (0, command_1.issueCommand)("error", (0, utils_1.toCommandProperties)(properties), message instanceof Error ? message.toString() : message); } - exports.error = error; + exports.error = error2; function warning(message, properties = {}) { (0, command_1.issueCommand)("warning", (0, utils_1.toCommandProperties)(properties), message instanceof Error ? message.toString() : message); } @@ -20044,8 +20044,8 @@ var require_add = __commonJS({ } if (kind === "error") { hook = function(method, options) { - return Promise.resolve().then(method.bind(null, options)).catch(function(error) { - return orig(error, options); + return Promise.resolve().then(method.bind(null, options)).catch(function(error2) { + return orig(error2, options); }); }; } @@ -20777,7 +20777,7 @@ var require_dist_node5 = __commonJS({ } if (status >= 400) { const data = await getResponseData(response); - const error = new import_request_error.RequestError(toErrorMessage(data), status, { + const error2 = new import_request_error.RequestError(toErrorMessage(data), status, { response: { url, status, @@ -20786,7 +20786,7 @@ var require_dist_node5 = __commonJS({ }, request: requestOptions }); - throw error; + throw error2; } return parseSuccessResponseBody ? await getResponseData(response) : response.body; }).then((data) => { @@ -20796,17 +20796,17 @@ var require_dist_node5 = __commonJS({ headers, data }; - }).catch((error) => { - if (error instanceof import_request_error.RequestError) - throw error; - else if (error.name === "AbortError") - throw error; - let message = error.message; - if (error.name === "TypeError" && "cause" in error) { - if (error.cause instanceof Error) { - message = error.cause.message; - } else if (typeof error.cause === "string") { - message = error.cause; + }).catch((error2) => { + if (error2 instanceof import_request_error.RequestError) + throw error2; + else if (error2.name === "AbortError") + throw error2; + let message = error2.message; + if (error2.name === "TypeError" && "cause" in error2) { + if (error2.cause instanceof Error) { + message = error2.cause.message; + } else if (typeof error2.cause === "string") { + message = error2.cause; } } throw new import_request_error.RequestError(message, 500, { @@ -23478,9 +23478,9 @@ var require_dist_node10 = __commonJS({ /<([^<>]+)>;\s*rel="next"/ ) || [])[1]; return { value: normalizedResponse }; - } catch (error) { - if (error.status !== 409) - throw error; + } catch (error2) { + if (error2.status !== 409) + throw error2; url = ""; return { value: { @@ -24459,15 +24459,17 @@ var core = __toESM(require_core(), 1); var github = __toESM(require_github(), 1); import { execFileSync } from "child_process"; function getFileFromRef(ref, filePath, cwd2) { + const refFilePath = `${ref}:${filePath}`; try { - const content = execFileSync("git", ["show", `${ref}:${filePath}`], { + const content = execFileSync("git", ["show", refFilePath], { encoding: "utf8", cwd: cwd2, stdio: "pipe", - maxBuffer: 1e10 + maxBuffer: 1024 * 1024 * 100 }); return content; - } catch { + } catch (e) { + core.error(`Failed to get file from ref "${refFilePath}": ${e}`); return null; } } @@ -25087,8 +25089,8 @@ var COMMENT_TAG = ""; async function run() { try { const baseWorkspace = process2.env.GITHUB_WORKSPACE || process2.cwd(); - const workDir = core7.getInput("work-dir", {}); - const workspacePath = workDir ? join2(baseWorkspace, workDir) : baseWorkspace; + const workDir = core7.getInput("working-directory") || "."; + const workspacePath = join2(baseWorkspace, workDir); core7.info(`Workspace path is ${workspacePath}`); const baseRef = getBaseRef(); const currentRef = github2.context.sha; @@ -25121,7 +25123,7 @@ async function run() { core7.info("No lockfile detected in the workspace. Exiting."); return; } - const lockfilePath = workDir ? join2(workDir, lockfileFilename || "") : lockfileFilename; + const lockfilePath = join2(workDir, lockfileFilename); core7.info(`Using lockfile: ${lockfilePath}`); core7.info( `Comparing package lockfiles between ${baseRef} and ${currentRef}` @@ -25287,9 +25289,9 @@ ${messages.join("\n\n")}`; }); core7.info("Created new dependency diff comment"); } - } catch (error) { - if (error instanceof Error) { - core7.setFailed(error.message); + } catch (error2) { + if (error2 instanceof Error) { + core7.setFailed(error2.message); } else { core7.setFailed("An unknown error occurred."); } diff --git a/src/git.ts b/src/git.ts index 971478e..30667fb 100644 --- a/src/git.ts +++ b/src/git.ts @@ -7,15 +7,17 @@ export function getFileFromRef( filePath: string, cwd: string ): string | null { + const refFilePath = `${ref}:${filePath}`; try { - const content = execFileSync('git', ['show', `${ref}:${filePath}`], { + const content = execFileSync('git', ['show', refFilePath], { encoding: 'utf8', cwd, stdio: 'pipe', - maxBuffer: 10000000000 + maxBuffer: 1024 * 1024 * 100 }); return content; - } catch { + } catch (e) { + core.error(`Failed to get file from ref "${refFilePath}": ${e}`); return null; } } diff --git a/src/main.ts b/src/main.ts index c2f6c87..362c268 100644 --- a/src/main.ts +++ b/src/main.ts @@ -21,8 +21,8 @@ const COMMENT_TAG = ''; async function run(): Promise { try { const baseWorkspace = process.env.GITHUB_WORKSPACE || process.cwd(); - const workDir = core.getInput('work-dir', { }); - const workspacePath = workDir ? join(baseWorkspace, workDir) : baseWorkspace; + const workDir = core.getInput('working-directory') || '.'; + const workspacePath = join(baseWorkspace, workDir); core.info(`Workspace path is ${workspacePath}`); const baseRef = getBaseRef(); @@ -59,7 +59,7 @@ async function run(): Promise { core.info('No lockfile detected in the workspace. Exiting.'); return; } - const lockfilePath = workDir ? join(workDir, lockfileFilename || '') : lockfileFilename; + const lockfilePath = join(workDir, lockfileFilename); core.info(`Using lockfile: ${lockfilePath}`); core.info( From d77b9e1d6804fc98aea111a128de14caeadaee35 Mon Sep 17 00:00:00 2001 From: Humphrey Shotton <1696213+Humpheh@users.noreply.github.com> Date: Wed, 15 Oct 2025 20:23:58 +0100 Subject: [PATCH 11/13] Format --- build/main.js | 8 ++++++-- src/main.ts | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/build/main.js b/build/main.js index a4018a7..8ea0c9c 100644 --- a/build/main.js +++ b/build/main.js @@ -25164,7 +25164,9 @@ async function run() { lockfileFilename, currentPackageJson ?? void 0 ); - core7.info(`Parsed current lockfile with ${parsedCurrentLock.packages.length} packages`); + core7.info( + `Parsed current lockfile with ${parsedCurrentLock.packages.length} packages` + ); } catch (err) { core7.setFailed(`Failed to parse current lockfile: ${err}`); return; @@ -25175,7 +25177,9 @@ async function run() { lockfileFilename, basePackageJson ?? void 0 ); - core7.info(`Parsed base lockfile with ${parsedBaseLock.packages.length} packages`); + core7.info( + `Parsed base lockfile with ${parsedBaseLock.packages.length} packages` + ); } catch (err) { core7.setFailed(`Failed to parse base lockfile: ${err}`); return; diff --git a/src/main.ts b/src/main.ts index 362c268..6999bfc 100644 --- a/src/main.ts +++ b/src/main.ts @@ -106,7 +106,9 @@ async function run(): Promise { lockfileFilename, currentPackageJson ?? undefined ); - core.info(`Parsed current lockfile with ${parsedCurrentLock.packages.length} packages`); + core.info( + `Parsed current lockfile with ${parsedCurrentLock.packages.length} packages` + ); } catch (err) { core.setFailed(`Failed to parse current lockfile: ${err}`); return; @@ -117,7 +119,9 @@ async function run(): Promise { lockfileFilename, basePackageJson ?? undefined ); - core.info(`Parsed base lockfile with ${parsedBaseLock.packages.length} packages`); + core.info( + `Parsed base lockfile with ${parsedBaseLock.packages.length} packages` + ); } catch (err) { core.setFailed(`Failed to parse base lockfile: ${err}`); return; From adb7073cf291001786e7c454fc14191757039af9 Mon Sep 17 00:00:00 2001 From: Humphrey Shotton <1696213+Humpheh@users.noreply.github.com> Date: Thu, 16 Oct 2025 12:33:57 +0100 Subject: [PATCH 12/13] Alter tests to mock error logging --- build/main.js | 7 ++++--- src/git.ts | 7 ++++--- test/git_test.ts | 50 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/build/main.js b/build/main.js index 8ea0c9c..4ccccab 100644 --- a/build/main.js +++ b/build/main.js @@ -24461,13 +24461,12 @@ import { execFileSync } from "child_process"; function getFileFromRef(ref, filePath, cwd2) { const refFilePath = `${ref}:${filePath}`; try { - const content = execFileSync("git", ["show", refFilePath], { + return execFileSync("git", ["show", refFilePath], { encoding: "utf8", cwd: cwd2, stdio: "pipe", maxBuffer: 1024 * 1024 * 100 }); - return content; } catch (e) { core.error(`Failed to get file from ref "${refFilePath}": ${e}`); return null; @@ -24478,7 +24477,9 @@ function tryGetJSONFromRef(ref, filePath, cwd2) { if (content) { try { return JSON.parse(content); - } catch { + } catch (e) { + const refFilePath = `${ref}:${filePath}`; + core.error(`Failed to get json from ref "${refFilePath}": ${e}`); return null; } } diff --git a/src/git.ts b/src/git.ts index 30667fb..0d31366 100644 --- a/src/git.ts +++ b/src/git.ts @@ -9,13 +9,12 @@ export function getFileFromRef( ): string | null { const refFilePath = `${ref}:${filePath}`; try { - const content = execFileSync('git', ['show', refFilePath], { + return execFileSync('git', ['show', refFilePath], { encoding: 'utf8', cwd, stdio: 'pipe', maxBuffer: 1024 * 1024 * 100 }); - return content; } catch (e) { core.error(`Failed to get file from ref "${refFilePath}": ${e}`); return null; @@ -31,7 +30,9 @@ export function tryGetJSONFromRef( if (content) { try { return JSON.parse(content); - } catch { + } catch (e) { + const refFilePath = `${ref}:${filePath}`; + core.error(`Failed to get json from ref "${refFilePath}": ${e}`); return null; } } diff --git a/test/git_test.ts b/test/git_test.ts index 3210666..7b75641 100644 --- a/test/git_test.ts +++ b/test/git_test.ts @@ -1,9 +1,18 @@ -import {describe, it, expect} from 'vitest'; +import { + describe, + it, + expect, + beforeEach, + vi, + afterEach, + type MockInstance +} from 'vitest'; import * as git from '../src/git.js'; import * as github from '@actions/github'; import * as process from 'process'; import {fileURLToPath} from 'node:url'; import * as path from 'node:path'; +import * as importedCore from '@actions/core'; const currentDir = path.dirname(fileURLToPath(import.meta.url)); const rootDir = path.join(currentDir, '..'); @@ -60,32 +69,71 @@ describe('getBaseRef', () => { }); describe('getFileFromRef', () => { + let errorSpy: MockInstance<(typeof importedCore)['error']>; + + beforeEach(() => { + errorSpy = vi.spyOn(importedCore, 'error'); + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + it('should return file content from a given ref', () => { const content = git.getFileFromRef('HEAD', 'package.json', rootDir); expect(content).toBeDefined(); expect(content).toContain('"name":'); + expect(errorSpy.mock.calls).toEqual([]); }); it('should return null if file does not exist in the given ref', () => { const content = git.getFileFromRef('HEAD', 'nonexistentfile.txt', rootDir); expect(content).toBeNull(); + expect(errorSpy.mock.calls).toEqual([ + [ + 'Failed to get file from ref "HEAD:nonexistentfile.txt": Error: Command failed: git show HEAD:nonexistentfile.txt\n' + + "fatal: path 'nonexistentfile.txt' does not exist in 'HEAD'\n" + ] + ]); }); }); describe('tryGetJSONFromRef', () => { + let errorSpy: MockInstance<(typeof importedCore)['error']>; + + beforeEach(() => { + errorSpy = vi.spyOn(importedCore, 'error'); + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + it('returns null for non-existent file', () => { const result = git.tryGetJSONFromRef('HEAD', 'nonexistent.json', rootDir); expect(result).toBeNull(); + expect(errorSpy.mock.calls).toEqual([ + [ + 'Failed to get file from ref "HEAD:nonexistent.json": Error: Command failed: git show HEAD:nonexistent.json\n' + + "fatal: path 'nonexistent.json' does not exist in 'HEAD'\n" + ] + ]); }); it('returns null for invalid JSON content', () => { const result = git.tryGetJSONFromRef('HEAD', 'README.md', rootDir); expect(result).toBeNull(); + expect(errorSpy.mock.calls).toEqual([ + [ + `Failed to get json from ref "HEAD:README.md": SyntaxError: Unexpected token '#', "# e18e/act"... is not valid JSON` + ] + ]); }); it('returns parsed JSON object for valid JSON content', () => { const result = git.tryGetJSONFromRef('HEAD', 'package.json', rootDir); expect(result).toBeDefined(); expect(result).toHaveProperty('name'); + expect(errorSpy.mock.calls).toEqual([]); }); }); From 252516ae1e78f47d131adf5e2d364bca9a66404c Mon Sep 17 00:00:00 2001 From: Humphrey Shotton <1696213+Humpheh@users.noreply.github.com> Date: Thu, 16 Oct 2025 14:21:05 +0100 Subject: [PATCH 13/13] Try this --- test/git_test.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/test/git_test.ts b/test/git_test.ts index 7b75641..16be422 100644 --- a/test/git_test.ts +++ b/test/git_test.ts @@ -12,7 +12,7 @@ import * as github from '@actions/github'; import * as process from 'process'; import {fileURLToPath} from 'node:url'; import * as path from 'node:path'; -import * as importedCore from '@actions/core'; +import * as core from '@actions/core'; const currentDir = path.dirname(fileURLToPath(import.meta.url)); const rootDir = path.join(currentDir, '..'); @@ -69,10 +69,14 @@ describe('getBaseRef', () => { }); describe('getFileFromRef', () => { - let errorSpy: MockInstance<(typeof importedCore)['error']>; + let errorSpy: MockInstance<(typeof core)['error']>; beforeEach(() => { - errorSpy = vi.spyOn(importedCore, 'error'); + vi.mock(import('@actions/core'), async (importModule) => { + const mod = await importModule(); + return {...mod, error: vi.fn()}; + }); + errorSpy = vi.mocked(core.error); }); afterEach(() => { @@ -99,10 +103,14 @@ describe('getFileFromRef', () => { }); describe('tryGetJSONFromRef', () => { - let errorSpy: MockInstance<(typeof importedCore)['error']>; + let errorSpy: MockInstance<(typeof core)['error']>; beforeEach(() => { - errorSpy = vi.spyOn(importedCore, 'error'); + vi.mock(import('@actions/core'), async (importModule) => { + const mod = await importModule(); + return {...mod, error: vi.fn()}; + }); + errorSpy = vi.mocked(core.error); }); afterEach(() => {