11import * as core from "@actions/core" ;
2+ import * as toolcache from "@actions/tool-cache" ;
23
34import { getApiClient } from "./api-client" ;
45import * as artifactScanner from "./artifact-scanner" ;
@@ -16,6 +17,26 @@ import {
1617import * as util from "./util" ;
1718import { ConfigurationError , getErrorMessage , isDefined } from "./util" ;
1819
20+ /**
21+ * Enumerates specific error types, along with suitable error messages, for errors
22+ * that we want to track in status reports.
23+ */
24+ export enum StartProxyErrorType {
25+ DownloadFailed = "Failed to download proxy archive." ,
26+ }
27+
28+ /**
29+ * We want to avoid accidentally leaking secrets that may be contained in exception
30+ * messages in the `start-proxy` action. Consequently, we don't report the messages
31+ * of arbitrary exceptions. This type of error ensures that the message is one from
32+ * `StartProxyErrorType` and therefore safe to include in a status report.
33+ */
34+ export class StartProxyError extends Error {
35+ constructor ( errorType : StartProxyErrorType ) {
36+ super ( errorType ) ;
37+ }
38+ }
39+
1940interface StartProxyStatus extends StatusReportBase {
2041 // A comma-separated list of registry types which are configured for CodeQL.
2142 // This only includes registry types we support, not all that are configured.
@@ -53,6 +74,23 @@ export async function sendSuccessStatusReport(
5374 }
5475}
5576
77+ /**
78+ * Returns an error message for `error` that can safely be reported in a status report,
79+ * i.e. that does not contain sensitive information.
80+ *
81+ * @param error The error for which to get an error message.
82+ */
83+ export function getSafeErrorMessage ( error : Error ) : string {
84+ // If the error is a `StartProxyError`, the constructor ensures that the
85+ // message comes from `StartProxyErrorType`.
86+ if ( error instanceof StartProxyError ) {
87+ return error . message ;
88+ }
89+
90+ // Otherwise, omit the actual error message.
91+ return `Error from start-proxy Action omitted (${ typeof error } ).` ;
92+ }
93+
5694/**
5795 * Sends a status report for the `start-proxy` action indicating a failure.
5896 *
@@ -70,6 +108,8 @@ export async function sendFailedStatusReport(
70108 const error = util . wrapError ( unwrappedError ) ;
71109 core . setFailed ( `start-proxy action failed: ${ error . message } ` ) ;
72110
111+ const statusReportMessage = getSafeErrorMessage ( error ) ;
112+
73113 // We skip sending the error message and stack trace here to avoid the possibility
74114 // of leaking any sensitive information into the telemetry.
75115 const errorStatusReportBase = await createStatusReportBase (
@@ -81,7 +121,7 @@ export async function sendFailedStatusReport(
81121 } ,
82122 await util . checkDiskUsage ( logger ) ,
83123 logger ,
84- "Error from start-proxy Action omitted" ,
124+ statusReportMessage ,
85125 ) ;
86126 if ( errorStatusReportBase !== undefined ) {
87127 await sendStatusReport ( errorStatusReportBase ) ;
@@ -369,3 +409,28 @@ export function credentialToStr(c: Credential): string {
369409 c . username
370410 } ; Password: ${ c . password !== undefined } ; Token: ${ c . token !== undefined } `;
371411}
412+
413+ /**
414+ * Attempts to download a file from `url` into the toolcache.
415+ *
416+ * @param logger THe logger to use.
417+ * @param url The URL to download the proxy binary from.
418+ * @param authorization The authorization information to use.
419+ * @returns If successful, the path to the downloaded file.
420+ */
421+ export async function downloadProxy (
422+ logger : Logger ,
423+ url : string ,
424+ authorization : string | undefined ,
425+ ) {
426+ try {
427+ return toolcache . downloadTool ( url , undefined , authorization , {
428+ accept : "application/octet-stream" ,
429+ } ) ;
430+ } catch ( error ) {
431+ logger . error (
432+ `Failed to download proxy archive from ${ url } : ${ getErrorMessage ( error ) } ` ,
433+ ) ;
434+ throw new StartProxyError ( StartProxyErrorType . DownloadFailed ) ;
435+ }
436+ }
0 commit comments