Skip to content

Commit

Permalink
Merge branch 'master' into report-upload-failures
Browse files Browse the repository at this point in the history
  • Loading branch information
Joshua Hale committed May 1, 2020
2 parents 26e955c + 5bceb2b commit d68eb11
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 41 deletions.
70 changes: 49 additions & 21 deletions lib/upload-lib.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

79 changes: 59 additions & 20 deletions src/upload-lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,63 @@ export function combineSarifFiles(sarifFiles: string[]): string {
return JSON.stringify(combinedSarif);
}

// Upload the given payload.
// If the request fails then this will retry a small number of times.
async function uploadPayload(payload): Promise<boolean> {
core.info('Uploading results');

const githubToken = core.getInput('token');
const ph: auth.BearerCredentialHandler = new auth.BearerCredentialHandler(githubToken);
const client = new http.HttpClient('Code Scanning : Upload SARIF', [ph]);
const url = 'https://api.github.com/repos/' + process.env['GITHUB_REPOSITORY'] + '/code-scanning/analysis';

// Make up to 4 attempts to upload, and sleep for these
// number of seconds between each attempt.
// We don't want to backoff too much to avoid wasting action
// minutes, but just waiting a little bit could maybe help.
const backoffPeriods = [1, 5, 15];

for (let attempt = 0; attempt <= backoffPeriods.length; attempt++) {

const res: http.HttpClientResponse = await client.put(url, payload);
core.debug('response status: ' + res.message.statusCode);

const statusCode = res.message.statusCode;
if (statusCode === 202) {
core.info("Successfully uploaded results");
return true;
}

const requestID = res.message.headers["x-github-request-id"];

// On any other status code that's not 5xx mark the upload as failed
if (!statusCode || statusCode < 500 || statusCode >= 600) {
core.setFailed('Upload failed (' + requestID + '): (' + statusCode + ') ' + await res.readBody());
return false;
}

// On a 5xx status code we may retry the request
if (attempt < backoffPeriods.length) {
// Log the failure as a warning but don't mark the action as failed yet
core.warning('Upload attempt (' + (attempt + 1) + ' of ' + (backoffPeriods.length + 1) +
') failed (' + requestID + '). Retrying in ' + backoffPeriods[attempt] +
' seconds: (' + statusCode + ') ' + await res.readBody());
// Sleep for the backoff period
await new Promise(r => setTimeout(r, backoffPeriods[attempt] * 1000));
continue;

} else {
// If the upload fails with 5xx then we assume it is a temporary problem
// and not an error that the user has caused or can fix.
// We avoid marking the job as failed to avoid breaking CI workflows.
core.error('Upload failed (' + requestID + '): (' + statusCode + ') ' + await res.readBody());
return false;
}
}

return false;
}

// Uploads a single sarif file or a directory of sarif files
// depending on what the path happens to refer to.
// Returns true iff the upload occurred and succeeded
Expand Down Expand Up @@ -115,26 +172,8 @@ async function uploadFiles(sarifFiles: string[]): Promise<boolean> {
"tool_names": toolNames,
});

core.info('Uploading results');
const githubToken = core.getInput('token');
const ph: auth.BearerCredentialHandler = new auth.BearerCredentialHandler(githubToken);
const client = new http.HttpClient('Code Scanning : Upload SARIF', [ph]);
const url = 'https://api.github.com/repos/' + process.env['GITHUB_REPOSITORY'] + '/code-scanning/analysis';
const res: http.HttpClientResponse = await client.put(url, payload);
const requestID = res.message.headers["x-github-request-id"];

core.debug('response status: ' + res.message.statusCode);
if (res.message.statusCode === 500) {
// If the upload fails with 500 then we assume it is a temporary problem
// with turbo-scan and not an error that the user has caused or can fix.
// We avoid marking the job as failed to avoid breaking CI workflows.
core.error('Upload failed (' + requestID + '): ' + await res.readBody());
} else if (res.message.statusCode !== 202) {
core.setFailed('Upload failed (' + requestID + '): ' + await res.readBody());
} else {
core.info("Successfully uploaded results");
succeeded = true;
}
// Make the upload
succeeded = await uploadPayload(payload);

// Mark that we have made an upload
fs.writeFileSync(sentinelFile, '');
Expand Down

0 comments on commit d68eb11

Please sign in to comment.