From a63886bff563ff37363fa5140c38d3d121b5e1a6 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 10 Mar 2026 16:36:02 +0000 Subject: [PATCH] Refactor: Extract separate function for `uploadBundledDatabase` --- lib/analyze-action.js | 75 +++++++++++++++++++------------- src/database-upload.ts | 98 ++++++++++++++++++++++++++---------------- 2 files changed, 106 insertions(+), 67 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index da459df0f..c84eec3a5 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -110952,13 +110952,6 @@ async function cleanupAndUploadDatabases(repositoryNwo, codeql, config, apiDetai await withGroupAsync("Cleaning up databases", async () => { await codeql.databaseCleanupCluster(config, cleanupLevel); }); - const client = getApiClient(); - const uploadsUrl = new URL(parseGitHubUrl(apiDetails.url)); - uploadsUrl.hostname = `uploads.${uploadsUrl.hostname}`; - let uploadsBaseUrl = uploadsUrl.toString(); - if (uploadsBaseUrl.endsWith("/")) { - uploadsBaseUrl = uploadsBaseUrl.slice(0, -1); - } const reports = []; for (const language of config.languages) { let bundledDbSize = void 0; @@ -110973,30 +110966,15 @@ async function cleanupAndUploadDatabases(repositoryNwo, codeql, config, apiDetai const maxAttempts = 4; let uploadDurationMs; for (let attempt = 1; attempt <= maxAttempts; attempt++) { - const bundledDbReadStream = fs13.createReadStream(bundledDb); try { - const attemptStartTime = performance.now(); - await client.request( - `POST /repos/:owner/:repo/code-scanning/codeql/databases/:language?name=:name&commit_oid=:commit_oid`, - { - baseUrl: uploadsBaseUrl, - owner: repositoryNwo.owner, - repo: repositoryNwo.repo, - language, - name: `${language}-database`, - commit_oid: commitOid, - data: bundledDbReadStream, - headers: { - authorization: `token ${apiDetails.auth}`, - "Content-Type": "application/zip", - "Content-Length": bundledDbSize - }, - request: { - retries: 0 - } - } + uploadDurationMs = await uploadBundledDatabase( + repositoryNwo, + language, + commitOid, + bundledDb, + bundledDbSize, + apiDetails ); - uploadDurationMs = performance.now() - attemptStartTime; break; } catch (e) { const httpError = asHTTPError(e); @@ -111014,8 +110992,6 @@ async function cleanupAndUploadDatabases(repositoryNwo, codeql, config, apiDetai `Database upload attempt ${attempt} of ${maxAttempts} failed for ${language}: ${getErrorMessage(e)}. Retrying in ${backoffMs / 1e3}s...` ); await new Promise((resolve8) => setTimeout(resolve8, backoffMs)); - } finally { - bundledDbReadStream.close(); } } reports.push({ @@ -111038,6 +111014,43 @@ async function cleanupAndUploadDatabases(repositoryNwo, codeql, config, apiDetai } return reports; } +async function uploadBundledDatabase(repositoryNwo, language, commitOid, bundledDb, bundledDbSize, apiDetails) { + const client = getApiClient(); + const uploadsUrl = new URL(parseGitHubUrl(apiDetails.url)); + uploadsUrl.hostname = `uploads.${uploadsUrl.hostname}`; + let uploadsBaseUrl = uploadsUrl.toString(); + if (uploadsBaseUrl.endsWith("/")) { + uploadsBaseUrl = uploadsBaseUrl.slice(0, -1); + } + const bundledDbReadStream = fs13.createReadStream(bundledDb); + try { + const startTime = performance.now(); + await client.request( + `POST /repos/:owner/:repo/code-scanning/codeql/databases/:language?name=:name&commit_oid=:commit_oid`, + { + baseUrl: uploadsBaseUrl, + owner: repositoryNwo.owner, + repo: repositoryNwo.repo, + language, + name: `${language}-database`, + commit_oid: commitOid, + data: bundledDbReadStream, + headers: { + authorization: `token ${apiDetails.auth}`, + "Content-Type": "application/zip", + "Content-Length": bundledDbSize + }, + // Disable `octokit/plugin-retry.js`, since the request body is a ReadStream which can only be consumed once. + request: { + retries: 0 + } + } + ); + return performance.now() - startTime; + } finally { + bundledDbReadStream.close(); + } +} // src/status-report.ts var os4 = __toESM(require("os")); diff --git a/src/database-upload.ts b/src/database-upload.ts index 8d7d49551..c7db68fc3 100644 --- a/src/database-upload.ts +++ b/src/database-upload.ts @@ -85,18 +85,6 @@ export async function cleanupAndUploadDatabases( await codeql.databaseCleanupCluster(config, cleanupLevel); }); - const client = getApiClient(); - - const uploadsUrl = new URL(parseGitHubUrl(apiDetails.url)); - uploadsUrl.hostname = `uploads.${uploadsUrl.hostname}`; - - // Octokit expects the baseUrl to not have a trailing slash, - // but it is included by default in a URL. - let uploadsBaseUrl = uploadsUrl.toString(); - if (uploadsBaseUrl.endsWith("/")) { - uploadsBaseUrl = uploadsBaseUrl.slice(0, -1); - } - const reports: DatabaseUploadResult[] = []; for (const language of config.languages) { let bundledDbSize: number | undefined = undefined; @@ -118,30 +106,15 @@ export async function cleanupAndUploadDatabases( const maxAttempts = 4; // 1 initial attempt + 3 retries, identical to the default retry behavior of Octokit let uploadDurationMs: number | undefined; for (let attempt = 1; attempt <= maxAttempts; attempt++) { - const bundledDbReadStream = fs.createReadStream(bundledDb); try { - const attemptStartTime = performance.now(); - await client.request( - `POST /repos/:owner/:repo/code-scanning/codeql/databases/:language?name=:name&commit_oid=:commit_oid`, - { - baseUrl: uploadsBaseUrl, - owner: repositoryNwo.owner, - repo: repositoryNwo.repo, - language, - name: `${language}-database`, - commit_oid: commitOid, - data: bundledDbReadStream, - headers: { - authorization: `token ${apiDetails.auth}`, - "Content-Type": "application/zip", - "Content-Length": bundledDbSize, - }, - request: { - retries: 0, - }, - }, + uploadDurationMs = await uploadBundledDatabase( + repositoryNwo, + language, + commitOid, + bundledDb, + bundledDbSize, + apiDetails, ); - uploadDurationMs = performance.now() - attemptStartTime; break; } catch (e) { const httpError = asHTTPError(e); @@ -160,8 +133,6 @@ export async function cleanupAndUploadDatabases( `Database upload attempt ${attempt} of ${maxAttempts} failed for ${language}: ${util.getErrorMessage(e)}. Retrying in ${backoffMs / 1000}s...`, ); await new Promise((resolve) => setTimeout(resolve, backoffMs)); - } finally { - bundledDbReadStream.close(); } } reports.push({ @@ -187,3 +158,58 @@ export async function cleanupAndUploadDatabases( } return reports; } + +/** + * Uploads a bundled database to the GitHub API. + * + * @returns the duration of the upload in milliseconds + */ +async function uploadBundledDatabase( + repositoryNwo: RepositoryNwo, + language: string, + commitOid: string, + bundledDb: string, + bundledDbSize: number, + apiDetails: GitHubApiDetails, +): Promise { + const client = getApiClient(); + + const uploadsUrl = new URL(parseGitHubUrl(apiDetails.url)); + uploadsUrl.hostname = `uploads.${uploadsUrl.hostname}`; + + // Octokit expects the baseUrl to not have a trailing slash, + // but it is included by default in a URL. + let uploadsBaseUrl = uploadsUrl.toString(); + if (uploadsBaseUrl.endsWith("/")) { + uploadsBaseUrl = uploadsBaseUrl.slice(0, -1); + } + + const bundledDbReadStream = fs.createReadStream(bundledDb); + try { + const startTime = performance.now(); + await client.request( + `POST /repos/:owner/:repo/code-scanning/codeql/databases/:language?name=:name&commit_oid=:commit_oid`, + { + baseUrl: uploadsBaseUrl, + owner: repositoryNwo.owner, + repo: repositoryNwo.repo, + language, + name: `${language}-database`, + commit_oid: commitOid, + data: bundledDbReadStream, + headers: { + authorization: `token ${apiDetails.auth}`, + "Content-Type": "application/zip", + "Content-Length": bundledDbSize, + }, + // Disable `octokit/plugin-retry.js`, since the request body is a ReadStream which can only be consumed once. + request: { + retries: 0, + }, + }, + ); + return performance.now() - startTime; + } finally { + bundledDbReadStream.close(); + } +}