Permalink
April 28, 2020 16:46
April 28, 2020 16:46
April 28, 2020 16:46
Newer
100644
142 lines (142 sloc)
6.45 KB
1
"use strict";
2
var __importStar = (this && this.__importStar) || function (mod) {
3
if (mod && mod.__esModule) return mod;
4
var result = {};
5
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
6
result["default"] = mod;
7
return result;
8
};
9
var __importDefault = (this && this.__importDefault) || function (mod) {
10
return (mod && mod.__esModule) ? mod : { "default": mod };
11
};
12
Object.defineProperty(exports, "__esModule", { value: true });
13
const core = __importStar(require("@actions/core"));
14
const http = __importStar(require("@actions/http-client"));
15
const auth = __importStar(require("@actions/http-client/auth"));
16
const io = __importStar(require("@actions/io"));
17
const file_url_1 = __importDefault(require("file-url"));
18
const fs = __importStar(require("fs"));
19
const path = __importStar(require("path"));
20
const zlib_1 = __importDefault(require("zlib"));
21
const fingerprints = __importStar(require("./fingerprints"));
22
const sharedEnv = __importStar(require("./shared-environment"));
23
const util = __importStar(require("./util"));
24
// Construct the location of the sentinel file for detecting multiple uploads.
25
// The returned location should be writable.
26
async function getSentinelFilePath() {
27
// Use the temp dir instead of placing next to the sarif file because of
28
// issues with docker actions. The directory containing the sarif file
29
// may not be writable by us.
30
const uploadsTmpDir = path.join(process.env['RUNNER_TEMP'] || '/tmp/codeql-action', 'uploads');
31
await io.mkdirP(uploadsTmpDir);
32
// Hash the absolute path so we'll behave correctly in the unlikely
33
// scenario a file is referenced twice with different paths.
34
return path.join(uploadsTmpDir, 'codeql-action-upload-sentinel');
35
}
36
// Takes a list of paths to sarif files and combines them together,
37
// returning the contents of the combined sarif file.
38
function combineSarifFiles(sarifFiles) {
39
let combinedSarif = {
40
version: null,
41
runs: []
42
};
43
for (let sarifFile of sarifFiles) {
44
let sarifObject = JSON.parse(fs.readFileSync(sarifFile, 'utf8'));
45
// Check SARIF version
46
if (combinedSarif.version === null) {
47
combinedSarif.version = sarifObject.version;
48
}
49
else if (combinedSarif.version !== sarifObject.version) {
50
throw "Different SARIF versions encountered: " + combinedSarif.version + " and " + sarifObject.version;
51
}
52
combinedSarif.runs.push(...sarifObject.runs);
53
}
54
return JSON.stringify(combinedSarif);
55
}
56
exports.combineSarifFiles = combineSarifFiles;
57
// Uploads a single sarif file or a directory of sarif files
58
// depending on what the path happens to refer to.
59
async function upload(input) {
60
if (fs.lstatSync(input).isDirectory()) {
61
const sarifFiles = fs.readdirSync(input)
62
.filter(f => f.endsWith(".sarif"))
63
.map(f => path.resolve(input, f));
64
await uploadFiles(sarifFiles);
65
}
66
else {
67
await uploadFiles([input]);
68
}
69
}
70
exports.upload = upload;
71
// Uploads the given set of sarif files.
72
async function uploadFiles(sarifFiles) {
73
core.startGroup("Uploading results");
74
try {
75
// Check if an upload has happened before. If so then abort.
76
// This is intended to catch when the finish and upload-sarif actions
77
// are used together, and then the upload-sarif action is invoked twice.
78
const sentinelFile = await getSentinelFilePath();
79
if (fs.existsSync(sentinelFile)) {
80
core.info("Aborting as an upload has already happened from this job");
81
return;
82
}
83
const commitOid = util.getRequiredEnvParam('GITHUB_SHA');
84
const workflowRunIDStr = util.getRequiredEnvParam('GITHUB_RUN_ID');
85
const ref = util.getRequiredEnvParam('GITHUB_REF'); // it's in the form "refs/heads/master"
86
const analysisName = util.getRequiredEnvParam('GITHUB_WORKFLOW');
87
const startedAt = process.env[sharedEnv.CODEQL_ACTION_STARTED_AT];
88
core.debug("Uploading sarif files: " + JSON.stringify(sarifFiles));
89
let sarifPayload = combineSarifFiles(sarifFiles);
90
sarifPayload = fingerprints.addFingerprints(sarifPayload);
91
const zipped_sarif = zlib_1.default.gzipSync(sarifPayload).toString('base64');
92
let checkoutPath = core.getInput('checkout_path');
93
let checkoutURI = file_url_1.default(checkoutPath);
94
const workflowRunID = parseInt(workflowRunIDStr, 10);
95
if (Number.isNaN(workflowRunID)) {
96
core.setFailed('GITHUB_RUN_ID must define a non NaN workflow run ID');
97
return;
98
}
99
let matrix = core.getInput('matrix');
100
if (matrix === "null" || matrix === "") {
101
matrix = undefined;
102
}
104
const payload = JSON.stringify({
105
"commit_oid": commitOid,
106
"ref": ref,
107
"analysis_name": analysisName,
108
"sarif": zipped_sarif,
109
"workflow_run_id": workflowRunID,
110
"checkout_uri": checkoutURI,
111
"environment": matrix,
114
});
115
core.info('Uploading results');
116
const githubToken = core.getInput('token');
117
const ph = new auth.BearerCredentialHandler(githubToken);
118
const client = new http.HttpClient('Code Scanning : Upload SARIF', [ph]);
119
const url = 'https://api.github.com/repos/' + process.env['GITHUB_REPOSITORY'] + '/code-scanning/analysis';
120
const res = await client.put(url, payload);
121
const requestID = res.message.headers["x-github-request-id"];
122
core.debug('response status: ' + res.message.statusCode);
123
if (res.message.statusCode === 500) {
124
// If the upload fails with 500 then we assume it is a temporary problem
125
// with turbo-scan and not an error that the user has caused or can fix.
126
// We avoid marking the job as failed to avoid breaking CI workflows.
127
core.error('Upload failed (' + requestID + '): ' + await res.readBody());
128
}
129
else if (res.message.statusCode !== 202) {
130
core.setFailed('Upload failed (' + requestID + '): ' + await res.readBody());
131
}
132
else {
133
core.info("Successfully uploaded results");
134
}
135
// Mark that we have made an upload
136
fs.writeFileSync(sentinelFile, '');
137
}
138
catch (error) {
139
core.setFailed(error.message);
140
}
141
core.endGroup();
142
}