mirror of
https://github.com/github/codeql-action.git
synced 2026-08-05 13:02:04 -05:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e0299c3c04 | |||
| aad14bf2cb | |||
| a08742f199 | |||
| 151d531bd0 | |||
| 504c8cfc6f | |||
| a0d4330434 | |||
| bb9ed79f3d | |||
| 17548064f9 | |||
| ef507971e7 | |||
| 96d02d50f7 | |||
| 0fdc2c71e4 | |||
| 28944b580b | |||
| 50a2815790 | |||
| 464ce1b43a | |||
| 74c48f71fa |
@@ -26,10 +26,6 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
CodeQL-Build:
|
CodeQL-Build:
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
|
|
||||||
# CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
|
# CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
|||||||
Generated
+23
@@ -0,0 +1,23 @@
|
|||||||
|
"use strict";
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||||
|
result["default"] = mod;
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
const core = __importStar(require("@actions/core"));
|
||||||
|
const octokit = __importStar(require("@octokit/rest"));
|
||||||
|
const console_log_level_1 = __importDefault(require("console-log-level"));
|
||||||
|
const githubAPIURL = process.env["GITHUB_API_URL"] || "https://api.github.com";
|
||||||
|
exports.client = new octokit.Octokit({
|
||||||
|
auth: core.getInput("token"),
|
||||||
|
baseUrl: githubAPIURL,
|
||||||
|
userAgent: "CodeQL Action",
|
||||||
|
log: console_log_level_1.default({ level: "debug" })
|
||||||
|
});
|
||||||
|
//# sourceMappingURL=api-client.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,oDAAsC;AACtC,uDAAyC;AACzC,0EAAgD;AAEhD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,wBAAwB,CAAC;AAClE,QAAA,MAAM,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;IACxC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;IAC5B,OAAO,EAAE,YAAY;IACrB,SAAS,EAAE,eAAe;IAC1B,GAAG,EAAE,2BAAe,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;CACzC,CAAC,CAAC"}
|
||||||
Generated
+13
-13
@@ -11,13 +11,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const core = __importStar(require("@actions/core"));
|
const core = __importStar(require("@actions/core"));
|
||||||
const http = __importStar(require("@actions/http-client"));
|
|
||||||
const auth = __importStar(require("@actions/http-client/auth"));
|
|
||||||
const file_url_1 = __importDefault(require("file-url"));
|
const file_url_1 = __importDefault(require("file-url"));
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const jsonschema = __importStar(require("jsonschema"));
|
const jsonschema = __importStar(require("jsonschema"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
const zlib_1 = __importDefault(require("zlib"));
|
const zlib_1 = __importDefault(require("zlib"));
|
||||||
|
const api = __importStar(require("./api-client"));
|
||||||
const fingerprints = __importStar(require("./fingerprints"));
|
const fingerprints = __importStar(require("./fingerprints"));
|
||||||
const sharedEnv = __importStar(require("./shared-environment"));
|
const sharedEnv = __importStar(require("./shared-environment"));
|
||||||
const util = __importStar(require("./util"));
|
const util = __importStar(require("./util"));
|
||||||
@@ -51,27 +50,28 @@ async function uploadPayload(payload) {
|
|||||||
if (testMode) {
|
if (testMode) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const githubToken = core.getInput('token');
|
const [owner, repo] = util.getRequiredEnvParam("GITHUB_REPOSITORY").split("/");
|
||||||
const ph = 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
|
// Make up to 4 attempts to upload, and sleep for these
|
||||||
// number of seconds between each attempt.
|
// number of seconds between each attempt.
|
||||||
// We don't want to backoff too much to avoid wasting action
|
// We don't want to backoff too much to avoid wasting action
|
||||||
// minutes, but just waiting a little bit could maybe help.
|
// minutes, but just waiting a little bit could maybe help.
|
||||||
const backoffPeriods = [1, 5, 15];
|
const backoffPeriods = [1, 5, 15];
|
||||||
for (let attempt = 0; attempt <= backoffPeriods.length; attempt++) {
|
for (let attempt = 0; attempt <= backoffPeriods.length; attempt++) {
|
||||||
const res = await client.put(url, payload);
|
const response = await api.client.request("PUT /repos/:owner/:repo/code-scanning/analysis", ({
|
||||||
core.debug('response status: ' + res.message.statusCode);
|
owner: owner,
|
||||||
const statusCode = res.message.statusCode;
|
repo: repo,
|
||||||
|
data: payload,
|
||||||
|
}));
|
||||||
|
core.debug('response status: ' + response.status);
|
||||||
|
const statusCode = response.status;
|
||||||
if (statusCode === 202) {
|
if (statusCode === 202) {
|
||||||
core.info("Successfully uploaded results");
|
core.info("Successfully uploaded results");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const requestID = res.message.headers["x-github-request-id"];
|
const requestID = response.headers["x-github-request-id"];
|
||||||
// On any other status code that's not 5xx mark the upload as failed
|
// On any other status code that's not 5xx mark the upload as failed
|
||||||
if (!statusCode || statusCode < 500 || statusCode >= 600) {
|
if (!statusCode || statusCode < 500 || statusCode >= 600) {
|
||||||
core.setFailed('Upload failed (' + requestID + '): (' + statusCode + ') ' + await res.readBody());
|
core.setFailed('Upload failed (' + requestID + '): (' + statusCode + ') ' + JSON.stringify(response.data));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// On a 5xx status code we may retry the request
|
// On a 5xx status code we may retry the request
|
||||||
@@ -79,7 +79,7 @@ async function uploadPayload(payload) {
|
|||||||
// Log the failure as a warning but don't mark the action as failed yet
|
// 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) +
|
core.warning('Upload attempt (' + (attempt + 1) + ' of ' + (backoffPeriods.length + 1) +
|
||||||
') failed (' + requestID + '). Retrying in ' + backoffPeriods[attempt] +
|
') failed (' + requestID + '). Retrying in ' + backoffPeriods[attempt] +
|
||||||
' seconds: (' + statusCode + ') ' + await res.readBody());
|
' seconds: (' + statusCode + ') ' + JSON.stringify(response.data));
|
||||||
// Sleep for the backoff period
|
// Sleep for the backoff period
|
||||||
await new Promise(r => setTimeout(r, backoffPeriods[attempt] * 1000));
|
await new Promise(r => setTimeout(r, backoffPeriods[attempt] * 1000));
|
||||||
continue;
|
continue;
|
||||||
@@ -88,7 +88,7 @@ async function uploadPayload(payload) {
|
|||||||
// If the upload fails with 5xx then we assume it is a temporary problem
|
// 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.
|
// and not an error that the user has caused or can fix.
|
||||||
// We avoid marking the job as failed to avoid breaking CI workflows.
|
// We avoid marking the job as failed to avoid breaking CI workflows.
|
||||||
core.error('Upload failed (' + requestID + '): (' + statusCode + ') ' + await res.readBody());
|
core.error('Upload failed (' + requestID + '): (' + statusCode + ') ' + JSON.stringify(response.data));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Generated
+38
-43
@@ -6,19 +6,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
result["default"] = mod;
|
result["default"] = mod;
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const core = __importStar(require("@actions/core"));
|
const core = __importStar(require("@actions/core"));
|
||||||
const exec = __importStar(require("@actions/exec"));
|
const exec = __importStar(require("@actions/exec"));
|
||||||
const http = __importStar(require("@actions/http-client"));
|
|
||||||
const auth = __importStar(require("@actions/http-client/auth"));
|
|
||||||
const octokit = __importStar(require("@octokit/rest"));
|
|
||||||
const console_log_level_1 = __importDefault(require("console-log-level"));
|
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const os = __importStar(require("os"));
|
const os = __importStar(require("os"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
|
const api = __importStar(require("./api-client"));
|
||||||
const sharedEnv = __importStar(require("./shared-environment"));
|
const sharedEnv = __importStar(require("./shared-environment"));
|
||||||
/**
|
/**
|
||||||
* Should the current action be aborted?
|
* Should the current action be aborted?
|
||||||
@@ -47,7 +41,7 @@ exports.should_abort = should_abort;
|
|||||||
*/
|
*/
|
||||||
function getRequiredEnvParam(paramName) {
|
function getRequiredEnvParam(paramName) {
|
||||||
const value = process.env[paramName];
|
const value = process.env[paramName];
|
||||||
if (value === undefined) {
|
if (value === undefined || value.length === 0) {
|
||||||
throw new Error(paramName + ' environment variable must be set');
|
throw new Error(paramName + ' environment variable must be set');
|
||||||
}
|
}
|
||||||
core.debug(paramName + '=' + value);
|
core.debug(paramName + '=' + value);
|
||||||
@@ -75,12 +69,7 @@ async function getLanguagesInRepo() {
|
|||||||
let owner = repo_nwo[0];
|
let owner = repo_nwo[0];
|
||||||
let repo = repo_nwo[1];
|
let repo = repo_nwo[1];
|
||||||
core.debug(`GitHub repo ${owner} ${repo}`);
|
core.debug(`GitHub repo ${owner} ${repo}`);
|
||||||
let ok = new octokit.Octokit({
|
const response = await api.client.request("GET /repos/:owner/:repo/languages", ({
|
||||||
auth: core.getInput('token'),
|
|
||||||
userAgent: "CodeQL Action",
|
|
||||||
log: console_log_level_1.default({ level: "debug" })
|
|
||||||
});
|
|
||||||
const response = await ok.request("GET /repos/:owner/:repo/languages", ({
|
|
||||||
owner,
|
owner,
|
||||||
repo
|
repo
|
||||||
}));
|
}));
|
||||||
@@ -140,15 +129,28 @@ exports.getLanguages = getLanguages;
|
|||||||
* Gets the SHA of the commit that is currently checked out.
|
* Gets the SHA of the commit that is currently checked out.
|
||||||
*/
|
*/
|
||||||
async function getCommitOid() {
|
async function getCommitOid() {
|
||||||
let commitOid = '';
|
// Try to use git to get the current commit SHA. If that fails then
|
||||||
await exec.exec('git', ['rev-parse', 'HEAD'], {
|
// log but otherwise silently fall back to using the SHA from the environment.
|
||||||
silent: true,
|
// The only time these two values will differ is during analysis of a PR when
|
||||||
listeners: {
|
// the workflow has changed the current commit to the head commit instead of
|
||||||
stdout: (data) => { commitOid += data.toString(); },
|
// the merge commit, which must mean that git is available.
|
||||||
stderr: (data) => { process.stderr.write(data); }
|
// Even if this does go wrong, it's not a huge problem for the alerts to
|
||||||
}
|
// reported on the merge commit.
|
||||||
});
|
try {
|
||||||
return commitOid.trim();
|
let commitOid = '';
|
||||||
|
await exec.exec('git', ['rev-parse', 'HEAD'], {
|
||||||
|
silent: true,
|
||||||
|
listeners: {
|
||||||
|
stdout: (data) => { commitOid += data.toString(); },
|
||||||
|
stderr: (data) => { process.stderr.write(data); }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return commitOid.trim();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
core.info("Failed to call git to get current commit. Continuing with data from environment: " + e);
|
||||||
|
return getRequiredEnvParam('GITHUB_SHA');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exports.getCommitOid = getCommitOid;
|
exports.getCommitOid = getCommitOid;
|
||||||
/**
|
/**
|
||||||
@@ -158,19 +160,14 @@ async function getWorkflowPath() {
|
|||||||
const repo_nwo = getRequiredEnvParam('GITHUB_REPOSITORY').split("/");
|
const repo_nwo = getRequiredEnvParam('GITHUB_REPOSITORY').split("/");
|
||||||
const owner = repo_nwo[0];
|
const owner = repo_nwo[0];
|
||||||
const repo = repo_nwo[1];
|
const repo = repo_nwo[1];
|
||||||
const run_id = getRequiredEnvParam('GITHUB_RUN_ID');
|
const run_id = Number(getRequiredEnvParam('GITHUB_RUN_ID'));
|
||||||
const ok = new octokit.Octokit({
|
const runsResponse = await api.client.request('GET /repos/:owner/:repo/actions/runs/:run_id', {
|
||||||
auth: core.getInput('token'),
|
|
||||||
userAgent: "CodeQL Action",
|
|
||||||
log: console_log_level_1.default({ level: 'debug' })
|
|
||||||
});
|
|
||||||
const runsResponse = await ok.request('GET /repos/:owner/:repo/actions/runs/:run_id', {
|
|
||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
run_id
|
run_id
|
||||||
});
|
});
|
||||||
const workflowUrl = runsResponse.data.workflow_url;
|
const workflowUrl = runsResponse.data.workflow_url;
|
||||||
const workflowResponse = await ok.request('GET ' + workflowUrl);
|
const workflowResponse = await api.client.request('GET ' + workflowUrl);
|
||||||
return workflowResponse.data.path;
|
return workflowResponse.data.path;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -252,7 +249,7 @@ async function createStatusReport(actionName, status, cause, exception) {
|
|||||||
if (exception) {
|
if (exception) {
|
||||||
statusReport.exception = exception;
|
statusReport.exception = exception;
|
||||||
}
|
}
|
||||||
if (status === 'success' || status === 'failure') {
|
if (status === 'success' || status === 'failure' || status === 'aborted') {
|
||||||
statusReport.completed_at = new Date().toISOString();
|
statusReport.completed_at = new Date().toISOString();
|
||||||
}
|
}
|
||||||
let matrix = core.getInput('matrix');
|
let matrix = core.getInput('matrix');
|
||||||
@@ -264,21 +261,19 @@ async function createStatusReport(actionName, status, cause, exception) {
|
|||||||
/**
|
/**
|
||||||
* Send a status report to the code_scanning/analysis/status endpoint.
|
* Send a status report to the code_scanning/analysis/status endpoint.
|
||||||
*
|
*
|
||||||
* Returns the status code of the response to the status request, or
|
* Returns the status code of the response to the status request.
|
||||||
* undefined if the given statusReport is undefined or no response was
|
|
||||||
* received.
|
|
||||||
*/
|
*/
|
||||||
async function sendStatusReport(statusReport) {
|
async function sendStatusReport(statusReport) {
|
||||||
var _a;
|
|
||||||
const statusReportJSON = JSON.stringify(statusReport);
|
const statusReportJSON = JSON.stringify(statusReport);
|
||||||
core.debug('Sending status report: ' + statusReportJSON);
|
core.debug('Sending status report: ' + statusReportJSON);
|
||||||
const githubToken = core.getInput('token');
|
const nwo = getRequiredEnvParam("GITHUB_REPOSITORY");
|
||||||
const ph = new auth.BearerCredentialHandler(githubToken);
|
const [owner, repo] = nwo.split("/");
|
||||||
const client = new http.HttpClient('Code Scanning : Status Report', [ph]);
|
const statusResponse = await api.client.request('PUT /repos/:owner/:repo/code-scanning/analysis/status', {
|
||||||
const url = 'https://api.github.com/repos/' + process.env['GITHUB_REPOSITORY']
|
owner: owner,
|
||||||
+ '/code-scanning/analysis/status';
|
repo: repo,
|
||||||
const res = await client.put(url, statusReportJSON);
|
data: statusReportJSON,
|
||||||
return (_a = res.message) === null || _a === void 0 ? void 0 : _a.statusCode;
|
});
|
||||||
|
return statusResponse.status;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Send a status report that an action is starting.
|
* Send a status report that an action is starting.
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
Generated
+7
-5
@@ -53,10 +53,12 @@ ava_1.default('getThreadsFlag() should return the correct --threads flag', t =>
|
|||||||
t.deepEqual(flag, expectedFlag);
|
t.deepEqual(flag, expectedFlag);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ava_1.default('getThreadsFlag() throws if the ram input is < 0 or NaN', t => {
|
ava_1.default('getThreadsFlag() throws if the threads input is not an integer', t => {
|
||||||
for (const input of ["hello!"]) {
|
process.env['INPUT_THREADS'] = "hello!";
|
||||||
process.env['INPUT_THREADS'] = input;
|
t.throws(util.getThreadsFlag);
|
||||||
t.throws(util.getThreadsFlag);
|
});
|
||||||
}
|
ava_1.default('getRef() throws on the empty string', t => {
|
||||||
|
process.env["GITHUB_REF"] = "";
|
||||||
|
t.throws(util.getRef);
|
||||||
});
|
});
|
||||||
//# sourceMappingURL=util.test.js.map
|
//# sourceMappingURL=util.test.js.map
|
||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"util.test.js","sourceRoot":"","sources":["../src/util.test.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8CAAuB;AACvB,uCAAyB;AACzB,uCAAyB;AAEzB,mDAAmD;AACnD,6CAA+B;AAE/B,kCAAkB,CAAC,aAAI,CAAC,CAAC;AAEzB,aAAI,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE;IACvB,MAAM,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,GAAG,mCAAmC,EAAE,MAAM,CAAC,CAAC;IACvF,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,+BAA+B,EAAE,QAAQ,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,sDAAsD,EAAE,CAAC,CAAC,EAAE;IAE/D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;IAE3D,MAAM,KAAK,GAAG;QACZ,EAAE,EAAE,SAAS,QAAQ,GAAG,GAAG,EAAE;QAC7B,KAAK,EAAE,WAAW;KACnB,CAAC;IAEF,KAAK,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QAEzD,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC;QAEjC,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;KACjC;AACH,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,uDAAuD,EAAE,CAAC,CAAC,EAAE;IAChE,KAAK,MAAM,KAAK,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE;QACpC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC;QACjC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;KAC9B;AACH,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,2DAA2D,EAAE,CAAC,CAAC,EAAE;IAEpE,MAAM,OAAO,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC;IAEjC,MAAM,KAAK,GAAG;QACZ,GAAG,EAAE,aAAa;QAClB,GAAG,EAAE,aAAa;QAClB,CAAC,GAAG,OAAO,GAAG,CAAC,EAAE,CAAC,EAAE,aAAa,OAAO,EAAE;QAC1C,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC,EAAE,aAAa,CAAC,OAAO,EAAE;KAC7C,CAAC;IAEF,KAAK,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QAEzD,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,KAAK,CAAC;QAErC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACnC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;KACjC;AACH,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,wDAAwD,EAAE,CAAC,CAAC,EAAE;IACjE,KAAK,MAAM,KAAK,IAAI,CAAC,QAAQ,CAAC,EAAE;QAC9B,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,KAAK,CAAC;QACrC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;KAC/B;AACH,CAAC,CAAC,CAAC"}
|
{"version":3,"file":"util.test.js","sourceRoot":"","sources":["../src/util.test.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8CAAuB;AACvB,uCAAyB;AACzB,uCAAyB;AAEzB,mDAAmD;AACnD,6CAA+B;AAE/B,kCAAkB,CAAC,aAAI,CAAC,CAAC;AAEzB,aAAI,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE;IACvB,MAAM,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,GAAG,mCAAmC,EAAE,MAAM,CAAC,CAAC;IACvF,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,+BAA+B,EAAE,QAAQ,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,sDAAsD,EAAE,CAAC,CAAC,EAAE;IAE/D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;IAE3D,MAAM,KAAK,GAAG;QACZ,EAAE,EAAE,SAAS,QAAQ,GAAG,GAAG,EAAE;QAC7B,KAAK,EAAE,WAAW;KACnB,CAAC;IAEF,KAAK,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QAEzD,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC;QAEjC,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;KACjC;AACH,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,uDAAuD,EAAE,CAAC,CAAC,EAAE;IAChE,KAAK,MAAM,KAAK,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE;QACpC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC;QACjC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;KAC9B;AACH,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,2DAA2D,EAAE,CAAC,CAAC,EAAE;IAEpE,MAAM,OAAO,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC;IAEjC,MAAM,KAAK,GAAG;QACZ,GAAG,EAAE,aAAa;QAClB,GAAG,EAAE,aAAa;QAClB,CAAC,GAAG,OAAO,GAAG,CAAC,EAAE,CAAC,EAAE,aAAa,OAAO,EAAE;QAC1C,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC,EAAE,aAAa,CAAC,OAAO,EAAE;KAC7C,CAAC;IAEF,KAAK,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QAEzD,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,KAAK,CAAC;QAErC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACnC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;KACjC;AACH,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,gEAAgE,EAAE,CAAC,CAAC,EAAE;IACzE,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,QAAQ,CAAC;IACxC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,qCAAqC,EAAE,CAAC,CAAC,EAAE;IAC9C,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC;IAC/B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACxB,CAAC,CAAC,CAAC"}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import * as core from "@actions/core";
|
||||||
|
import * as octokit from "@octokit/rest";
|
||||||
|
import consoleLogLevel from "console-log-level";
|
||||||
|
|
||||||
|
const githubAPIURL = process.env["GITHUB_API_URL"] || "https://api.github.com";
|
||||||
|
export const client = new octokit.Octokit({
|
||||||
|
auth: core.getInput("token"),
|
||||||
|
baseUrl: githubAPIURL,
|
||||||
|
userAgent: "CodeQL Action",
|
||||||
|
log: consoleLogLevel({ level: "debug" })
|
||||||
|
});
|
||||||
+13
-13
@@ -1,12 +1,11 @@
|
|||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import * as http from '@actions/http-client';
|
|
||||||
import * as auth from '@actions/http-client/auth';
|
|
||||||
import fileUrl from 'file-url';
|
import fileUrl from 'file-url';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as jsonschema from 'jsonschema';
|
import * as jsonschema from 'jsonschema';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import zlib from 'zlib';
|
import zlib from 'zlib';
|
||||||
|
|
||||||
|
import * as api from './api-client';
|
||||||
import * as fingerprints from './fingerprints';
|
import * as fingerprints from './fingerprints';
|
||||||
import * as sharedEnv from './shared-environment';
|
import * as sharedEnv from './shared-environment';
|
||||||
import * as util from './util';
|
import * as util from './util';
|
||||||
@@ -45,10 +44,7 @@ async function uploadPayload(payload): Promise<boolean> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const githubToken = core.getInput('token');
|
const [owner, repo] = util.getRequiredEnvParam("GITHUB_REPOSITORY").split("/");
|
||||||
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
|
// Make up to 4 attempts to upload, and sleep for these
|
||||||
// number of seconds between each attempt.
|
// number of seconds between each attempt.
|
||||||
@@ -57,21 +53,25 @@ async function uploadPayload(payload): Promise<boolean> {
|
|||||||
const backoffPeriods = [1, 5, 15];
|
const backoffPeriods = [1, 5, 15];
|
||||||
|
|
||||||
for (let attempt = 0; attempt <= backoffPeriods.length; attempt++) {
|
for (let attempt = 0; attempt <= backoffPeriods.length; attempt++) {
|
||||||
|
const response = await api.client.request("PUT /repos/:owner/:repo/code-scanning/analysis", ({
|
||||||
|
owner: owner,
|
||||||
|
repo: repo,
|
||||||
|
data: payload,
|
||||||
|
}));
|
||||||
|
|
||||||
const res: http.HttpClientResponse = await client.put(url, payload);
|
core.debug('response status: ' + response.status);
|
||||||
core.debug('response status: ' + res.message.statusCode);
|
|
||||||
|
|
||||||
const statusCode = res.message.statusCode;
|
const statusCode = response.status;
|
||||||
if (statusCode === 202) {
|
if (statusCode === 202) {
|
||||||
core.info("Successfully uploaded results");
|
core.info("Successfully uploaded results");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const requestID = res.message.headers["x-github-request-id"];
|
const requestID = response.headers["x-github-request-id"];
|
||||||
|
|
||||||
// On any other status code that's not 5xx mark the upload as failed
|
// On any other status code that's not 5xx mark the upload as failed
|
||||||
if (!statusCode || statusCode < 500 || statusCode >= 600) {
|
if (!statusCode || statusCode < 500 || statusCode >= 600) {
|
||||||
core.setFailed('Upload failed (' + requestID + '): (' + statusCode + ') ' + await res.readBody());
|
core.setFailed('Upload failed (' + requestID + '): (' + statusCode + ') ' + JSON.stringify(response.data));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ async function uploadPayload(payload): Promise<boolean> {
|
|||||||
// Log the failure as a warning but don't mark the action as failed yet
|
// 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) +
|
core.warning('Upload attempt (' + (attempt + 1) + ' of ' + (backoffPeriods.length + 1) +
|
||||||
') failed (' + requestID + '). Retrying in ' + backoffPeriods[attempt] +
|
') failed (' + requestID + '). Retrying in ' + backoffPeriods[attempt] +
|
||||||
' seconds: (' + statusCode + ') ' + await res.readBody());
|
' seconds: (' + statusCode + ') ' + JSON.stringify(response.data));
|
||||||
// Sleep for the backoff period
|
// Sleep for the backoff period
|
||||||
await new Promise(r => setTimeout(r, backoffPeriods[attempt] * 1000));
|
await new Promise(r => setTimeout(r, backoffPeriods[attempt] * 1000));
|
||||||
continue;
|
continue;
|
||||||
@@ -89,7 +89,7 @@ async function uploadPayload(payload): Promise<boolean> {
|
|||||||
// If the upload fails with 5xx then we assume it is a temporary problem
|
// 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.
|
// and not an error that the user has caused or can fix.
|
||||||
// We avoid marking the job as failed to avoid breaking CI workflows.
|
// We avoid marking the job as failed to avoid breaking CI workflows.
|
||||||
core.error('Upload failed (' + requestID + '): (' + statusCode + ') ' + await res.readBody());
|
core.error('Upload failed (' + requestID + '): (' + statusCode + ') ' + JSON.stringify(response.data));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-5
@@ -58,9 +58,12 @@ test('getThreadsFlag() should return the correct --threads flag', t => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('getThreadsFlag() throws if the ram input is < 0 or NaN', t => {
|
test('getThreadsFlag() throws if the threads input is not an integer', t => {
|
||||||
for (const input of ["hello!"]) {
|
process.env['INPUT_THREADS'] = "hello!";
|
||||||
process.env['INPUT_THREADS'] = input;
|
t.throws(util.getThreadsFlag);
|
||||||
t.throws(util.getThreadsFlag);
|
});
|
||||||
}
|
|
||||||
|
test('getRef() throws on the empty string', t => {
|
||||||
|
process.env["GITHUB_REF"] = "";
|
||||||
|
t.throws(util.getRef);
|
||||||
});
|
});
|
||||||
|
|||||||
+38
-42
@@ -1,13 +1,10 @@
|
|||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import * as exec from '@actions/exec';
|
import * as exec from '@actions/exec';
|
||||||
import * as http from '@actions/http-client';
|
|
||||||
import * as auth from '@actions/http-client/auth';
|
|
||||||
import * as octokit from '@octokit/rest';
|
|
||||||
import consoleLogLevel from 'console-log-level';
|
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
|
import * as api from './api-client';
|
||||||
import * as sharedEnv from './shared-environment';
|
import * as sharedEnv from './shared-environment';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,7 +37,7 @@ export function should_abort(actionName: string, requireInitActionHasRun: boolea
|
|||||||
*/
|
*/
|
||||||
export function getRequiredEnvParam(paramName: string): string {
|
export function getRequiredEnvParam(paramName: string): string {
|
||||||
const value = process.env[paramName];
|
const value = process.env[paramName];
|
||||||
if (value === undefined) {
|
if (value === undefined || value.length === 0) {
|
||||||
throw new Error(paramName + ' environment variable must be set');
|
throw new Error(paramName + ' environment variable must be set');
|
||||||
}
|
}
|
||||||
core.debug(paramName + '=' + value);
|
core.debug(paramName + '=' + value);
|
||||||
@@ -68,12 +65,7 @@ async function getLanguagesInRepo(): Promise<string[]> {
|
|||||||
let repo = repo_nwo[1];
|
let repo = repo_nwo[1];
|
||||||
|
|
||||||
core.debug(`GitHub repo ${owner} ${repo}`);
|
core.debug(`GitHub repo ${owner} ${repo}`);
|
||||||
let ok = new octokit.Octokit({
|
const response = await api.client.request("GET /repos/:owner/:repo/languages", ({
|
||||||
auth: core.getInput('token'),
|
|
||||||
userAgent: "CodeQL Action",
|
|
||||||
log: consoleLogLevel({ level: "debug" })
|
|
||||||
});
|
|
||||||
const response = await ok.request("GET /repos/:owner/:repo/languages", ({
|
|
||||||
owner,
|
owner,
|
||||||
repo
|
repo
|
||||||
}));
|
}));
|
||||||
@@ -139,15 +131,27 @@ export async function getLanguages(): Promise<string[]> {
|
|||||||
* Gets the SHA of the commit that is currently checked out.
|
* Gets the SHA of the commit that is currently checked out.
|
||||||
*/
|
*/
|
||||||
export async function getCommitOid(): Promise<string> {
|
export async function getCommitOid(): Promise<string> {
|
||||||
let commitOid = '';
|
// Try to use git to get the current commit SHA. If that fails then
|
||||||
await exec.exec('git', ['rev-parse', 'HEAD'], {
|
// log but otherwise silently fall back to using the SHA from the environment.
|
||||||
silent: true,
|
// The only time these two values will differ is during analysis of a PR when
|
||||||
listeners: {
|
// the workflow has changed the current commit to the head commit instead of
|
||||||
stdout: (data) => { commitOid += data.toString(); },
|
// the merge commit, which must mean that git is available.
|
||||||
stderr: (data) => { process.stderr.write(data); }
|
// Even if this does go wrong, it's not a huge problem for the alerts to
|
||||||
}
|
// reported on the merge commit.
|
||||||
});
|
try {
|
||||||
return commitOid.trim();
|
let commitOid = '';
|
||||||
|
await exec.exec('git', ['rev-parse', 'HEAD'], {
|
||||||
|
silent: true,
|
||||||
|
listeners: {
|
||||||
|
stdout: (data) => { commitOid += data.toString(); },
|
||||||
|
stderr: (data) => { process.stderr.write(data); }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return commitOid.trim();
|
||||||
|
} catch (e) {
|
||||||
|
core.info("Failed to call git to get current commit. Continuing with data from environment: " + e);
|
||||||
|
return getRequiredEnvParam('GITHUB_SHA');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -157,22 +161,16 @@ async function getWorkflowPath(): Promise<string> {
|
|||||||
const repo_nwo = getRequiredEnvParam('GITHUB_REPOSITORY').split("/");
|
const repo_nwo = getRequiredEnvParam('GITHUB_REPOSITORY').split("/");
|
||||||
const owner = repo_nwo[0];
|
const owner = repo_nwo[0];
|
||||||
const repo = repo_nwo[1];
|
const repo = repo_nwo[1];
|
||||||
const run_id = getRequiredEnvParam('GITHUB_RUN_ID');
|
const run_id = Number(getRequiredEnvParam('GITHUB_RUN_ID'));
|
||||||
|
|
||||||
const ok = new octokit.Octokit({
|
const runsResponse = await api.client.request('GET /repos/:owner/:repo/actions/runs/:run_id', {
|
||||||
auth: core.getInput('token'),
|
|
||||||
userAgent: "CodeQL Action",
|
|
||||||
log: consoleLogLevel({ level: 'debug' })
|
|
||||||
});
|
|
||||||
|
|
||||||
const runsResponse = await ok.request('GET /repos/:owner/:repo/actions/runs/:run_id', {
|
|
||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
run_id
|
run_id
|
||||||
});
|
});
|
||||||
const workflowUrl = runsResponse.data.workflow_url;
|
const workflowUrl = runsResponse.data.workflow_url;
|
||||||
|
|
||||||
const workflowResponse = await ok.request('GET ' + workflowUrl);
|
const workflowResponse = await api.client.request('GET ' + workflowUrl);
|
||||||
|
|
||||||
return workflowResponse.data.path;
|
return workflowResponse.data.path;
|
||||||
}
|
}
|
||||||
@@ -283,7 +281,7 @@ async function createStatusReport(
|
|||||||
if (exception) {
|
if (exception) {
|
||||||
statusReport.exception = exception;
|
statusReport.exception = exception;
|
||||||
}
|
}
|
||||||
if (status === 'success' || status === 'failure') {
|
if (status === 'success' || status === 'failure' || status === 'aborted') {
|
||||||
statusReport.completed_at = new Date().toISOString();
|
statusReport.completed_at = new Date().toISOString();
|
||||||
}
|
}
|
||||||
let matrix: string | undefined = core.getInput('matrix');
|
let matrix: string | undefined = core.getInput('matrix');
|
||||||
@@ -297,23 +295,21 @@ async function createStatusReport(
|
|||||||
/**
|
/**
|
||||||
* Send a status report to the code_scanning/analysis/status endpoint.
|
* Send a status report to the code_scanning/analysis/status endpoint.
|
||||||
*
|
*
|
||||||
* Returns the status code of the response to the status request, or
|
* Returns the status code of the response to the status request.
|
||||||
* undefined if the given statusReport is undefined or no response was
|
|
||||||
* received.
|
|
||||||
*/
|
*/
|
||||||
async function sendStatusReport(statusReport: StatusReport): Promise<number | undefined> {
|
async function sendStatusReport(statusReport: StatusReport): Promise<number> {
|
||||||
const statusReportJSON = JSON.stringify(statusReport);
|
const statusReportJSON = JSON.stringify(statusReport);
|
||||||
|
|
||||||
core.debug('Sending status report: ' + statusReportJSON);
|
core.debug('Sending status report: ' + statusReportJSON);
|
||||||
|
|
||||||
const githubToken = core.getInput('token');
|
const nwo = getRequiredEnvParam("GITHUB_REPOSITORY");
|
||||||
const ph: auth.BearerCredentialHandler = new auth.BearerCredentialHandler(githubToken);
|
const [owner, repo] = nwo.split("/");
|
||||||
const client = new http.HttpClient('Code Scanning : Status Report', [ph]);
|
const statusResponse = await api.client.request('PUT /repos/:owner/:repo/code-scanning/analysis/status', {
|
||||||
const url = 'https://api.github.com/repos/' + process.env['GITHUB_REPOSITORY']
|
owner: owner,
|
||||||
+ '/code-scanning/analysis/status';
|
repo: repo,
|
||||||
const res: http.HttpClientResponse = await client.put(url, statusReportJSON);
|
data: statusReportJSON,
|
||||||
|
});
|
||||||
return res.message?.statusCode;
|
return statusResponse.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user