From 59ce3a25ba97f6eccde6eb1e3c559d7b410ff597 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 15 Sep 2026 19:57:17 +0100 Subject: [PATCH] Include failed bundle attempts in fallback timing Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- lib/entry-points.js | 23 +++++++++++++---------- src/setup-codeql.test.ts | 28 ++++++++++++++++++++++++---- src/setup-codeql.ts | 3 +++ 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 88ad90dcf..01091d39a 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -4305,7 +4305,7 @@ var require_util2 = __commonJS({ var { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = require_constants3(); var { getGlobalOrigin } = require_global(); var { collectASequenceOfCodePoints, collectAnHTTPQuotedString, removeChars, parseMIMEType } = require_data_url(); - var { performance: performance6 } = require("node:perf_hooks"); + var { performance: performance7 } = require("node:perf_hooks"); var { isBlobLike, ReadableStreamFrom, isValidHTTPToken, normalizedMethodRecordsBase } = require_util(); var assert = require("node:assert"); var { isUint8Array } = require("node:util/types"); @@ -4464,7 +4464,7 @@ var require_util2 = __commonJS({ }; } function coarsenedSharedCurrentTime(crossOriginIsolatedCapability) { - return coarsenTime(performance6.now(), crossOriginIsolatedCapability); + return coarsenTime(performance7.now(), crossOriginIsolatedCapability); } function createOpaqueTimingInfo(timingInfo) { return { @@ -142119,7 +142119,7 @@ module.exports = __toCommonJS(entry_points_exports); // src/analyze-action.ts var fs23 = __toESM(require("fs")); var import_path5 = __toESM(require("path")); -var import_perf_hooks4 = require("perf_hooks"); +var import_perf_hooks5 = require("perf_hooks"); var core17 = __toESM(require_core()); // src/action-common.ts @@ -148611,7 +148611,7 @@ var SarifScanOrder = [ // src/analyze.ts var fs17 = __toESM(require("fs")); var path16 = __toESM(require("path")); -var import_perf_hooks3 = require("perf_hooks"); +var import_perf_hooks4 = require("perf_hooks"); var io5 = __toESM(require_io()); // src/autobuild.ts @@ -151194,6 +151194,7 @@ async function logGeneratedFilesTelemetry(config, duration, generatedFilesCount) // src/setup-codeql.ts var fs14 = __toESM(require("fs")); var path13 = __toESM(require("path")); +var import_perf_hooks3 = require("perf_hooks"); var core12 = __toESM(require_core()); var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); @@ -152632,6 +152633,7 @@ async function downloadCodeQLBundle(action, source, apiDetails, tarVersion, temp const { bundle } = source; const { logger } = action; await tryDeleteToolcacheBundles(action); + const startTime = import_perf_hooks3.performance.now(); try { const result = await downloadCodeQL( source, @@ -152668,6 +152670,7 @@ async function downloadCodeQLBundle(action, source, apiDetails, tarVersion, temp ...result, statusReport: { ...result.statusReport, + totalDurationMs: Math.round(import_perf_hooks3.performance.now() - startTime), perLanguageBundleFallback: true } }; @@ -153834,10 +153837,10 @@ function dbIsFinalized(config, language, logger) { } } async function finalizeDatabaseCreation(codeql, features, config, threadsFlag, memoryFlag, logger) { - const extractionStart = import_perf_hooks3.performance.now(); + const extractionStart = import_perf_hooks4.performance.now(); await runExtraction(codeql, features, config, logger); - const extractionTime = import_perf_hooks3.performance.now() - extractionStart; - const trapImportStart = import_perf_hooks3.performance.now(); + const extractionTime = import_perf_hooks4.performance.now() - extractionStart; + const trapImportStart = import_perf_hooks4.performance.now(); for (const language of config.languages) { if (dbIsFinalized(config, language, logger)) { logger.info( @@ -153854,7 +153857,7 @@ async function finalizeDatabaseCreation(codeql, features, config, threadsFlag, m logger.endGroup(); } } - const trapImportTime = import_perf_hooks3.performance.now() - trapImportStart; + const trapImportTime = import_perf_hooks4.performance.now() - trapImportStart; return { scanned_language_extraction_duration_ms: Math.round(extractionTime), trap_import_duration_ms: Math.round(trapImportTime) @@ -156661,9 +156664,9 @@ async function run({ startedAt, logger }) { features, logger ); - const trapCacheUploadStartTime = import_perf_hooks4.performance.now(); + const trapCacheUploadStartTime = import_perf_hooks5.performance.now(); didUploadTrapCaches = await uploadTrapCaches(codeql, config, logger); - trapCacheUploadTime = import_perf_hooks4.performance.now() - trapCacheUploadStartTime; + trapCacheUploadTime = import_perf_hooks5.performance.now() - trapCacheUploadStartTime; trapCacheCleanupTelemetry = await cleanupTrapCaches( config, features, diff --git a/src/setup-codeql.test.ts b/src/setup-codeql.test.ts index f7caf575f..5e69ddaaa 100644 --- a/src/setup-codeql.test.ts +++ b/src/setup-codeql.test.ts @@ -1,6 +1,7 @@ import * as fs from "fs"; import * as os from "os"; import * as path from "path"; +import { performance } from "perf_hooks"; import * as github from "@actions/github"; import * as toolcache from "@actions/tool-cache"; @@ -1223,10 +1224,23 @@ for (const bundle of ["per-language", "combined", "fallback"] as const) { delete process.env[EnvVar.HAS_SET_UP_CODEQL]; const downloadSpy = sinon.spy(setupCodeql, "downloadCodeQL"); - const extractStub = stubDownloadAndExtract(); - if (bundle === "fallback") { - extractStub.onFirstCall().rejects(new HTTPError("Not Found", 404)); - } + let elapsedMs = 1000; + sinon.stub(performance, "now").callsFake(() => elapsedMs); + const extractStub = sinon + .stub(toolsDownload, "downloadAndExtract") + .callsFake(async (_url, _compressionMethod, dest) => { + if (bundle === "fallback" && extractStub.callCount === 1) { + elapsedMs += 700.2; + throw new HTTPError("Not Found", 404); + } + elapsedMs += 300.2; + fs.mkdirSync(dest, { recursive: true }); + return { + downloadDurationMs: 200, + extractionDurationMs: 100, + totalDurationMs: 300, + }; + }); const addDiagnostic = sinon.stub(diagnostics, "addNoLanguageDiagnostic"); const features = createFeatures([ Feature.PerLanguageBundles, @@ -1255,6 +1269,12 @@ for (const bundle of ["per-language", "combined", "fallback"] as const) { bundle === "combined" ? "combined" : "per-language", ); t.is(result.codeqlFolder, extractStub.lastCall.args[2]); + t.is( + result.toolsDownloadStatusReport?.totalDurationMs, + bundle === "fallback" ? 1000 : 300, + ); + t.is(result.toolsDownloadStatusReport?.downloadDurationMs, 200); + t.is(result.toolsDownloadStatusReport?.extractionDurationMs, 100); t.is(extractStub.callCount, bundle === "fallback" ? 2 : 1); t.is(downloadSpy.callCount, extractStub.callCount); t.is( diff --git a/src/setup-codeql.ts b/src/setup-codeql.ts index 85639ff93..27090ffdd 100644 --- a/src/setup-codeql.ts +++ b/src/setup-codeql.ts @@ -1,6 +1,7 @@ import * as fs from "fs"; import { OutgoingHttpHeaders } from "http"; import * as path from "path"; +import { performance } from "perf_hooks"; import * as core from "@actions/core"; import * as toolcache from "@actions/tool-cache"; @@ -1148,6 +1149,7 @@ export async function downloadCodeQLBundle( await tryDeleteToolcacheBundles(action); + const startTime = performance.now(); try { const result = await downloadCodeQL( source, @@ -1193,6 +1195,7 @@ export async function downloadCodeQLBundle( ...result, statusReport: { ...result.statusReport, + totalDurationMs: Math.round(performance.now() - startTime), perLanguageBundleFallback: true, }, };