mirror of
https://github.com/github/codeql-action.git
synced 2026-04-26 16:58:47 +00:00
Add StartProxyError for status-report-safe errors, and use for proxy download
This commit is contained in:
Generated
+31
-13
@@ -115932,7 +115932,7 @@ var require_cache5 = __commonJS({
|
||||
var import_child_process = require("child_process");
|
||||
var path = __toESM(require("path"));
|
||||
var core11 = __toESM(require_core());
|
||||
var toolcache = __toESM(require_tool_cache());
|
||||
var toolcache2 = __toESM(require_tool_cache());
|
||||
var import_node_forge = __toESM(require_lib2());
|
||||
|
||||
// src/actions-util.ts
|
||||
@@ -118929,6 +118929,7 @@ function getActionsLogger() {
|
||||
|
||||
// src/start-proxy.ts
|
||||
var core10 = __toESM(require_core());
|
||||
var toolcache = __toESM(require_tool_cache());
|
||||
|
||||
// src/artifact-scanner.ts
|
||||
var exec = __toESM(require_exec());
|
||||
@@ -119573,6 +119574,11 @@ async function sendUnhandledErrorStatusReport(actionName, actionStartedAt, error
|
||||
}
|
||||
|
||||
// src/start-proxy.ts
|
||||
var StartProxyError = class extends Error {
|
||||
constructor(errorType) {
|
||||
super(errorType);
|
||||
}
|
||||
};
|
||||
async function sendSuccessStatusReport(startedAt, config, registry_types, logger) {
|
||||
const statusReportBase = await createStatusReportBase(
|
||||
"start-proxy" /* StartProxy */,
|
||||
@@ -119590,9 +119596,16 @@ async function sendSuccessStatusReport(startedAt, config, registry_types, logger
|
||||
await sendStatusReport(statusReport);
|
||||
}
|
||||
}
|
||||
function getSafeErrorMessage(error3) {
|
||||
if (error3 instanceof StartProxyError) {
|
||||
return error3.message;
|
||||
}
|
||||
return `Error from start-proxy Action omitted (${typeof error3}).`;
|
||||
}
|
||||
async function sendFailedStatusReport(logger, startedAt, language, unwrappedError) {
|
||||
const error3 = wrapError(unwrappedError);
|
||||
core10.setFailed(`start-proxy action failed: ${error3.message}`);
|
||||
const statusReportMessage = getSafeErrorMessage(error3);
|
||||
const errorStatusReportBase = await createStatusReportBase(
|
||||
"start-proxy" /* StartProxy */,
|
||||
getActionsStatus(error3),
|
||||
@@ -119602,7 +119615,7 @@ async function sendFailedStatusReport(logger, startedAt, language, unwrappedErro
|
||||
},
|
||||
await checkDiskUsage(logger),
|
||||
logger,
|
||||
"Error from start-proxy Action omitted"
|
||||
statusReportMessage
|
||||
);
|
||||
if (errorStatusReportBase !== void 0) {
|
||||
await sendStatusReport(errorStatusReportBase);
|
||||
@@ -119761,6 +119774,18 @@ async function getDownloadUrl(logger) {
|
||||
function credentialToStr(c) {
|
||||
return `Type: ${c.type}; Host: ${c.host}; Url: ${c.url} Username: ${c.username}; Password: ${c.password !== void 0}; Token: ${c.token !== void 0}`;
|
||||
}
|
||||
async function downloadProxy(logger, url, authorization) {
|
||||
try {
|
||||
return toolcache.downloadTool(url, void 0, authorization, {
|
||||
accept: "application/octet-stream"
|
||||
});
|
||||
} catch (error3) {
|
||||
logger.error(
|
||||
`Failed to download proxy archive from ${url}: ${getErrorMessage(error3)}`
|
||||
);
|
||||
throw new StartProxyError("Failed to download proxy archive." /* DownloadFailed */);
|
||||
}
|
||||
}
|
||||
|
||||
// src/start-proxy-action.ts
|
||||
var KEY_SIZE = 2048;
|
||||
@@ -119915,7 +119940,7 @@ async function startProxy(binPath, config, logFilePath, logger) {
|
||||
async function getProxyBinaryPath(logger) {
|
||||
const proxyFileName = process.platform === "win32" ? `${UPDATEJOB_PROXY}.exe` : UPDATEJOB_PROXY;
|
||||
const proxyInfo = await getDownloadUrl(logger);
|
||||
let proxyBin = toolcache.find(proxyFileName, proxyInfo.version);
|
||||
let proxyBin = toolcache2.find(proxyFileName, proxyInfo.version);
|
||||
if (!proxyBin) {
|
||||
const apiDetails = getApiDetails();
|
||||
const authorization = getAuthorizationHeaderFor(
|
||||
@@ -119923,16 +119948,9 @@ async function getProxyBinaryPath(logger) {
|
||||
apiDetails,
|
||||
proxyInfo.url
|
||||
);
|
||||
const temp = await toolcache.downloadTool(
|
||||
proxyInfo.url,
|
||||
void 0,
|
||||
authorization,
|
||||
{
|
||||
accept: "application/octet-stream"
|
||||
}
|
||||
);
|
||||
const extracted = await toolcache.extractTar(temp);
|
||||
proxyBin = await toolcache.cacheDir(
|
||||
const temp = await downloadProxy(logger, proxyInfo.url, authorization);
|
||||
const extracted = await toolcache2.extractTar(temp);
|
||||
proxyBin = await toolcache2.cacheDir(
|
||||
extracted,
|
||||
proxyFileName,
|
||||
proxyInfo.version
|
||||
|
||||
@@ -12,6 +12,7 @@ import { getActionsLogger, Logger } from "./logging";
|
||||
import {
|
||||
Credential,
|
||||
credentialToStr,
|
||||
downloadProxy,
|
||||
getCredentials,
|
||||
getDownloadUrl,
|
||||
parseLanguage,
|
||||
@@ -238,14 +239,7 @@ async function getProxyBinaryPath(logger: Logger): Promise<string> {
|
||||
apiDetails,
|
||||
proxyInfo.url,
|
||||
);
|
||||
const temp = await toolcache.downloadTool(
|
||||
proxyInfo.url,
|
||||
undefined,
|
||||
authorization,
|
||||
{
|
||||
accept: "application/octet-stream",
|
||||
},
|
||||
);
|
||||
const temp = await downloadProxy(logger, proxyInfo.url, authorization);
|
||||
const extracted = await toolcache.extractTar(temp);
|
||||
proxyBin = await toolcache.cacheDir(
|
||||
extracted,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import * as toolcache from "@actions/tool-cache";
|
||||
import test from "ava";
|
||||
import sinon from "sinon";
|
||||
|
||||
@@ -318,3 +319,47 @@ test("credentialToStr - hides passwords/tokens", (t) => {
|
||||
.includes(secret),
|
||||
);
|
||||
});
|
||||
|
||||
test("getSafeErrorMessage - returns actual message for `StartProxyError`", (t) => {
|
||||
const error = new startProxyExports.StartProxyError(
|
||||
startProxyExports.StartProxyErrorType.DownloadFailed,
|
||||
);
|
||||
t.is(startProxyExports.getSafeErrorMessage(error), error.message);
|
||||
});
|
||||
|
||||
test("getSafeErrorMessage - does not return message for arbitrary errors", (t) => {
|
||||
const error = new Error(startProxyExports.StartProxyErrorType.DownloadFailed);
|
||||
|
||||
const message = startProxyExports.getSafeErrorMessage(error);
|
||||
|
||||
t.not(message, error.message);
|
||||
t.assert(message.startsWith("Error from start-proxy Action omitted"));
|
||||
t.assert(message.includes(typeof error));
|
||||
});
|
||||
|
||||
test("downloadProxy - returns file path on success", async (t) => {
|
||||
const loggedMessages = [];
|
||||
const logger = getRecordingLogger(loggedMessages);
|
||||
const testPath = "/some/path";
|
||||
sinon.stub(toolcache, "downloadTool").resolves(testPath);
|
||||
|
||||
const result = await startProxyExports.downloadProxy(
|
||||
logger,
|
||||
"url",
|
||||
undefined,
|
||||
);
|
||||
t.is(result, testPath);
|
||||
});
|
||||
|
||||
test("downloadProxy - wraps errors on failure", async (t) => {
|
||||
const loggedMessages = [];
|
||||
const logger = getRecordingLogger(loggedMessages);
|
||||
sinon.stub(toolcache, "downloadTool").throws();
|
||||
|
||||
await t.throwsAsync(
|
||||
startProxyExports.downloadProxy(logger, "url", undefined),
|
||||
{
|
||||
instanceOf: startProxyExports.StartProxyError,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
+66
-1
@@ -1,4 +1,5 @@
|
||||
import * as core from "@actions/core";
|
||||
import * as toolcache from "@actions/tool-cache";
|
||||
|
||||
import { getApiClient } from "./api-client";
|
||||
import * as artifactScanner from "./artifact-scanner";
|
||||
@@ -16,6 +17,26 @@ import {
|
||||
import * as util from "./util";
|
||||
import { ConfigurationError, getErrorMessage, isDefined } from "./util";
|
||||
|
||||
/**
|
||||
* Enumerates specific error types, along with suitable error messages, for errors
|
||||
* that we want to track in status reports.
|
||||
*/
|
||||
export enum StartProxyErrorType {
|
||||
DownloadFailed = "Failed to download proxy archive.",
|
||||
}
|
||||
|
||||
/**
|
||||
* We want to avoid accidentally leaking secrets that may be contained in exception
|
||||
* messages in the `start-proxy` action. Consequently, we don't report the messages
|
||||
* of arbitrary exceptions. This type of error ensures that the message is one from
|
||||
* `StartProxyErrorType` and therefore safe to include in a status report.
|
||||
*/
|
||||
export class StartProxyError extends Error {
|
||||
constructor(errorType: StartProxyErrorType) {
|
||||
super(errorType);
|
||||
}
|
||||
}
|
||||
|
||||
interface StartProxyStatus extends StatusReportBase {
|
||||
// A comma-separated list of registry types which are configured for CodeQL.
|
||||
// This only includes registry types we support, not all that are configured.
|
||||
@@ -53,6 +74,23 @@ export async function sendSuccessStatusReport(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an error message for `error` that can safely be reported in a status report,
|
||||
* i.e. that does not contain sensitive information.
|
||||
*
|
||||
* @param error The error for which to get an error message.
|
||||
*/
|
||||
export function getSafeErrorMessage(error: Error): string {
|
||||
// If the error is a `StartProxyError`, the constructor ensures that the
|
||||
// message comes from `StartProxyErrorType`.
|
||||
if (error instanceof StartProxyError) {
|
||||
return error.message;
|
||||
}
|
||||
|
||||
// Otherwise, omit the actual error message.
|
||||
return `Error from start-proxy Action omitted (${typeof error}).`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a status report for the `start-proxy` action indicating a failure.
|
||||
*
|
||||
@@ -70,6 +108,8 @@ export async function sendFailedStatusReport(
|
||||
const error = util.wrapError(unwrappedError);
|
||||
core.setFailed(`start-proxy action failed: ${error.message}`);
|
||||
|
||||
const statusReportMessage = getSafeErrorMessage(error);
|
||||
|
||||
// We skip sending the error message and stack trace here to avoid the possibility
|
||||
// of leaking any sensitive information into the telemetry.
|
||||
const errorStatusReportBase = await createStatusReportBase(
|
||||
@@ -81,7 +121,7 @@ export async function sendFailedStatusReport(
|
||||
},
|
||||
await util.checkDiskUsage(logger),
|
||||
logger,
|
||||
"Error from start-proxy Action omitted",
|
||||
statusReportMessage,
|
||||
);
|
||||
if (errorStatusReportBase !== undefined) {
|
||||
await sendStatusReport(errorStatusReportBase);
|
||||
@@ -369,3 +409,28 @@ export function credentialToStr(c: Credential): string {
|
||||
c.username
|
||||
}; Password: ${c.password !== undefined}; Token: ${c.token !== undefined}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to download a file from `url` into the toolcache.
|
||||
*
|
||||
* @param logger THe logger to use.
|
||||
* @param url The URL to download the proxy binary from.
|
||||
* @param authorization The authorization information to use.
|
||||
* @returns If successful, the path to the downloaded file.
|
||||
*/
|
||||
export async function downloadProxy(
|
||||
logger: Logger,
|
||||
url: string,
|
||||
authorization: string | undefined,
|
||||
) {
|
||||
try {
|
||||
return toolcache.downloadTool(url, undefined, authorization, {
|
||||
accept: "application/octet-stream",
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(
|
||||
`Failed to download proxy archive from ${url}: ${getErrorMessage(error)}`,
|
||||
);
|
||||
throw new StartProxyError(StartProxyErrorType.DownloadFailed);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user