mirror of
https://github.com/github/codeql-action.git
synced 2025-12-14 03:20:11 +08:00
Compare commits
30 Commits
revert-132
...
bundle-tes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bcf676e52d | ||
|
|
7c2a7b236c | ||
|
|
0fdcc52338 | ||
|
|
d5693a7fd2 | ||
|
|
eb4eda5cbe | ||
|
|
6e18b27d4d | ||
|
|
de0b59097a | ||
|
|
d5c453c995 | ||
|
|
657540584e | ||
|
|
a0660c80bd | ||
|
|
396f7167d8 | ||
|
|
e5ad069f2c | ||
|
|
5b35de62bd | ||
|
|
d5853409b4 | ||
|
|
8608105240 | ||
|
|
ac66bbe1fe | ||
|
|
3a28cb4ca8 | ||
|
|
8127c47bbd | ||
|
|
44c88fdd05 | ||
|
|
6230b36dc2 | ||
|
|
3d552ba624 | ||
|
|
42235cc048 | ||
|
|
631929a68f | ||
|
|
128c2cf718 | ||
|
|
69bf3f24d4 | ||
|
|
02d3d62def | ||
|
|
dc366899d2 | ||
|
|
4896ba51da | ||
|
|
30d2cce9f8 | ||
|
|
368c14c502 |
2
.github/workflows/integration-testing.yml
vendored
2
.github/workflows/integration-testing.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
TEST_MODE: true
|
TEST_MODE: true
|
||||||
- run: |
|
- run: |
|
||||||
cd "$CODEQL_ACTION_DATABASE_DIR"
|
cd "$RUNNER_TEMP/codeql_databases"
|
||||||
# List all directories as there will be precisely one directory per database
|
# List all directories as there will be precisely one directory per database
|
||||||
# but there may be other files in this directory such as query suites.
|
# but there may be other files in this directory such as query suites.
|
||||||
if [ "$(ls -d */ | wc -l)" != 6 ] || \
|
if [ "$(ls -d */ | wc -l)" != 6 ] || \
|
||||||
|
|||||||
@@ -26,6 +26,25 @@ This project also includes configuration to run tests from VSCode (with support
|
|||||||
|
|
||||||
To see the effect of your changes and to test them, push your changes in a branch and then look at the [Actions output](https://github.com/github/codeql-action/actions) for that branch. You can also exercise the code locally by running the automated tests.
|
To see the effect of your changes and to test them, push your changes in a branch and then look at the [Actions output](https://github.com/github/codeql-action/actions) for that branch. You can also exercise the code locally by running the automated tests.
|
||||||
|
|
||||||
|
### Running the action locally
|
||||||
|
|
||||||
|
It is possible to run this action locally via [act](https://github.com/nektos/act) via the following steps:
|
||||||
|
|
||||||
|
1. Create a GitHub [Personal Access Token](https://github.com/settings/tokens) (PAT).
|
||||||
|
1. Install [act](https://github.com/nektos/act) v0.2.10 or greater.
|
||||||
|
1. Add a `.env` file in the root of the project you are running:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
CODEQL_LOCAL_RUN=true
|
||||||
|
|
||||||
|
# Optional, for better logging
|
||||||
|
GITHUB_JOB=<ANY_JOB_NAME>
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Run `act -j codeql -s GITHUB_TOKEN=<PAT>`
|
||||||
|
|
||||||
|
Running locally will generate the CodeQL database and run all the queries, but it will avoid uploading and reporting results to GitHub. Note that this must be done on a repository that _consumes_ this action, not this repository. The use case is to debug failures of this action on specific repositories.
|
||||||
|
|
||||||
### Integration tests
|
### Integration tests
|
||||||
|
|
||||||
As well as the unit tests (see _Common tasks_ above), there are integration tests, defined in `.github/workflows/integration-testing.yml`. These are run by a CI check. Depending on the change you’re making, you may want to add a test to this file or extend an existing one.
|
As well as the unit tests (see _Common tasks_ above), there are integration tests, defined in `.github/workflows/integration-testing.yml`. These are run by a CI check. Depending on the change you’re making, you may want to add a test to this file or extend an existing one.
|
||||||
|
|||||||
6
lib/api-client.js
generated
6
lib/api-client.js
generated
@@ -13,7 +13,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||||||
const core = __importStar(require("@actions/core"));
|
const core = __importStar(require("@actions/core"));
|
||||||
const github = __importStar(require("@actions/github"));
|
const github = __importStar(require("@actions/github"));
|
||||||
const console_log_level_1 = __importDefault(require("console-log-level"));
|
const console_log_level_1 = __importDefault(require("console-log-level"));
|
||||||
exports.getApiClient = function () {
|
const util_1 = require("./util");
|
||||||
|
exports.getApiClient = function (allowLocalRun = false) {
|
||||||
|
if (util_1.isLocalRun() && !allowLocalRun) {
|
||||||
|
throw new Error('Invalid API call in local run');
|
||||||
|
}
|
||||||
return new github.GitHub(core.getInput('token'), {
|
return new github.GitHub(core.getInput('token'), {
|
||||||
userAgent: "CodeQL Action",
|
userAgent: "CodeQL Action",
|
||||||
log: console_log_level_1.default({ level: "debug" })
|
log: console_log_level_1.default({ level: "debug" })
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,oDAAsC;AACtC,wDAA0C;AAC1C,0EAAgD;AAEnC,QAAA,YAAY,GAAG;IAC1B,OAAO,IAAI,MAAM,CAAC,MAAM,CACtB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EACtB;QACE,SAAS,EAAE,eAAe;QAC1B,GAAG,EAAE,2BAAe,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;KACzC,CAAC,CAAC;AACP,CAAC,CAAC"}
|
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,oDAAsC;AACtC,wDAA0C;AAC1C,0EAAgD;AAEhD,iCAAoC;AAEvB,QAAA,YAAY,GAAG,UAAS,aAAa,GAAG,KAAK;IACxD,IAAI,iBAAU,EAAE,IAAI,CAAC,aAAa,EAAE;QAClC,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;KAClD;IACD,OAAO,IAAI,MAAM,CAAC,MAAM,CACtB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EACtB;QACE,SAAS,EAAE,eAAe;QAC1B,GAAG,EAAE,2BAAe,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;KACzC,CAAC,CAAC;AACP,CAAC,CAAC"}
|
||||||
11
lib/autobuild.js
generated
11
lib/autobuild.js
generated
@@ -9,7 +9,7 @@ var __importStar = (this && this.__importStar) || 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 codeql_1 = require("./codeql");
|
const codeql_1 = require("./codeql");
|
||||||
const sharedEnv = __importStar(require("./shared-environment"));
|
const config_utils = __importStar(require("./config-utils"));
|
||||||
const util = __importStar(require("./util"));
|
const util = __importStar(require("./util"));
|
||||||
async function sendCompletedStatusReport(startedAt, allLanguages, failingLanguage, cause) {
|
async function sendCompletedStatusReport(startedAt, allLanguages, failingLanguage, cause) {
|
||||||
var _a, _b;
|
var _a, _b;
|
||||||
@@ -23,19 +23,19 @@ async function sendCompletedStatusReport(startedAt, allLanguages, failingLanguag
|
|||||||
await util.sendStatusReport(statusReport);
|
await util.sendStatusReport(statusReport);
|
||||||
}
|
}
|
||||||
async function run() {
|
async function run() {
|
||||||
var _a;
|
|
||||||
const startedAt = new Date();
|
const startedAt = new Date();
|
||||||
let language;
|
let language;
|
||||||
try {
|
try {
|
||||||
if (util.should_abort('autobuild', true) ||
|
util.prepareLocalRunEnvironment();
|
||||||
!await util.sendStatusReport(await util.createStatusReportBase('autobuild', 'starting', startedAt), true)) {
|
if (!await util.sendStatusReport(await util.createStatusReportBase('autobuild', 'starting', startedAt), true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const config = await config_utils.getConfig();
|
||||||
// Attempt to find a language to autobuild
|
// Attempt to find a language to autobuild
|
||||||
// We want pick the dominant language in the repo from the ones we're able to build
|
// We want pick the dominant language in the repo from the ones we're able to build
|
||||||
// The languages are sorted in order specified by user or by lines of code if we got
|
// The languages are sorted in order specified by user or by lines of code if we got
|
||||||
// them from the GitHub API, so try to build the first language on the list.
|
// them from the GitHub API, so try to build the first language on the list.
|
||||||
const autobuildLanguages = ((_a = process.env[sharedEnv.CODEQL_ACTION_TRACED_LANGUAGES]) === null || _a === void 0 ? void 0 : _a.split(',')) || [];
|
const autobuildLanguages = config.languages.filter(codeql_1.isTracedLanguage);
|
||||||
language = autobuildLanguages[0];
|
language = autobuildLanguages[0];
|
||||||
if (!language) {
|
if (!language) {
|
||||||
core.info("None of the languages in this project require extra build steps");
|
core.info("None of the languages in this project require extra build steps");
|
||||||
@@ -52,6 +52,7 @@ async function run() {
|
|||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
core.setFailed("We were unable to automatically build your code. Please replace the call to the autobuild action with your custom build steps. " + error.message);
|
core.setFailed("We were unable to automatically build your code. Please replace the call to the autobuild action with your custom build steps. " + error.message);
|
||||||
|
console.log(error);
|
||||||
await sendCompletedStatusReport(startedAt, [language], language, error);
|
await sendCompletedStatusReport(startedAt, [language], language, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"autobuild.js","sourceRoot":"","sources":["../src/autobuild.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AAEtC,qCAAqC;AACrC,gEAAkD;AAClD,6CAA+B;AAS/B,KAAK,UAAU,yBAAyB,CACtC,SAAe,EACf,YAAsB,EACtB,eAAwB,EACxB,KAAa;;IAEb,MAAM,MAAM,GAAG,eAAe,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5F,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,sBAAsB,CACxD,WAAW,EACX,MAAM,EACN,SAAS,QACT,KAAK,0CAAE,OAAO,QACd,KAAK,0CAAE,KAAK,CAAC,CAAC;IAChB,MAAM,YAAY,GAA0B;QAC1C,GAAG,gBAAgB;QACnB,mBAAmB,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;QAC3C,iBAAiB,EAAE,eAAe;KACnC,CAAC;IACF,MAAM,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;AAC5C,CAAC;AAED,KAAK,UAAU,GAAG;;IAChB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,IAAI,QAAQ,CAAC;IACb,IAAI;QACF,IAAI,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,IAAI,CAAC;YACpC,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,IAAI,CAAC,sBAAsB,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC,EAAE;YAC7G,OAAO;SACR;QAED,0CAA0C;QAC1C,mFAAmF;QACnF,oFAAoF;QACpF,4EAA4E;QAC5E,MAAM,kBAAkB,GAAG,OAAA,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,8BAA8B,CAAC,0CAAE,KAAK,CAAC,GAAG,MAAK,EAAE,CAAC;QACnG,QAAQ,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;QAEjC,IAAI,CAAC,QAAQ,EAAE;YACb,IAAI,CAAC,IAAI,CAAC,iEAAiE,CAAC,CAAC;YAC7E,OAAO;SACR;QAED,IAAI,CAAC,KAAK,CAAC,sCAAsC,QAAQ,EAAE,CAAC,CAAC;QAE7D,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE;YACjC,IAAI,CAAC,OAAO,CAAC,oCAAoC,QAAQ,8BAA8B,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,wDAAwD,CAAC,CAAC;SAC3L;QAED,IAAI,CAAC,UAAU,CAAC,qCAAqC,QAAQ,OAAO,CAAC,CAAC;QACtE,MAAM,MAAM,GAAG,kBAAS,EAAE,CAAC;QAC3B,MAAM,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAEpC,IAAI,CAAC,QAAQ,EAAE,CAAC;KAEjB;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,kIAAkI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;QACnK,MAAM,yBAAyB,CAAC,SAAS,EAAE,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACxE,OAAO;KACR;IAED,MAAM,yBAAyB,CAAC,SAAS,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACd,IAAI,CAAC,SAAS,CAAC,4BAA4B,GAAG,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
|
{"version":3,"file":"autobuild.js","sourceRoot":"","sources":["../src/autobuild.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AAEtC,qCAAuD;AACvD,6DAA+C;AAC/C,6CAA+B;AAS/B,KAAK,UAAU,yBAAyB,CACtC,SAAe,EACf,YAAsB,EACtB,eAAwB,EACxB,KAAa;;IAEb,MAAM,MAAM,GAAG,eAAe,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5F,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,sBAAsB,CACxD,WAAW,EACX,MAAM,EACN,SAAS,QACT,KAAK,0CAAE,OAAO,QACd,KAAK,0CAAE,KAAK,CAAC,CAAC;IAChB,MAAM,YAAY,GAA0B;QAC1C,GAAG,gBAAgB;QACnB,mBAAmB,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;QAC3C,iBAAiB,EAAE,eAAe;KACnC,CAAC;IACF,MAAM,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;AAC5C,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,IAAI,QAAQ,CAAC;IACb,IAAI;QACF,IAAI,CAAC,0BAA0B,EAAE,CAAC;QAClC,IAAI,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,IAAI,CAAC,sBAAsB,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC,EAAE;YAC7G,OAAO;SACR;QAED,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,EAAE,CAAC;QAE9C,0CAA0C;QAC1C,mFAAmF;QACnF,oFAAoF;QACpF,4EAA4E;QAC5E,MAAM,kBAAkB,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,yBAAgB,CAAC,CAAC;QACrE,QAAQ,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;QAEjC,IAAI,CAAC,QAAQ,EAAE;YACb,IAAI,CAAC,IAAI,CAAC,iEAAiE,CAAC,CAAC;YAC7E,OAAO;SACR;QAED,IAAI,CAAC,KAAK,CAAC,sCAAsC,QAAQ,EAAE,CAAC,CAAC;QAE7D,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE;YACjC,IAAI,CAAC,OAAO,CAAC,oCAAoC,QAAQ,8BAA8B,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,wDAAwD,CAAC,CAAC;SAC3L;QAED,IAAI,CAAC,UAAU,CAAC,qCAAqC,QAAQ,OAAO,CAAC,CAAC;QACtE,MAAM,MAAM,GAAG,kBAAS,EAAE,CAAC;QAC3B,MAAM,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAEpC,IAAI,CAAC,QAAQ,EAAE,CAAC;KAEjB;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,kIAAkI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;QACnK,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,yBAAyB,CAAC,SAAS,EAAE,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACxE,OAAO;KACR;IAED,MAAM,yBAAyB,CAAC,SAAS,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACd,IAAI,CAAC,SAAS,CAAC,4BAA4B,GAAG,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
|
||||||
25
lib/codeql.js
generated
25
lib/codeql.js
generated
@@ -13,7 +13,6 @@ 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 http = __importStar(require("@actions/http-client"));
|
||||||
const io = __importStar(require("@actions/io"));
|
|
||||||
const toolcache = __importStar(require("@actions/tool-cache"));
|
const toolcache = __importStar(require("@actions/tool-cache"));
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
@@ -35,11 +34,7 @@ let cachedCodeQL = undefined;
|
|||||||
const CODEQL_ACTION_CMD = "CODEQL_ACTION_CMD";
|
const CODEQL_ACTION_CMD = "CODEQL_ACTION_CMD";
|
||||||
const CODEQL_BUNDLE_VERSION = "codeql-bundle-20200630";
|
const CODEQL_BUNDLE_VERSION = "codeql-bundle-20200630";
|
||||||
const CODEQL_BUNDLE_NAME = "codeql-bundle.tar.gz";
|
const CODEQL_BUNDLE_NAME = "codeql-bundle.tar.gz";
|
||||||
const GITHUB_DOTCOM_API_URL = "https://api.github.com";
|
|
||||||
const CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action";
|
const CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action";
|
||||||
function getInstanceAPIURL() {
|
|
||||||
return process.env["GITHUB_API_URL"] || GITHUB_DOTCOM_API_URL;
|
|
||||||
}
|
|
||||||
function getCodeQLActionRepository() {
|
function getCodeQLActionRepository() {
|
||||||
// Actions do not know their own repository name,
|
// Actions do not know their own repository name,
|
||||||
// so we currently use this hack to find the name based on where our files are.
|
// so we currently use this hack to find the name based on where our files are.
|
||||||
@@ -59,11 +54,11 @@ async function getCodeQLBundleDownloadURL() {
|
|||||||
const codeQLActionRepository = getCodeQLActionRepository();
|
const codeQLActionRepository = getCodeQLActionRepository();
|
||||||
const potentialDownloadSources = [
|
const potentialDownloadSources = [
|
||||||
// This GitHub instance, and this Action.
|
// This GitHub instance, and this Action.
|
||||||
[getInstanceAPIURL(), codeQLActionRepository],
|
[util.getInstanceAPIURL(), codeQLActionRepository],
|
||||||
// This GitHub instance, and the canonical Action.
|
// This GitHub instance, and the canonical Action.
|
||||||
[getInstanceAPIURL(), CODEQL_DEFAULT_ACTION_REPOSITORY],
|
[util.getInstanceAPIURL(), CODEQL_DEFAULT_ACTION_REPOSITORY],
|
||||||
// GitHub.com, and the canonical Action.
|
// GitHub.com, and the canonical Action.
|
||||||
[GITHUB_DOTCOM_API_URL, CODEQL_DEFAULT_ACTION_REPOSITORY],
|
[util.GITHUB_DOTCOM_API_URL, CODEQL_DEFAULT_ACTION_REPOSITORY],
|
||||||
];
|
];
|
||||||
// We now filter out any duplicates.
|
// We now filter out any duplicates.
|
||||||
// Duplicates will happen either because the GitHub instance is GitHub.com, or because the Action is not a fork.
|
// Duplicates will happen either because the GitHub instance is GitHub.com, or because the Action is not a fork.
|
||||||
@@ -71,7 +66,7 @@ async function getCodeQLBundleDownloadURL() {
|
|||||||
for (let downloadSource of uniqueDownloadSources) {
|
for (let downloadSource of uniqueDownloadSources) {
|
||||||
let [apiURL, repository] = downloadSource;
|
let [apiURL, repository] = downloadSource;
|
||||||
// If we've reached the final case, short-circuit the API check since we know the bundle exists and is public.
|
// If we've reached the final case, short-circuit the API check since we know the bundle exists and is public.
|
||||||
if (apiURL === GITHUB_DOTCOM_API_URL && repository === CODEQL_DEFAULT_ACTION_REPOSITORY) {
|
if (apiURL === util.GITHUB_DOTCOM_API_URL && repository === CODEQL_DEFAULT_ACTION_REPOSITORY) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let [repositoryOwner, repositoryName] = repository.split("/");
|
let [repositoryOwner, repositoryName] = repository.split("/");
|
||||||
@@ -106,7 +101,7 @@ async function toolcacheDownloadTool(url, headers) {
|
|||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
const pipeline = globalutil.promisify(stream.pipeline);
|
const pipeline = globalutil.promisify(stream.pipeline);
|
||||||
await io.mkdirP(path.dirname(dest));
|
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
||||||
await pipeline(response.message, fs.createWriteStream(dest));
|
await pipeline(response.message, fs.createWriteStream(dest));
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
@@ -126,7 +121,7 @@ async function setupCodeQL() {
|
|||||||
// We only want to provide an authorization header if we are downloading
|
// We only want to provide an authorization header if we are downloading
|
||||||
// from the same GitHub instance the Action is running on.
|
// from the same GitHub instance the Action is running on.
|
||||||
// This avoids leaking Enterprise tokens to dotcom.
|
// This avoids leaking Enterprise tokens to dotcom.
|
||||||
if (codeqlURL.startsWith(getInstanceAPIURL() + "/")) {
|
if (codeqlURL.startsWith(util.getInstanceAPIURL() + "/")) {
|
||||||
core.debug('Downloading CodeQL bundle with token.');
|
core.debug('Downloading CodeQL bundle with token.');
|
||||||
let token = core.getInput('token', { required: true });
|
let token = core.getInput('token', { required: true });
|
||||||
headers.authorization = `token ${token}`;
|
headers.authorization = `token ${token}`;
|
||||||
@@ -325,4 +320,12 @@ function getCodeQLForCmd(cmd) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
function isTracedLanguage(language) {
|
||||||
|
return ['cpp', 'java', 'csharp'].includes(language);
|
||||||
|
}
|
||||||
|
exports.isTracedLanguage = isTracedLanguage;
|
||||||
|
function isScannedLanguage(language) {
|
||||||
|
return !isTracedLanguage(language);
|
||||||
|
}
|
||||||
|
exports.isScannedLanguage = isScannedLanguage;
|
||||||
//# sourceMappingURL=codeql.js.map
|
//# sourceMappingURL=codeql.js.map
|
||||||
File diff suppressed because one or more lines are too long
80
lib/config-utils.js
generated
80
lib/config-utils.js
generated
@@ -8,7 +8,6 @@ var __importStar = (this && this.__importStar) || 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 io = __importStar(require("@actions/io"));
|
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const yaml = __importStar(require("js-yaml"));
|
const yaml = __importStar(require("js-yaml"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
@@ -23,6 +22,13 @@ const QUERIES_PROPERTY = 'queries';
|
|||||||
const QUERIES_USES_PROPERTY = 'uses';
|
const QUERIES_USES_PROPERTY = 'uses';
|
||||||
const PATHS_IGNORE_PROPERTY = 'paths-ignore';
|
const PATHS_IGNORE_PROPERTY = 'paths-ignore';
|
||||||
const PATHS_PROPERTY = 'paths';
|
const PATHS_PROPERTY = 'paths';
|
||||||
|
// All the languages supported by CodeQL
|
||||||
|
const ALL_LANGUAGES = ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'];
|
||||||
|
// Some alternate names for languages
|
||||||
|
const LANGUAGE_ALIASES = {
|
||||||
|
'c': 'cpp',
|
||||||
|
'typescript': 'javascript',
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* A list of queries from https://github.com/github/codeql that
|
* A list of queries from https://github.com/github/codeql that
|
||||||
* we don't want to run. Disabling them here is a quicker alternative to
|
* we don't want to run. Disabling them here is a quicker alternative to
|
||||||
@@ -280,6 +286,15 @@ exports.getConfigFileDirectoryGivenMessage = getConfigFileDirectoryGivenMessage;
|
|||||||
function getConfigFilePropertyError(configFile, property, error) {
|
function getConfigFilePropertyError(configFile, property, error) {
|
||||||
return 'The configuration file "' + configFile + '" is invalid: property "' + property + '" ' + error;
|
return 'The configuration file "' + configFile + '" is invalid: property "' + property + '" ' + error;
|
||||||
}
|
}
|
||||||
|
function getNoLanguagesError() {
|
||||||
|
return "Did not detect any languages to analyze. " +
|
||||||
|
"Please update input in workflow or check that GitHub detects the correct languages in your repository.";
|
||||||
|
}
|
||||||
|
exports.getNoLanguagesError = getNoLanguagesError;
|
||||||
|
function getUnknownLanguagesError(languages) {
|
||||||
|
return "Did not recognise the following languages: " + languages.join(', ');
|
||||||
|
}
|
||||||
|
exports.getUnknownLanguagesError = getUnknownLanguagesError;
|
||||||
/**
|
/**
|
||||||
* Gets the set of languages in the current repository
|
* Gets the set of languages in the current repository
|
||||||
*/
|
*/
|
||||||
@@ -301,10 +316,10 @@ 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}`);
|
||||||
const response = await api.getApiClient().request("GET /repos/:owner/:repo/languages", ({
|
const response = await api.getApiClient(true).repos.listLanguages({
|
||||||
owner,
|
owner,
|
||||||
repo
|
repo
|
||||||
}));
|
});
|
||||||
core.debug("Languages API response: " + JSON.stringify(response));
|
core.debug("Languages API response: " + JSON.stringify(response));
|
||||||
// The GitHub API is going to return languages in order of popularity,
|
// The GitHub API is going to return languages in order of popularity,
|
||||||
// When we pick a language to autobuild we want to pick the most popular traced language
|
// When we pick a language to autobuild we want to pick the most popular traced language
|
||||||
@@ -328,6 +343,9 @@ async function getLanguagesInRepo() {
|
|||||||
* The result is obtained from the action input parameter 'languages' if that
|
* The result is obtained from the action input parameter 'languages' if that
|
||||||
* has been set, otherwise it is deduced as all languages in the repo that
|
* has been set, otherwise it is deduced as all languages in the repo that
|
||||||
* can be analysed.
|
* can be analysed.
|
||||||
|
*
|
||||||
|
* If no languages could be detected from either the workflow or the repository
|
||||||
|
* then throw an error.
|
||||||
*/
|
*/
|
||||||
async function getLanguages() {
|
async function getLanguages() {
|
||||||
// Obtain from action input 'languages' if set
|
// Obtain from action input 'languages' if set
|
||||||
@@ -341,7 +359,33 @@ async function getLanguages() {
|
|||||||
languages = await getLanguagesInRepo();
|
languages = await getLanguagesInRepo();
|
||||||
core.info("Automatically detected languages: " + JSON.stringify(languages));
|
core.info("Automatically detected languages: " + JSON.stringify(languages));
|
||||||
}
|
}
|
||||||
return languages;
|
// If the languages parameter was not given and no languages were
|
||||||
|
// detected then fail here as this is a workflow configuration error.
|
||||||
|
if (languages.length === 0) {
|
||||||
|
throw new Error(getNoLanguagesError());
|
||||||
|
}
|
||||||
|
// Make sure they are supported
|
||||||
|
const checkedLanguages = [];
|
||||||
|
const unknownLanguages = [];
|
||||||
|
for (let language of languages) {
|
||||||
|
// Normalise to lower case
|
||||||
|
language = language.toLowerCase();
|
||||||
|
// Resolve any known aliases
|
||||||
|
if (language in LANGUAGE_ALIASES) {
|
||||||
|
language = LANGUAGE_ALIASES[language];
|
||||||
|
}
|
||||||
|
const checkedLanguage = ALL_LANGUAGES.find(l => l === language);
|
||||||
|
if (checkedLanguage === undefined) {
|
||||||
|
unknownLanguages.push(language);
|
||||||
|
}
|
||||||
|
else if (checkedLanguages.indexOf(checkedLanguage) === -1) {
|
||||||
|
checkedLanguages.push(checkedLanguage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (unknownLanguages.length > 0) {
|
||||||
|
throw new Error(getUnknownLanguagesError(unknownLanguages));
|
||||||
|
}
|
||||||
|
return checkedLanguages;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get the default config for when the user has not supplied one.
|
* Get the default config for when the user has not supplied one.
|
||||||
@@ -384,11 +428,6 @@ async function loadConfig(configFile) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const languages = await getLanguages();
|
const languages = await getLanguages();
|
||||||
// If the languages parameter was not given and no languages were
|
|
||||||
// detected then fail here as this is a workflow configuration error.
|
|
||||||
if (languages.length === 0) {
|
|
||||||
throw new Error("Did not detect any languages to analyze. Please update input in workflow.");
|
|
||||||
}
|
|
||||||
const queries = {};
|
const queries = {};
|
||||||
const pathsIgnore = [];
|
const pathsIgnore = [];
|
||||||
const paths = [];
|
const paths = [];
|
||||||
@@ -435,6 +474,14 @@ async function loadConfig(configFile) {
|
|||||||
paths.push(validateAndSanitisePath(path, PATHS_PROPERTY, configFile));
|
paths.push(validateAndSanitisePath(path, PATHS_PROPERTY, configFile));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// The list of queries should not be empty for any language. If it is then
|
||||||
|
// it is a user configuration error.
|
||||||
|
for (const language of languages) {
|
||||||
|
if (queries[language] === undefined || queries[language].length === 0) {
|
||||||
|
throw new Error(`Did not detect any queries to run for ${language}. ` +
|
||||||
|
"Please make sure that the default queries are enabled, or you are specifying queries to run.");
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
languages,
|
languages,
|
||||||
queries,
|
queries,
|
||||||
@@ -491,7 +538,7 @@ async function getRemoteConfig(configFile) {
|
|||||||
if (pieces === null || pieces.groups === undefined || pieces.length < 5) {
|
if (pieces === null || pieces.groups === undefined || pieces.length < 5) {
|
||||||
throw new Error(getConfigFileRepoFormatInvalidMessage(configFile));
|
throw new Error(getConfigFileRepoFormatInvalidMessage(configFile));
|
||||||
}
|
}
|
||||||
const response = await api.getApiClient().repos.getContents({
|
const response = await api.getApiClient(true).repos.getContents({
|
||||||
owner: pieces.groups.owner,
|
owner: pieces.groups.owner,
|
||||||
repo: pieces.groups.repo,
|
repo: pieces.groups.repo,
|
||||||
path: pieces.groups.path,
|
path: pieces.groups.path,
|
||||||
@@ -509,17 +556,11 @@ async function getRemoteConfig(configFile) {
|
|||||||
}
|
}
|
||||||
return yaml.safeLoad(Buffer.from(fileContents, 'base64').toString('binary'));
|
return yaml.safeLoad(Buffer.from(fileContents, 'base64').toString('binary'));
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Get the directory where the parsed config will be stored.
|
|
||||||
*/
|
|
||||||
function getPathToParsedConfigFolder() {
|
|
||||||
return util.getRequiredEnvParam('RUNNER_TEMP');
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Get the file path where the parsed config will be stored.
|
* Get the file path where the parsed config will be stored.
|
||||||
*/
|
*/
|
||||||
function getPathToParsedConfigFile() {
|
function getPathToParsedConfigFile() {
|
||||||
return path.join(getPathToParsedConfigFolder(), 'config');
|
return path.join(util.getRequiredEnvParam('RUNNER_TEMP'), 'config');
|
||||||
}
|
}
|
||||||
exports.getPathToParsedConfigFile = getPathToParsedConfigFile;
|
exports.getPathToParsedConfigFile = getPathToParsedConfigFile;
|
||||||
/**
|
/**
|
||||||
@@ -527,8 +568,9 @@ exports.getPathToParsedConfigFile = getPathToParsedConfigFile;
|
|||||||
*/
|
*/
|
||||||
async function saveConfig(config) {
|
async function saveConfig(config) {
|
||||||
const configString = JSON.stringify(config);
|
const configString = JSON.stringify(config);
|
||||||
await io.mkdirP(getPathToParsedConfigFolder());
|
const configFile = getPathToParsedConfigFile();
|
||||||
fs.writeFileSync(getPathToParsedConfigFile(), configString, 'utf8');
|
fs.mkdirSync(path.dirname(configFile), { recursive: true });
|
||||||
|
fs.writeFileSync(configFile, configString, 'utf8');
|
||||||
core.debug('Saved config:');
|
core.debug('Saved config:');
|
||||||
core.debug(configString);
|
core.debug(configString);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
50
lib/config-utils.test.js
generated
50
lib/config-utils.test.js
generated
@@ -42,6 +42,18 @@ function mockGetContents(content) {
|
|||||||
sinon_1.default.stub(api, "getApiClient").value(() => client);
|
sinon_1.default.stub(api, "getApiClient").value(() => client);
|
||||||
return spyGetContents;
|
return spyGetContents;
|
||||||
}
|
}
|
||||||
|
function mockListLanguages(languages) {
|
||||||
|
// Passing an auth token is required, so we just use a dummy value
|
||||||
|
let client = new github.GitHub('123');
|
||||||
|
const response = {
|
||||||
|
data: {},
|
||||||
|
};
|
||||||
|
for (const language of languages) {
|
||||||
|
response.data[language] = 123;
|
||||||
|
}
|
||||||
|
sinon_1.default.stub(client.repos, "listLanguages").resolves(response);
|
||||||
|
sinon_1.default.stub(api, "getApiClient").value(() => client);
|
||||||
|
}
|
||||||
ava_1.default("load empty config", async (t) => {
|
ava_1.default("load empty config", async (t) => {
|
||||||
return await util.withTmpDir(async (tmpDir) => {
|
return await util.withTmpDir(async (tmpDir) => {
|
||||||
process.env['RUNNER_TEMP'] = tmpDir;
|
process.env['RUNNER_TEMP'] = tmpDir;
|
||||||
@@ -200,7 +212,9 @@ ava_1.default("default queries are used", async (t) => {
|
|||||||
resolveQueriesArgs.push({ queries, extraSearchPath });
|
resolveQueriesArgs.push({ queries, extraSearchPath });
|
||||||
return {
|
return {
|
||||||
byLanguage: {
|
byLanguage: {
|
||||||
'javascript': {},
|
'javascript': {
|
||||||
|
'foo.ql': {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
noDeclaredLanguage: {},
|
noDeclaredLanguage: {},
|
||||||
multipleDeclaredLanguages: {},
|
multipleDeclaredLanguages: {},
|
||||||
@@ -231,7 +245,11 @@ ava_1.default("API client used when reading remote config", async (t) => {
|
|||||||
CodeQL.setCodeQL({
|
CodeQL.setCodeQL({
|
||||||
resolveQueries: async function () {
|
resolveQueries: async function () {
|
||||||
return {
|
return {
|
||||||
byLanguage: {},
|
byLanguage: {
|
||||||
|
'javascript': {
|
||||||
|
'foo.ql': {},
|
||||||
|
},
|
||||||
|
},
|
||||||
noDeclaredLanguage: {},
|
noDeclaredLanguage: {},
|
||||||
multipleDeclaredLanguages: {},
|
multipleDeclaredLanguages: {},
|
||||||
};
|
};
|
||||||
@@ -297,6 +315,34 @@ ava_1.default("Invalid format of remote config handled correctly", async (t) =>
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
ava_1.default("No detected languages", async (t) => {
|
||||||
|
return await util.withTmpDir(async (tmpDir) => {
|
||||||
|
process.env['RUNNER_TEMP'] = tmpDir;
|
||||||
|
process.env['GITHUB_WORKSPACE'] = tmpDir;
|
||||||
|
mockListLanguages([]);
|
||||||
|
try {
|
||||||
|
await configUtils.initConfig();
|
||||||
|
throw new Error('initConfig did not throw error');
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
t.deepEqual(err, new Error(configUtils.getNoLanguagesError()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
ava_1.default("Unknown languages", async (t) => {
|
||||||
|
return await util.withTmpDir(async (tmpDir) => {
|
||||||
|
process.env['RUNNER_TEMP'] = tmpDir;
|
||||||
|
process.env['GITHUB_WORKSPACE'] = tmpDir;
|
||||||
|
setInput('languages', 'ruby,english');
|
||||||
|
try {
|
||||||
|
await configUtils.initConfig();
|
||||||
|
throw new Error('initConfig did not throw error');
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
t.deepEqual(err, new Error(configUtils.getUnknownLanguagesError(['ruby', 'english'])));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGenerator) {
|
function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGenerator) {
|
||||||
ava_1.default("load invalid input - " + testName, async (t) => {
|
ava_1.default("load invalid input - " + testName, async (t) => {
|
||||||
return await util.withTmpDir(async (tmpDir) => {
|
return await util.withTmpDir(async (tmpDir) => {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
21
lib/finalize-db.js
generated
21
lib/finalize-db.js
generated
@@ -8,7 +8,6 @@ var __importStar = (this && this.__importStar) || 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 io = __importStar(require("@actions/io"));
|
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
const codeql_1 = require("./codeql");
|
const codeql_1 = require("./codeql");
|
||||||
@@ -27,11 +26,10 @@ async function sendStatusReport(startedAt, queriesStats, uploadStats, error) {
|
|||||||
};
|
};
|
||||||
await util.sendStatusReport(statusReport);
|
await util.sendStatusReport(statusReport);
|
||||||
}
|
}
|
||||||
async function createdDBForScannedLanguages(databaseFolder) {
|
async function createdDBForScannedLanguages(databaseFolder, config) {
|
||||||
const scannedLanguages = process.env[sharedEnv.CODEQL_ACTION_SCANNED_LANGUAGES];
|
const codeql = codeql_1.getCodeQL();
|
||||||
if (scannedLanguages) {
|
for (const language of config.languages) {
|
||||||
const codeql = codeql_1.getCodeQL();
|
if (codeql_1.isScannedLanguage(language)) {
|
||||||
for (const language of scannedLanguages.split(',')) {
|
|
||||||
core.startGroup('Extracting ' + language);
|
core.startGroup('Extracting ' + language);
|
||||||
await codeql.extractScannedLanguage(path.join(databaseFolder, language), language);
|
await codeql.extractScannedLanguage(path.join(databaseFolder, language), language);
|
||||||
core.endGroup();
|
core.endGroup();
|
||||||
@@ -39,7 +37,7 @@ async function createdDBForScannedLanguages(databaseFolder) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function finalizeDatabaseCreation(databaseFolder, config) {
|
async function finalizeDatabaseCreation(databaseFolder, config) {
|
||||||
await createdDBForScannedLanguages(databaseFolder);
|
await createdDBForScannedLanguages(databaseFolder, config);
|
||||||
const codeql = codeql_1.getCodeQL();
|
const codeql = codeql_1.getCodeQL();
|
||||||
for (const language of config.languages) {
|
for (const language of config.languages) {
|
||||||
core.startGroup('Finalizing ' + language);
|
core.startGroup('Finalizing ' + language);
|
||||||
@@ -82,16 +80,16 @@ async function run() {
|
|||||||
let queriesStats = undefined;
|
let queriesStats = undefined;
|
||||||
let uploadStats = undefined;
|
let uploadStats = undefined;
|
||||||
try {
|
try {
|
||||||
if (util.should_abort('finish', true) ||
|
util.prepareLocalRunEnvironment();
|
||||||
!await util.sendStatusReport(await util.createStatusReportBase('finish', 'starting', startedAt), true)) {
|
if (!await util.sendStatusReport(await util.createStatusReportBase('finish', 'starting', startedAt), true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const config = await configUtils.getConfig();
|
const config = await configUtils.getConfig();
|
||||||
core.exportVariable(sharedEnv.ODASA_TRACER_CONFIGURATION, '');
|
core.exportVariable(sharedEnv.ODASA_TRACER_CONFIGURATION, '');
|
||||||
delete process.env[sharedEnv.ODASA_TRACER_CONFIGURATION];
|
delete process.env[sharedEnv.ODASA_TRACER_CONFIGURATION];
|
||||||
const databaseFolder = util.getRequiredEnvParam(sharedEnv.CODEQL_ACTION_DATABASE_DIR);
|
const databaseFolder = util.getCodeQLDatabasesDir();
|
||||||
const sarifFolder = core.getInput('output');
|
const sarifFolder = core.getInput('output');
|
||||||
await io.mkdirP(sarifFolder);
|
fs.mkdirSync(sarifFolder, { recursive: true });
|
||||||
core.info('Finalizing database creation');
|
core.info('Finalizing database creation');
|
||||||
await finalizeDatabaseCreation(databaseFolder, config);
|
await finalizeDatabaseCreation(databaseFolder, config);
|
||||||
core.info('Analyzing database');
|
core.info('Analyzing database');
|
||||||
@@ -102,6 +100,7 @@ async function run() {
|
|||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
|
console.log(error);
|
||||||
await sendStatusReport(startedAt, queriesStats, uploadStats, error);
|
await sendStatusReport(startedAt, queriesStats, uploadStats, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"finalize-db.js","sourceRoot":"","sources":["../src/finalize-db.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"finalize-db.js","sourceRoot":"","sources":["../src/finalize-db.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AACtC,uCAAyB;AACzB,2CAA6B;AAE7B,qCAAwD;AACxD,4DAA8C;AAC9C,gEAAkD;AAClD,yDAA2C;AAC3C,6CAA+B;AAiC/B,KAAK,UAAU,gBAAgB,CAC7B,SAAe,EACf,YAA6C,EAC7C,WAAsD,EACtD,KAAa;;IAEb,MAAM,MAAM,GAAG,OAAA,YAAY,0CAAE,wBAAwB,MAAK,SAAS,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IACnH,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,QAAE,KAAK,0CAAE,OAAO,QAAE,KAAK,0CAAE,KAAK,CAAC,CAAC;IACtH,MAAM,YAAY,GAAuB;QACvC,GAAG,gBAAgB;QACnB,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;QACvB,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;KACvB,CAAC;IACF,MAAM,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;AAC5C,CAAC;AAED,KAAK,UAAU,4BAA4B,CAAC,cAAsB,EAAE,MAA0B;IAC5F,MAAM,MAAM,GAAG,kBAAS,EAAE,CAAC;IAC3B,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE;QACvC,IAAI,0BAAiB,CAAC,QAAQ,CAAC,EAAE;YAC/B,IAAI,CAAC,UAAU,CAAC,aAAa,GAAG,QAAQ,CAAC,CAAC;YAC1C,MAAM,MAAM,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;YACnF,IAAI,CAAC,QAAQ,EAAE,CAAC;SACjB;KACF;AACH,CAAC;AAED,KAAK,UAAU,wBAAwB,CAAC,cAAsB,EAAE,MAA0B;IACxF,MAAM,4BAA4B,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAE3D,MAAM,MAAM,GAAG,kBAAS,EAAE,CAAC;IAC3B,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE;QACvC,IAAI,CAAC,UAAU,CAAC,aAAa,GAAG,QAAQ,CAAC,CAAC;QAC1C,MAAM,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC;QACnE,IAAI,CAAC,QAAQ,EAAE,CAAC;KACjB;AACH,CAAC;AAED,2DAA2D;AAC3D,KAAK,UAAU,UAAU,CACvB,cAAsB,EACtB,WAAmB,EACnB,MAA0B;IAE1B,MAAM,MAAM,GAAG,kBAAS,EAAE,CAAC;IAC3B,KAAK,IAAI,QAAQ,IAAI,EAAE,CAAC,WAAW,CAAC,cAAc,CAAC,EAAE;QACnD,IAAI,CAAC,UAAU,CAAC,YAAY,GAAG,QAAQ,CAAC,CAAC;QAEzC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC/C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;YACxB,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,QAAQ,GAAG,gDAAgD,CAAC,CAAC;SACrG;QAED,IAAI;YACF,uEAAuE;YACvE,2EAA2E;YAC3E,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,cAAc,CAAC,CAAC;YACxE,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxE,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;YACjD,IAAI,CAAC,KAAK,CAAC,uBAAuB,GAAG,QAAQ,GAAG,OAAO,GAAG,kBAAkB,CAAC,CAAC;YAE9E,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,GAAG,QAAQ,CAAC,CAAC;YAE9D,MAAM,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;YAEzF,IAAI,CAAC,KAAK,CAAC,6BAA6B,GAAG,QAAQ,GAAG,eAAe,GAAG,SAAS,GAAG,GAAG,CAAC,CAAC;YACzF,IAAI,CAAC,QAAQ,EAAE,CAAC;SAEjB;QAAC,OAAO,CAAC,EAAE;YACV,+DAA+D;YAC/D,OAAO;gBACL,wBAAwB,EAAE,QAAQ;aACnC,CAAC;SACH;KACF;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,IAAI,YAAY,GAAoC,SAAS,CAAC;IAC9D,IAAI,WAAW,GAA8C,SAAS,CAAC;IACvE,IAAI;QACF,IAAI,CAAC,0BAA0B,EAAE,CAAC;QAClC,IAAI,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,IAAI,CAAC,sBAAsB,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC,EAAE;YAC1G,OAAO;SACR;QACD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,SAAS,EAAE,CAAC;QAE7C,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,0BAA0B,EAAE,EAAE,CAAC,CAAC;QAC9D,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;QAEzD,MAAM,cAAc,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAEpD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC5C,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE/C,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QAC1C,MAAM,wBAAwB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QAEvD,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAChC,YAAY,GAAG,MAAM,UAAU,CAAC,cAAc,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;QAErE,IAAI,MAAM,KAAK,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;YACtC,WAAW,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;SACpD;KAEF;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,gBAAgB,CAAC,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;QACpE,OAAO;KACR;IAED,MAAM,gBAAgB,CAAC,SAAS,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;AAC/D,CAAC;AAED,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACd,IAAI,CAAC,SAAS,CAAC,yBAAyB,GAAG,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
|
||||||
34
lib/setup-tracer.js
generated
34
lib/setup-tracer.js
generated
@@ -9,13 +9,11 @@ var __importStar = (this && this.__importStar) || 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 exec = __importStar(require("@actions/exec"));
|
const exec = __importStar(require("@actions/exec"));
|
||||||
const io = __importStar(require("@actions/io"));
|
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
const analysisPaths = __importStar(require("./analysis-paths"));
|
const analysisPaths = __importStar(require("./analysis-paths"));
|
||||||
const codeql_1 = require("./codeql");
|
const codeql_1 = require("./codeql");
|
||||||
const configUtils = __importStar(require("./config-utils"));
|
const configUtils = __importStar(require("./config-utils"));
|
||||||
const sharedEnv = __importStar(require("./shared-environment"));
|
|
||||||
const util = __importStar(require("./util"));
|
const util = __importStar(require("./util"));
|
||||||
const CRITICAL_TRACER_VARS = new Set(['SEMMLE_PRELOAD_libtrace',
|
const CRITICAL_TRACER_VARS = new Set(['SEMMLE_PRELOAD_libtrace',
|
||||||
,
|
,
|
||||||
@@ -58,7 +56,7 @@ function concatTracerConfigs(configs) {
|
|||||||
const env = {};
|
const env = {};
|
||||||
let copyExecutables = false;
|
let copyExecutables = false;
|
||||||
let envSize = 0;
|
let envSize = 0;
|
||||||
for (let v of Object.values(configs)) {
|
for (const v of configs) {
|
||||||
for (let e of Object.entries(v.env)) {
|
for (let e of Object.entries(v.env)) {
|
||||||
const name = e[0];
|
const name = e[0];
|
||||||
const value = e[1];
|
const value = e[1];
|
||||||
@@ -145,8 +143,8 @@ async function run() {
|
|||||||
let config;
|
let config;
|
||||||
let codeql;
|
let codeql;
|
||||||
try {
|
try {
|
||||||
if (util.should_abort('init', false) ||
|
util.prepareLocalRunEnvironment();
|
||||||
!await util.sendStatusReport(await util.createStatusReportBase('init', 'starting', startedAt), true)) {
|
if (!await util.sendStatusReport(await util.createStatusReportBase('init', 'starting', startedAt), true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
core.startGroup('Setup CodeQL tools');
|
core.startGroup('Setup CodeQL tools');
|
||||||
@@ -160,6 +158,7 @@ async function run() {
|
|||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
core.setFailed(e.message);
|
core.setFailed(e.message);
|
||||||
|
console.log(e);
|
||||||
await util.sendStatusReport(await util.createStatusReportBase('init', 'aborted', startedAt, e.message));
|
await util.sendStatusReport(await util.createStatusReportBase('init', 'aborted', startedAt, e.message));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -174,27 +173,22 @@ async function run() {
|
|||||||
// Setup CODEQL_RAM flag (todo improve this https://github.com/github/dsp-code-scanning/issues/935)
|
// Setup CODEQL_RAM flag (todo improve this https://github.com/github/dsp-code-scanning/issues/935)
|
||||||
const codeqlRam = process.env['CODEQL_RAM'] || '6500';
|
const codeqlRam = process.env['CODEQL_RAM'] || '6500';
|
||||||
core.exportVariable('CODEQL_RAM', codeqlRam);
|
core.exportVariable('CODEQL_RAM', codeqlRam);
|
||||||
const databaseFolder = path.resolve(util.getRequiredEnvParam('RUNNER_TEMP'), 'codeql_databases');
|
const databaseFolder = util.getCodeQLDatabasesDir();
|
||||||
await io.mkdirP(databaseFolder);
|
fs.mkdirSync(databaseFolder, { recursive: true });
|
||||||
let tracedLanguages = {};
|
let tracedLanguageConfigs = [];
|
||||||
let scannedLanguages = [];
|
|
||||||
// TODO: replace this code once CodeQL supports multi-language tracing
|
// TODO: replace this code once CodeQL supports multi-language tracing
|
||||||
for (let language of config.languages) {
|
for (let language of config.languages) {
|
||||||
const languageDatabase = path.join(databaseFolder, language);
|
const languageDatabase = path.join(databaseFolder, language);
|
||||||
// Init language database
|
// Init language database
|
||||||
await codeql.databaseInit(languageDatabase, language, sourceRoot);
|
await codeql.databaseInit(languageDatabase, language, sourceRoot);
|
||||||
// TODO: add better detection of 'traced languages' instead of using a hard coded list
|
// TODO: add better detection of 'traced languages' instead of using a hard coded list
|
||||||
if (['cpp', 'java', 'csharp'].includes(language)) {
|
if (codeql_1.isTracedLanguage(language)) {
|
||||||
const config = await tracerConfig(codeql, languageDatabase);
|
const config = await tracerConfig(codeql, languageDatabase);
|
||||||
tracedLanguages[language] = config;
|
tracedLanguageConfigs.push(config);
|
||||||
}
|
|
||||||
else {
|
|
||||||
scannedLanguages.push(language);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const tracedLanguageKeys = Object.keys(tracedLanguages);
|
if (tracedLanguageConfigs.length > 0) {
|
||||||
if (tracedLanguageKeys.length > 0) {
|
const mainTracerConfig = concatTracerConfigs(tracedLanguageConfigs);
|
||||||
const mainTracerConfig = concatTracerConfigs(tracedLanguages);
|
|
||||||
if (mainTracerConfig.spec) {
|
if (mainTracerConfig.spec) {
|
||||||
for (let entry of Object.entries(mainTracerConfig.env)) {
|
for (let entry of Object.entries(mainTracerConfig.env)) {
|
||||||
core.exportVariable(entry[0], entry[1]);
|
core.exportVariable(entry[0], entry[1]);
|
||||||
@@ -214,18 +208,14 @@ async function run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
core.exportVariable(sharedEnv.CODEQL_ACTION_SCANNED_LANGUAGES, scannedLanguages.join(','));
|
|
||||||
core.exportVariable(sharedEnv.CODEQL_ACTION_TRACED_LANGUAGES, tracedLanguageKeys.join(','));
|
|
||||||
// TODO: make this a "private" environment variable of the action
|
|
||||||
core.exportVariable(sharedEnv.CODEQL_ACTION_DATABASE_DIR, databaseFolder);
|
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
|
console.log(error);
|
||||||
await util.sendStatusReport(await util.createStatusReportBase('init', 'failure', startedAt, error.message, error.stack));
|
await util.sendStatusReport(await util.createStatusReportBase('init', 'failure', startedAt, error.message, error.stack));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await sendSuccessStatusReport(startedAt, config);
|
await sendSuccessStatusReport(startedAt, config);
|
||||||
core.exportVariable(sharedEnv.CODEQL_ACTION_INIT_COMPLETED, 'true');
|
|
||||||
}
|
}
|
||||||
run().catch(e => {
|
run().catch(e => {
|
||||||
core.setFailed("init action failed: " + e);
|
core.setFailed("init action failed: " + e);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
6
lib/shared-environment.js
generated
6
lib/shared-environment.js
generated
@@ -1,16 +1,10 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.CODEQL_ACTION_DATABASE_DIR = 'CODEQL_ACTION_DATABASE_DIR';
|
|
||||||
exports.CODEQL_ACTION_ANALYSIS_KEY = 'CODEQL_ACTION_ANALYSIS_KEY';
|
|
||||||
exports.ODASA_TRACER_CONFIGURATION = 'ODASA_TRACER_CONFIGURATION';
|
exports.ODASA_TRACER_CONFIGURATION = 'ODASA_TRACER_CONFIGURATION';
|
||||||
exports.CODEQL_ACTION_SCANNED_LANGUAGES = 'CODEQL_ACTION_SCANNED_LANGUAGES';
|
|
||||||
exports.CODEQL_ACTION_TRACED_LANGUAGES = 'CODEQL_ACTION_TRACED_LANGUAGES';
|
|
||||||
// The time at which the first action (normally init) started executing.
|
// The time at which the first action (normally init) started executing.
|
||||||
// If a workflow invokes a different action without first invoking the init
|
// If a workflow invokes a different action without first invoking the init
|
||||||
// action (i.e. the upload action is being used by a third-party integrator)
|
// action (i.e. the upload action is being used by a third-party integrator)
|
||||||
// then this variable will be assigned the start time of the action invoked
|
// then this variable will be assigned the start time of the action invoked
|
||||||
// rather that the init action.
|
// rather that the init action.
|
||||||
exports.CODEQL_WORKFLOW_STARTED_AT = 'CODEQL_WORKFLOW_STARTED_AT';
|
exports.CODEQL_WORKFLOW_STARTED_AT = 'CODEQL_WORKFLOW_STARTED_AT';
|
||||||
// Populated when the init action completes successfully
|
|
||||||
exports.CODEQL_ACTION_INIT_COMPLETED = 'CODEQL_ACTION_INIT_COMPLETED';
|
|
||||||
//# sourceMappingURL=shared-environment.js.map
|
//# sourceMappingURL=shared-environment.js.map
|
||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"shared-environment.js","sourceRoot":"","sources":["../src/shared-environment.ts"],"names":[],"mappings":";;AAAa,QAAA,0BAA0B,GAAG,4BAA4B,CAAC;AAC1D,QAAA,0BAA0B,GAAG,4BAA4B,CAAC;AAC1D,QAAA,0BAA0B,GAAG,4BAA4B,CAAC;AAC1D,QAAA,+BAA+B,GAAG,iCAAiC,CAAC;AACpE,QAAA,8BAA8B,GAAG,gCAAgC,CAAC;AAC/E,wEAAwE;AACxE,2EAA2E;AAC3E,4EAA4E;AAC5E,2EAA2E;AAC3E,+BAA+B;AAClB,QAAA,0BAA0B,GAAG,4BAA4B,CAAC;AACvE,wDAAwD;AAC3C,QAAA,4BAA4B,GAAG,8BAA8B,CAAC"}
|
{"version":3,"file":"shared-environment.js","sourceRoot":"","sources":["../src/shared-environment.ts"],"names":[],"mappings":";;AAAa,QAAA,0BAA0B,GAAG,4BAA4B,CAAC;AACvE,wEAAwE;AACxE,2EAA2E;AAC3E,4EAA4E;AAC5E,2EAA2E;AAC3E,+BAA+B;AAClB,QAAA,0BAA0B,GAAG,4BAA4B,CAAC"}
|
||||||
9
lib/upload-lib.js
generated
9
lib/upload-lib.js
generated
@@ -194,8 +194,13 @@ async function uploadFiles(sarifFiles) {
|
|||||||
core.debug("Base64 zipped upload size: " + zippedUploadSizeBytes + " bytes");
|
core.debug("Base64 zipped upload size: " + zippedUploadSizeBytes + " bytes");
|
||||||
const numResultInSarif = countResultsInSarif(sarifPayload);
|
const numResultInSarif = countResultsInSarif(sarifPayload);
|
||||||
core.debug("Number of results in upload: " + numResultInSarif);
|
core.debug("Number of results in upload: " + numResultInSarif);
|
||||||
// Make the upload
|
if (!util.isLocalRun()) {
|
||||||
await uploadPayload(payload);
|
// Make the upload
|
||||||
|
await uploadPayload(payload);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
core.debug("Not uploading because this is a local run.");
|
||||||
|
}
|
||||||
core.endGroup();
|
core.endGroup();
|
||||||
return {
|
return {
|
||||||
raw_upload_size_bytes: rawUploadSizeBytes,
|
raw_upload_size_bytes: rawUploadSizeBytes,
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
4
lib/upload-sarif.js
generated
4
lib/upload-sarif.js
generated
@@ -20,8 +20,7 @@ async function sendSuccessStatusReport(startedAt, uploadStats) {
|
|||||||
}
|
}
|
||||||
async function run() {
|
async function run() {
|
||||||
const startedAt = new Date();
|
const startedAt = new Date();
|
||||||
if (util.should_abort('upload-sarif', false) ||
|
if (!await util.sendStatusReport(await util.createStatusReportBase('upload-sarif', 'starting', startedAt), true)) {
|
||||||
!await util.sendStatusReport(await util.createStatusReportBase('upload-sarif', 'starting', startedAt), true)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -30,6 +29,7 @@ async function run() {
|
|||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
|
console.log(error);
|
||||||
await util.sendStatusReport(await util.createStatusReportBase('upload-sarif', 'failure', startedAt, error.message, error.stack));
|
await util.sendStatusReport(await util.createStatusReportBase('upload-sarif', 'failure', startedAt, error.message, error.stack));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"upload-sarif.js","sourceRoot":"","sources":["../src/upload-sarif.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AAEtC,yDAA2C;AAC3C,6CAA+B;AAI/B,KAAK,UAAU,uBAAuB,CAAC,SAAe,EAAE,WAA0C;IAChG,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,cAAc,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IACjG,MAAM,YAAY,GAA4B;QAC5C,GAAG,gBAAgB;QACnB,GAAI,WAAW;KAChB,CAAC;IACF,MAAM,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;AAC5C,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,IAAI,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,KAAK,CAAC;QACxC,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,IAAI,CAAC,sBAAsB,CAAC,cAAc,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC,EAAE;QAChH,OAAO;KACR;IAED,IAAI;QACF,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;QACzE,MAAM,uBAAuB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;KAEvD;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,IAAI,CAAC,sBAAsB,CAC3D,cAAc,EACd,SAAS,EACT,SAAS,EACT,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QAChB,OAAO;KACR;AACH,CAAC;AAED,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACd,IAAI,CAAC,SAAS,CAAC,qCAAqC,GAAG,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
|
{"version":3,"file":"upload-sarif.js","sourceRoot":"","sources":["../src/upload-sarif.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AAEtC,yDAA2C;AAC3C,6CAA+B;AAI/B,KAAK,UAAU,uBAAuB,CAAC,SAAe,EAAE,WAA0C;IAChG,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,cAAc,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IACjG,MAAM,YAAY,GAA4B;QAC5C,GAAG,gBAAgB;QACnB,GAAI,WAAW;KAChB,CAAC;IACF,MAAM,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;AAC5C,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,IAAI,CAAC,sBAAsB,CAAC,cAAc,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC,EAAE;QAChH,OAAO;KACR;IAED,IAAI;QACF,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;QACzE,MAAM,uBAAuB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;KAEvD;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,IAAI,CAAC,sBAAsB,CAC3D,cAAc,EACd,SAAS,EACT,SAAS,EACT,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QAChB,OAAO;KACR;AACH,CAAC;AAED,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACd,IAAI,CAAC,SAAS,CAAC,qCAAqC,GAAG,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
|
||||||
79
lib/util.js
generated
79
lib/util.js
generated
@@ -15,27 +15,24 @@ const path = __importStar(require("path"));
|
|||||||
const api = __importStar(require("./api-client"));
|
const api = __importStar(require("./api-client"));
|
||||||
const sharedEnv = __importStar(require("./shared-environment"));
|
const sharedEnv = __importStar(require("./shared-environment"));
|
||||||
/**
|
/**
|
||||||
* Should the current action be aborted?
|
* The API URL for github.com.
|
||||||
*
|
|
||||||
* This method should be called at the start of all CodeQL actions and they
|
|
||||||
* should abort cleanly if this returns true without failing the action.
|
|
||||||
* This method will call `core.setFailed` if necessary.
|
|
||||||
*/
|
*/
|
||||||
function should_abort(actionName, requireInitActionHasRun) {
|
exports.GITHUB_DOTCOM_API_URL = "https://api.github.com";
|
||||||
// Check that required aspects of the environment are present
|
/**
|
||||||
const ref = process.env['GITHUB_REF'];
|
* Get the API URL for the GitHub instance we are connected to.
|
||||||
if (ref === undefined) {
|
* May be for github.com or for an enterprise instance.
|
||||||
core.setFailed('GITHUB_REF must be set.');
|
*/
|
||||||
return true;
|
function getInstanceAPIURL() {
|
||||||
}
|
return process.env["GITHUB_API_URL"] || exports.GITHUB_DOTCOM_API_URL;
|
||||||
// If the init action is required, then check the it completed successfully.
|
|
||||||
if (requireInitActionHasRun && process.env[sharedEnv.CODEQL_ACTION_INIT_COMPLETED] === undefined) {
|
|
||||||
core.setFailed('The CodeQL ' + actionName + ' action cannot be used unless the CodeQL init action is run first. Aborting.');
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
exports.should_abort = should_abort;
|
exports.getInstanceAPIURL = getInstanceAPIURL;
|
||||||
|
/**
|
||||||
|
* Are we running against a GitHub Enterpise instance, as opposed to github.com.
|
||||||
|
*/
|
||||||
|
function isEnterprise() {
|
||||||
|
return getInstanceAPIURL() !== exports.GITHUB_DOTCOM_API_URL;
|
||||||
|
}
|
||||||
|
exports.isEnterprise = isEnterprise;
|
||||||
/**
|
/**
|
||||||
* Get an environment parameter, but throw an error if it is not set.
|
* Get an environment parameter, but throw an error if it is not set.
|
||||||
*/
|
*/
|
||||||
@@ -48,6 +45,25 @@ function getRequiredEnvParam(paramName) {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
exports.getRequiredEnvParam = getRequiredEnvParam;
|
exports.getRequiredEnvParam = getRequiredEnvParam;
|
||||||
|
function isLocalRun() {
|
||||||
|
return !!process.env.CODEQL_LOCAL_RUN
|
||||||
|
&& process.env.CODEQL_LOCAL_RUN !== 'false'
|
||||||
|
&& process.env.CODEQL_LOCAL_RUN !== '0';
|
||||||
|
}
|
||||||
|
exports.isLocalRun = isLocalRun;
|
||||||
|
/**
|
||||||
|
* Ensures all required environment variables are set in the context of a local run.
|
||||||
|
*/
|
||||||
|
function prepareLocalRunEnvironment() {
|
||||||
|
if (!isLocalRun()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
core.debug('Action is running locally.');
|
||||||
|
if (!process.env.GITHUB_JOB) {
|
||||||
|
core.exportVariable('GITHUB_JOB', 'UNKNOWN-JOB');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.prepareLocalRunEnvironment = prepareLocalRunEnvironment;
|
||||||
/**
|
/**
|
||||||
* Gets the SHA of the commit that is currently checked out.
|
* Gets the SHA of the commit that is currently checked out.
|
||||||
*/
|
*/
|
||||||
@@ -80,6 +96,9 @@ exports.getCommitOid = getCommitOid;
|
|||||||
* Get the path of the currently executing workflow.
|
* Get the path of the currently executing workflow.
|
||||||
*/
|
*/
|
||||||
async function getWorkflowPath() {
|
async function getWorkflowPath() {
|
||||||
|
if (isLocalRun()) {
|
||||||
|
return 'LOCAL';
|
||||||
|
}
|
||||||
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];
|
||||||
@@ -102,14 +121,15 @@ async function getWorkflowPath() {
|
|||||||
* the github API, but after that the result will be cached.
|
* the github API, but after that the result will be cached.
|
||||||
*/
|
*/
|
||||||
async function getAnalysisKey() {
|
async function getAnalysisKey() {
|
||||||
let analysisKey = process.env[sharedEnv.CODEQL_ACTION_ANALYSIS_KEY];
|
const analysisKeyEnvVar = 'CODEQL_ACTION_ANALYSIS_KEY';
|
||||||
|
let analysisKey = process.env[analysisKeyEnvVar];
|
||||||
if (analysisKey !== undefined) {
|
if (analysisKey !== undefined) {
|
||||||
return analysisKey;
|
return analysisKey;
|
||||||
}
|
}
|
||||||
const workflowPath = await getWorkflowPath();
|
const workflowPath = await getWorkflowPath();
|
||||||
const jobName = getRequiredEnvParam('GITHUB_JOB');
|
const jobName = getRequiredEnvParam('GITHUB_JOB');
|
||||||
analysisKey = workflowPath + ':' + jobName;
|
analysisKey = workflowPath + ':' + jobName;
|
||||||
core.exportVariable(sharedEnv.CODEQL_ACTION_ANALYSIS_KEY, analysisKey);
|
core.exportVariable(analysisKeyEnvVar, analysisKey);
|
||||||
return analysisKey;
|
return analysisKey;
|
||||||
}
|
}
|
||||||
exports.getAnalysisKey = getAnalysisKey;
|
exports.getAnalysisKey = getAnalysisKey;
|
||||||
@@ -183,7 +203,7 @@ async function createStatusReportBase(actionName, status, actionStartedAt, cause
|
|||||||
}
|
}
|
||||||
let matrix = core.getInput('matrix');
|
let matrix = core.getInput('matrix');
|
||||||
if (matrix) {
|
if (matrix) {
|
||||||
// Temporarily do nothing.
|
statusReport.matrix_vars = matrix;
|
||||||
}
|
}
|
||||||
return statusReport;
|
return statusReport;
|
||||||
}
|
}
|
||||||
@@ -198,6 +218,14 @@ exports.createStatusReportBase = createStatusReportBase;
|
|||||||
* Returns whether sending the status report was successful of not.
|
* Returns whether sending the status report was successful of not.
|
||||||
*/
|
*/
|
||||||
async function sendStatusReport(statusReport, ignoreFailures) {
|
async function sendStatusReport(statusReport, ignoreFailures) {
|
||||||
|
if (isEnterprise()) {
|
||||||
|
core.debug("Not sending status report to GitHub Enterprise");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (isLocalRun()) {
|
||||||
|
core.debug("Not sending status report because this is a local run");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
const statusReportJSON = JSON.stringify(statusReport);
|
const statusReportJSON = JSON.stringify(statusReport);
|
||||||
core.debug('Sending status report: ' + statusReportJSON);
|
core.debug('Sending status report: ' + statusReportJSON);
|
||||||
const nwo = getRequiredEnvParam("GITHUB_REPOSITORY");
|
const nwo = getRequiredEnvParam("GITHUB_REPOSITORY");
|
||||||
@@ -307,4 +335,11 @@ function getThreadsFlag() {
|
|||||||
return `--threads=${numThreads}`;
|
return `--threads=${numThreads}`;
|
||||||
}
|
}
|
||||||
exports.getThreadsFlag = getThreadsFlag;
|
exports.getThreadsFlag = getThreadsFlag;
|
||||||
|
/**
|
||||||
|
* Get the directory where CodeQL databases should be placed.
|
||||||
|
*/
|
||||||
|
function getCodeQLDatabasesDir() {
|
||||||
|
return path.resolve(getRequiredEnvParam('RUNNER_TEMP'), 'codeql_databases');
|
||||||
|
}
|
||||||
|
exports.getCodeQLDatabasesDir = getCodeQLDatabasesDir;
|
||||||
//# sourceMappingURL=util.js.map
|
//# sourceMappingURL=util.js.map
|
||||||
File diff suppressed because one or more lines are too long
31
lib/util.test.js
generated
31
lib/util.test.js
generated
@@ -61,4 +61,35 @@ ava_1.default('getRef() throws on the empty string', t => {
|
|||||||
process.env["GITHUB_REF"] = "";
|
process.env["GITHUB_REF"] = "";
|
||||||
t.throws(util.getRef);
|
t.throws(util.getRef);
|
||||||
});
|
});
|
||||||
|
ava_1.default('isLocalRun() runs correctly', t => {
|
||||||
|
const origLocalRun = process.env.CODEQL_LOCAL_RUN;
|
||||||
|
process.env.CODEQL_LOCAL_RUN = '';
|
||||||
|
t.assert(!util.isLocalRun());
|
||||||
|
process.env.CODEQL_LOCAL_RUN = 'false';
|
||||||
|
t.assert(!util.isLocalRun());
|
||||||
|
process.env.CODEQL_LOCAL_RUN = '0';
|
||||||
|
t.assert(!util.isLocalRun());
|
||||||
|
process.env.CODEQL_LOCAL_RUN = 'true';
|
||||||
|
t.assert(util.isLocalRun());
|
||||||
|
process.env.CODEQL_LOCAL_RUN = 'hucairz';
|
||||||
|
t.assert(util.isLocalRun());
|
||||||
|
process.env.CODEQL_LOCAL_RUN = origLocalRun;
|
||||||
|
});
|
||||||
|
ava_1.default('prepareEnvironment() when a local run', t => {
|
||||||
|
const origLocalRun = process.env.CODEQL_LOCAL_RUN;
|
||||||
|
process.env.CODEQL_LOCAL_RUN = 'false';
|
||||||
|
process.env.GITHUB_JOB = 'YYY';
|
||||||
|
util.prepareLocalRunEnvironment();
|
||||||
|
// unchanged
|
||||||
|
t.deepEqual(process.env.GITHUB_JOB, 'YYY');
|
||||||
|
process.env.CODEQL_LOCAL_RUN = 'true';
|
||||||
|
util.prepareLocalRunEnvironment();
|
||||||
|
// unchanged
|
||||||
|
t.deepEqual(process.env.GITHUB_JOB, 'YYY');
|
||||||
|
process.env.GITHUB_JOB = '';
|
||||||
|
util.prepareLocalRunEnvironment();
|
||||||
|
// updated
|
||||||
|
t.deepEqual(process.env.GITHUB_JOB, 'UNKNOWN-JOB');
|
||||||
|
process.env.CODEQL_LOCAL_RUN = origLocalRun;
|
||||||
|
});
|
||||||
//# 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,mDAA2C;AAC3C,6CAA+B;AAE/B,0BAAU,CAAC,aAAI,CAAC,CAAC;AAEjB,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"}
|
{"version":3,"file":"util.test.js","sourceRoot":"","sources":["../src/util.test.ts"],"names":[],"mappings":"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"}
|
||||||
3
package-lock.json
generated
3
package-lock.json
generated
@@ -1878,7 +1878,8 @@
|
|||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "4.17.19",
|
"version": "4.17.19",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
|
||||||
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
|
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"lodash.clonedeep": {
|
"lodash.clonedeep": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
"@actions/exec": "^1.0.1",
|
"@actions/exec": "^1.0.1",
|
||||||
"@actions/github": "^2.2.0",
|
"@actions/github": "^2.2.0",
|
||||||
"@actions/http-client": "^1.0.8",
|
"@actions/http-client": "^1.0.8",
|
||||||
"@actions/io": "^1.0.1",
|
|
||||||
"@actions/tool-cache": "^1.5.5",
|
"@actions/tool-cache": "^1.5.5",
|
||||||
"console-log-level": "^1.4.1",
|
"console-log-level": "^1.4.1",
|
||||||
"file-url": "^3.0.0",
|
"file-url": "^3.0.0",
|
||||||
|
|||||||
@@ -2,7 +2,12 @@ import * as core from "@actions/core";
|
|||||||
import * as github from "@actions/github";
|
import * as github from "@actions/github";
|
||||||
import consoleLogLevel from "console-log-level";
|
import consoleLogLevel from "console-log-level";
|
||||||
|
|
||||||
export const getApiClient = function() {
|
import { isLocalRun } from "./util";
|
||||||
|
|
||||||
|
export const getApiClient = function(allowLocalRun = false) {
|
||||||
|
if (isLocalRun() && !allowLocalRun) {
|
||||||
|
throw new Error('Invalid API call in local run');
|
||||||
|
}
|
||||||
return new github.GitHub(
|
return new github.GitHub(
|
||||||
core.getInput('token'),
|
core.getInput('token'),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
|
|
||||||
import { getCodeQL } from './codeql';
|
import { getCodeQL, isTracedLanguage } from './codeql';
|
||||||
import * as sharedEnv from './shared-environment';
|
import * as config_utils from './config-utils';
|
||||||
import * as util from './util';
|
import * as util from './util';
|
||||||
|
|
||||||
interface AutobuildStatusReport extends util.StatusReportBase {
|
interface AutobuildStatusReport extends util.StatusReportBase {
|
||||||
@@ -36,16 +36,18 @@ async function run() {
|
|||||||
const startedAt = new Date();
|
const startedAt = new Date();
|
||||||
let language;
|
let language;
|
||||||
try {
|
try {
|
||||||
if (util.should_abort('autobuild', true) ||
|
util.prepareLocalRunEnvironment();
|
||||||
!await util.sendStatusReport(await util.createStatusReportBase('autobuild', 'starting', startedAt), true)) {
|
if (!await util.sendStatusReport(await util.createStatusReportBase('autobuild', 'starting', startedAt), true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const config = await config_utils.getConfig();
|
||||||
|
|
||||||
// Attempt to find a language to autobuild
|
// Attempt to find a language to autobuild
|
||||||
// We want pick the dominant language in the repo from the ones we're able to build
|
// We want pick the dominant language in the repo from the ones we're able to build
|
||||||
// The languages are sorted in order specified by user or by lines of code if we got
|
// The languages are sorted in order specified by user or by lines of code if we got
|
||||||
// them from the GitHub API, so try to build the first language on the list.
|
// them from the GitHub API, so try to build the first language on the list.
|
||||||
const autobuildLanguages = process.env[sharedEnv.CODEQL_ACTION_TRACED_LANGUAGES]?.split(',') || [];
|
const autobuildLanguages = config.languages.filter(isTracedLanguage);
|
||||||
language = autobuildLanguages[0];
|
language = autobuildLanguages[0];
|
||||||
|
|
||||||
if (!language) {
|
if (!language) {
|
||||||
@@ -67,6 +69,7 @@ async function run() {
|
|||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed("We were unable to automatically build your code. Please replace the call to the autobuild action with your custom build steps. " + error.message);
|
core.setFailed("We were unable to automatically build your code. Please replace the call to the autobuild action with your custom build steps. " + error.message);
|
||||||
|
console.log(error);
|
||||||
await sendCompletedStatusReport(startedAt, [language], language, error);
|
await sendCompletedStatusReport(startedAt, [language], language, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ 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 http from '@actions/http-client';
|
||||||
import { IHeaders } from '@actions/http-client/interfaces';
|
import { IHeaders } from '@actions/http-client/interfaces';
|
||||||
import * as io from '@actions/io';
|
|
||||||
import * as toolcache from '@actions/tool-cache';
|
import * as toolcache from '@actions/tool-cache';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
@@ -83,13 +82,8 @@ const CODEQL_ACTION_CMD = "CODEQL_ACTION_CMD";
|
|||||||
|
|
||||||
const CODEQL_BUNDLE_VERSION = "codeql-bundle-20200630";
|
const CODEQL_BUNDLE_VERSION = "codeql-bundle-20200630";
|
||||||
const CODEQL_BUNDLE_NAME = "codeql-bundle.tar.gz";
|
const CODEQL_BUNDLE_NAME = "codeql-bundle.tar.gz";
|
||||||
const GITHUB_DOTCOM_API_URL = "https://api.github.com";
|
|
||||||
const CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action";
|
const CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action";
|
||||||
|
|
||||||
function getInstanceAPIURL(): string {
|
|
||||||
return process.env["GITHUB_API_URL"] || GITHUB_DOTCOM_API_URL;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCodeQLActionRepository(): string {
|
function getCodeQLActionRepository(): string {
|
||||||
// Actions do not know their own repository name,
|
// Actions do not know their own repository name,
|
||||||
// so we currently use this hack to find the name based on where our files are.
|
// so we currently use this hack to find the name based on where our files are.
|
||||||
@@ -110,11 +104,11 @@ async function getCodeQLBundleDownloadURL(): Promise<string> {
|
|||||||
const codeQLActionRepository = getCodeQLActionRepository();
|
const codeQLActionRepository = getCodeQLActionRepository();
|
||||||
const potentialDownloadSources = [
|
const potentialDownloadSources = [
|
||||||
// This GitHub instance, and this Action.
|
// This GitHub instance, and this Action.
|
||||||
[getInstanceAPIURL(), codeQLActionRepository],
|
[util.getInstanceAPIURL(), codeQLActionRepository],
|
||||||
// This GitHub instance, and the canonical Action.
|
// This GitHub instance, and the canonical Action.
|
||||||
[getInstanceAPIURL(), CODEQL_DEFAULT_ACTION_REPOSITORY],
|
[util.getInstanceAPIURL(), CODEQL_DEFAULT_ACTION_REPOSITORY],
|
||||||
// GitHub.com, and the canonical Action.
|
// GitHub.com, and the canonical Action.
|
||||||
[GITHUB_DOTCOM_API_URL, CODEQL_DEFAULT_ACTION_REPOSITORY],
|
[util.GITHUB_DOTCOM_API_URL, CODEQL_DEFAULT_ACTION_REPOSITORY],
|
||||||
];
|
];
|
||||||
// We now filter out any duplicates.
|
// We now filter out any duplicates.
|
||||||
// Duplicates will happen either because the GitHub instance is GitHub.com, or because the Action is not a fork.
|
// Duplicates will happen either because the GitHub instance is GitHub.com, or because the Action is not a fork.
|
||||||
@@ -122,7 +116,7 @@ async function getCodeQLBundleDownloadURL(): Promise<string> {
|
|||||||
for (let downloadSource of uniqueDownloadSources) {
|
for (let downloadSource of uniqueDownloadSources) {
|
||||||
let [apiURL, repository] = downloadSource;
|
let [apiURL, repository] = downloadSource;
|
||||||
// If we've reached the final case, short-circuit the API check since we know the bundle exists and is public.
|
// If we've reached the final case, short-circuit the API check since we know the bundle exists and is public.
|
||||||
if (apiURL === GITHUB_DOTCOM_API_URL && repository === CODEQL_DEFAULT_ACTION_REPOSITORY) {
|
if (apiURL === util.GITHUB_DOTCOM_API_URL && repository === CODEQL_DEFAULT_ACTION_REPOSITORY) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let [repositoryOwner, repositoryName] = repository.split("/");
|
let [repositoryOwner, repositoryName] = repository.split("/");
|
||||||
@@ -159,7 +153,7 @@ async function toolcacheDownloadTool(url: string, headers?: IHeaders): Promise<s
|
|||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
const pipeline = globalutil.promisify(stream.pipeline);
|
const pipeline = globalutil.promisify(stream.pipeline);
|
||||||
await io.mkdirP(path.dirname(dest));
|
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
||||||
await pipeline(response.message, fs.createWriteStream(dest));
|
await pipeline(response.message, fs.createWriteStream(dest));
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
@@ -181,7 +175,7 @@ export async function setupCodeQL(): Promise<CodeQL> {
|
|||||||
// We only want to provide an authorization header if we are downloading
|
// We only want to provide an authorization header if we are downloading
|
||||||
// from the same GitHub instance the Action is running on.
|
// from the same GitHub instance the Action is running on.
|
||||||
// This avoids leaking Enterprise tokens to dotcom.
|
// This avoids leaking Enterprise tokens to dotcom.
|
||||||
if (codeqlURL.startsWith(getInstanceAPIURL() + "/")) {
|
if (codeqlURL.startsWith(util.getInstanceAPIURL() + "/")) {
|
||||||
core.debug('Downloading CodeQL bundle with token.');
|
core.debug('Downloading CodeQL bundle with token.');
|
||||||
let token = core.getInput('token', { required: true });
|
let token = core.getInput('token', { required: true });
|
||||||
headers.authorization = `token ${token}`;
|
headers.authorization = `token ${token}`;
|
||||||
@@ -395,3 +389,11 @@ function getCodeQLForCmd(cmd: string): CodeQL {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isTracedLanguage(language: string): boolean {
|
||||||
|
return ['cpp', 'java', 'csharp'].includes(language);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isScannedLanguage(language: string): boolean {
|
||||||
|
return !isTracedLanguage(language);
|
||||||
|
}
|
||||||
|
|||||||
@@ -36,6 +36,19 @@ function mockGetContents(content: GetContentsResponse): sinon.SinonStub<any, any
|
|||||||
return spyGetContents;
|
return spyGetContents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mockListLanguages(languages: string[]) {
|
||||||
|
// Passing an auth token is required, so we just use a dummy value
|
||||||
|
let client = new github.GitHub('123');
|
||||||
|
const response = {
|
||||||
|
data: {},
|
||||||
|
};
|
||||||
|
for (const language of languages) {
|
||||||
|
response.data[language] = 123;
|
||||||
|
}
|
||||||
|
sinon.stub(client.repos, "listLanguages").resolves(response as any);
|
||||||
|
sinon.stub(api, "getApiClient").value(() => client);
|
||||||
|
}
|
||||||
|
|
||||||
test("load empty config", async t => {
|
test("load empty config", async t => {
|
||||||
return await util.withTmpDir(async tmpDir => {
|
return await util.withTmpDir(async tmpDir => {
|
||||||
process.env['RUNNER_TEMP'] = tmpDir;
|
process.env['RUNNER_TEMP'] = tmpDir;
|
||||||
@@ -224,7 +237,9 @@ test("default queries are used", async t => {
|
|||||||
resolveQueriesArgs.push({queries, extraSearchPath});
|
resolveQueriesArgs.push({queries, extraSearchPath});
|
||||||
return {
|
return {
|
||||||
byLanguage: {
|
byLanguage: {
|
||||||
'javascript': {},
|
'javascript': {
|
||||||
|
'foo.ql': {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
noDeclaredLanguage: {},
|
noDeclaredLanguage: {},
|
||||||
multipleDeclaredLanguages: {},
|
multipleDeclaredLanguages: {},
|
||||||
@@ -262,7 +277,11 @@ test("API client used when reading remote config", async t => {
|
|||||||
CodeQL.setCodeQL({
|
CodeQL.setCodeQL({
|
||||||
resolveQueries: async function() {
|
resolveQueries: async function() {
|
||||||
return {
|
return {
|
||||||
byLanguage: {},
|
byLanguage: {
|
||||||
|
'javascript': {
|
||||||
|
'foo.ql': {},
|
||||||
|
},
|
||||||
|
},
|
||||||
noDeclaredLanguage: {},
|
noDeclaredLanguage: {},
|
||||||
multipleDeclaredLanguages: {},
|
multipleDeclaredLanguages: {},
|
||||||
};
|
};
|
||||||
@@ -337,6 +356,38 @@ test("Invalid format of remote config handled correctly", async t => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("No detected languages", async t => {
|
||||||
|
return await util.withTmpDir(async tmpDir => {
|
||||||
|
process.env['RUNNER_TEMP'] = tmpDir;
|
||||||
|
process.env['GITHUB_WORKSPACE'] = tmpDir;
|
||||||
|
|
||||||
|
mockListLanguages([]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await configUtils.initConfig();
|
||||||
|
throw new Error('initConfig did not throw error');
|
||||||
|
} catch (err) {
|
||||||
|
t.deepEqual(err, new Error(configUtils.getNoLanguagesError()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Unknown languages", async t => {
|
||||||
|
return await util.withTmpDir(async tmpDir => {
|
||||||
|
process.env['RUNNER_TEMP'] = tmpDir;
|
||||||
|
process.env['GITHUB_WORKSPACE'] = tmpDir;
|
||||||
|
|
||||||
|
setInput('languages', 'ruby,english');
|
||||||
|
|
||||||
|
try {
|
||||||
|
await configUtils.initConfig();
|
||||||
|
throw new Error('initConfig did not throw error');
|
||||||
|
} catch (err) {
|
||||||
|
t.deepEqual(err, new Error(configUtils.getUnknownLanguagesError(['ruby', 'english'])));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
function doInvalidInputTest(
|
function doInvalidInputTest(
|
||||||
testName: string,
|
testName: string,
|
||||||
inputFileContents: string,
|
inputFileContents: string,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import * as io from '@actions/io';
|
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as yaml from 'js-yaml';
|
import * as yaml from 'js-yaml';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
@@ -17,6 +16,16 @@ const QUERIES_USES_PROPERTY = 'uses';
|
|||||||
const PATHS_IGNORE_PROPERTY = 'paths-ignore';
|
const PATHS_IGNORE_PROPERTY = 'paths-ignore';
|
||||||
const PATHS_PROPERTY = 'paths';
|
const PATHS_PROPERTY = 'paths';
|
||||||
|
|
||||||
|
// All the languages supported by CodeQL
|
||||||
|
const ALL_LANGUAGES = ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] as const;
|
||||||
|
type Language = (typeof ALL_LANGUAGES)[number];
|
||||||
|
|
||||||
|
// Some alternate names for languages
|
||||||
|
const LANGUAGE_ALIASES: {[name: string]: Language} = {
|
||||||
|
'c': 'cpp',
|
||||||
|
'typescript': 'javascript',
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format of the config file supplied by the user.
|
* Format of the config file supplied by the user.
|
||||||
*/
|
*/
|
||||||
@@ -38,7 +47,7 @@ export interface Config {
|
|||||||
/**
|
/**
|
||||||
* Set of languages to run analysis for.
|
* Set of languages to run analysis for.
|
||||||
*/
|
*/
|
||||||
languages: string[];
|
languages: Language[];
|
||||||
/**
|
/**
|
||||||
* Map from language to query files.
|
* Map from language to query files.
|
||||||
* Will only contain .ql files and not other kinds of files,
|
* Will only contain .ql files and not other kinds of files,
|
||||||
@@ -402,12 +411,21 @@ function getConfigFilePropertyError(configFile: string, property: string, error:
|
|||||||
return 'The configuration file "' + configFile + '" is invalid: property "' + property + '" ' + error;
|
return 'The configuration file "' + configFile + '" is invalid: property "' + property + '" ' + error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getNoLanguagesError(): string {
|
||||||
|
return "Did not detect any languages to analyze. " +
|
||||||
|
"Please update input in workflow or check that GitHub detects the correct languages in your repository.";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getUnknownLanguagesError(languages: string[]): string {
|
||||||
|
return "Did not recognise the following languages: " + languages.join(', ');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the set of languages in the current repository
|
* Gets the set of languages in the current repository
|
||||||
*/
|
*/
|
||||||
async function getLanguagesInRepo(): Promise<string[]> {
|
async function getLanguagesInRepo(): Promise<Language[]> {
|
||||||
// Translate between GitHub's API names for languages and ours
|
// Translate between GitHub's API names for languages and ours
|
||||||
const codeqlLanguages = {
|
const codeqlLanguages: {[lang: string]: Language} = {
|
||||||
'C': 'cpp',
|
'C': 'cpp',
|
||||||
'C++': 'cpp',
|
'C++': 'cpp',
|
||||||
'C#': 'csharp',
|
'C#': 'csharp',
|
||||||
@@ -423,10 +441,10 @@ 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}`);
|
||||||
const response = await api.getApiClient().request("GET /repos/:owner/:repo/languages", ({
|
const response = await api.getApiClient(true).repos.listLanguages({
|
||||||
owner,
|
owner,
|
||||||
repo
|
repo
|
||||||
}));
|
});
|
||||||
|
|
||||||
core.debug("Languages API response: " + JSON.stringify(response));
|
core.debug("Languages API response: " + JSON.stringify(response));
|
||||||
|
|
||||||
@@ -434,7 +452,7 @@ async function getLanguagesInRepo(): Promise<string[]> {
|
|||||||
// When we pick a language to autobuild we want to pick the most popular traced language
|
// When we pick a language to autobuild we want to pick the most popular traced language
|
||||||
// Since sets in javascript maintain insertion order, using a set here and then splatting it
|
// Since sets in javascript maintain insertion order, using a set here and then splatting it
|
||||||
// into an array gives us an array of languages ordered by popularity
|
// into an array gives us an array of languages ordered by popularity
|
||||||
let languages: Set<string> = new Set();
|
let languages: Set<Language> = new Set();
|
||||||
for (let lang in response.data) {
|
for (let lang in response.data) {
|
||||||
if (lang in codeqlLanguages) {
|
if (lang in codeqlLanguages) {
|
||||||
languages.add(codeqlLanguages[lang]);
|
languages.add(codeqlLanguages[lang]);
|
||||||
@@ -452,8 +470,11 @@ async function getLanguagesInRepo(): Promise<string[]> {
|
|||||||
* The result is obtained from the action input parameter 'languages' if that
|
* The result is obtained from the action input parameter 'languages' if that
|
||||||
* has been set, otherwise it is deduced as all languages in the repo that
|
* has been set, otherwise it is deduced as all languages in the repo that
|
||||||
* can be analysed.
|
* can be analysed.
|
||||||
|
*
|
||||||
|
* If no languages could be detected from either the workflow or the repository
|
||||||
|
* then throw an error.
|
||||||
*/
|
*/
|
||||||
async function getLanguages(): Promise<string[]> {
|
async function getLanguages(): Promise<Language[]> {
|
||||||
|
|
||||||
// Obtain from action input 'languages' if set
|
// Obtain from action input 'languages' if set
|
||||||
let languages = core.getInput('languages', { required: false })
|
let languages = core.getInput('languages', { required: false })
|
||||||
@@ -468,7 +489,35 @@ async function getLanguages(): Promise<string[]> {
|
|||||||
core.info("Automatically detected languages: " + JSON.stringify(languages));
|
core.info("Automatically detected languages: " + JSON.stringify(languages));
|
||||||
}
|
}
|
||||||
|
|
||||||
return languages;
|
// If the languages parameter was not given and no languages were
|
||||||
|
// detected then fail here as this is a workflow configuration error.
|
||||||
|
if (languages.length === 0) {
|
||||||
|
throw new Error(getNoLanguagesError());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure they are supported
|
||||||
|
const checkedLanguages: Language[] = [];
|
||||||
|
const unknownLanguages: string[] = [];
|
||||||
|
for (let language of languages) {
|
||||||
|
// Normalise to lower case
|
||||||
|
language = language.toLowerCase();
|
||||||
|
// Resolve any known aliases
|
||||||
|
if (language in LANGUAGE_ALIASES) {
|
||||||
|
language = LANGUAGE_ALIASES[language];
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkedLanguage = ALL_LANGUAGES.find(l => l === language);
|
||||||
|
if (checkedLanguage === undefined) {
|
||||||
|
unknownLanguages.push(language);
|
||||||
|
} else if (checkedLanguages.indexOf(checkedLanguage) === -1) {
|
||||||
|
checkedLanguages.push(checkedLanguage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (unknownLanguages.length > 0) {
|
||||||
|
throw new Error(getUnknownLanguagesError(unknownLanguages));
|
||||||
|
}
|
||||||
|
|
||||||
|
return checkedLanguages;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -515,11 +564,6 @@ async function loadConfig(configFile: string): Promise<Config> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const languages = await getLanguages();
|
const languages = await getLanguages();
|
||||||
// If the languages parameter was not given and no languages were
|
|
||||||
// detected then fail here as this is a workflow configuration error.
|
|
||||||
if (languages.length === 0) {
|
|
||||||
throw new Error("Did not detect any languages to analyze. Please update input in workflow.");
|
|
||||||
}
|
|
||||||
|
|
||||||
const queries = {};
|
const queries = {};
|
||||||
const pathsIgnore: string[] = [];
|
const pathsIgnore: string[] = [];
|
||||||
@@ -572,6 +616,15 @@ async function loadConfig(configFile: string): Promise<Config> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The list of queries should not be empty for any language. If it is then
|
||||||
|
// it is a user configuration error.
|
||||||
|
for (const language of languages) {
|
||||||
|
if (queries[language] === undefined || queries[language].length === 0) {
|
||||||
|
throw new Error(`Did not detect any queries to run for ${language}. ` +
|
||||||
|
"Please make sure that the default queries are enabled, or you are specifying queries to run.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
languages,
|
languages,
|
||||||
queries,
|
queries,
|
||||||
@@ -636,7 +689,7 @@ async function getRemoteConfig(configFile: string): Promise<UserConfig> {
|
|||||||
throw new Error(getConfigFileRepoFormatInvalidMessage(configFile));
|
throw new Error(getConfigFileRepoFormatInvalidMessage(configFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await api.getApiClient().repos.getContents({
|
const response = await api.getApiClient(true).repos.getContents({
|
||||||
owner: pieces.groups.owner,
|
owner: pieces.groups.owner,
|
||||||
repo: pieces.groups.repo,
|
repo: pieces.groups.repo,
|
||||||
path: pieces.groups.path,
|
path: pieces.groups.path,
|
||||||
@@ -655,18 +708,11 @@ async function getRemoteConfig(configFile: string): Promise<UserConfig> {
|
|||||||
return yaml.safeLoad(Buffer.from(fileContents, 'base64').toString('binary'));
|
return yaml.safeLoad(Buffer.from(fileContents, 'base64').toString('binary'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the directory where the parsed config will be stored.
|
|
||||||
*/
|
|
||||||
function getPathToParsedConfigFolder(): string {
|
|
||||||
return util.getRequiredEnvParam('RUNNER_TEMP');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the file path where the parsed config will be stored.
|
* Get the file path where the parsed config will be stored.
|
||||||
*/
|
*/
|
||||||
export function getPathToParsedConfigFile(): string {
|
export function getPathToParsedConfigFile(): string {
|
||||||
return path.join(getPathToParsedConfigFolder(), 'config');
|
return path.join(util.getRequiredEnvParam('RUNNER_TEMP'), 'config');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -674,8 +720,9 @@ export function getPathToParsedConfigFile(): string {
|
|||||||
*/
|
*/
|
||||||
async function saveConfig(config: Config) {
|
async function saveConfig(config: Config) {
|
||||||
const configString = JSON.stringify(config);
|
const configString = JSON.stringify(config);
|
||||||
await io.mkdirP(getPathToParsedConfigFolder());
|
const configFile = getPathToParsedConfigFile();
|
||||||
fs.writeFileSync(getPathToParsedConfigFile(), configString, 'utf8');
|
fs.mkdirSync(path.dirname(configFile), { recursive: true });
|
||||||
|
fs.writeFileSync(configFile, configString, 'utf8');
|
||||||
core.debug('Saved config:');
|
core.debug('Saved config:');
|
||||||
core.debug(configString);
|
core.debug(configString);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import * as io from '@actions/io';
|
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import { getCodeQL } from './codeql';
|
import { getCodeQL, isScannedLanguage } from './codeql';
|
||||||
import * as configUtils from './config-utils';
|
import * as configUtils from './config-utils';
|
||||||
import * as sharedEnv from './shared-environment';
|
import * as sharedEnv from './shared-environment';
|
||||||
import * as upload_lib from './upload-lib';
|
import * as upload_lib from './upload-lib';
|
||||||
@@ -56,11 +55,10 @@ async function sendStatusReport(
|
|||||||
await util.sendStatusReport(statusReport);
|
await util.sendStatusReport(statusReport);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createdDBForScannedLanguages(databaseFolder: string) {
|
async function createdDBForScannedLanguages(databaseFolder: string, config: configUtils.Config) {
|
||||||
const scannedLanguages = process.env[sharedEnv.CODEQL_ACTION_SCANNED_LANGUAGES];
|
const codeql = getCodeQL();
|
||||||
if (scannedLanguages) {
|
for (const language of config.languages) {
|
||||||
const codeql = getCodeQL();
|
if (isScannedLanguage(language)) {
|
||||||
for (const language of scannedLanguages.split(',')) {
|
|
||||||
core.startGroup('Extracting ' + language);
|
core.startGroup('Extracting ' + language);
|
||||||
await codeql.extractScannedLanguage(path.join(databaseFolder, language), language);
|
await codeql.extractScannedLanguage(path.join(databaseFolder, language), language);
|
||||||
core.endGroup();
|
core.endGroup();
|
||||||
@@ -69,7 +67,7 @@ async function createdDBForScannedLanguages(databaseFolder: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function finalizeDatabaseCreation(databaseFolder: string, config: configUtils.Config) {
|
async function finalizeDatabaseCreation(databaseFolder: string, config: configUtils.Config) {
|
||||||
await createdDBForScannedLanguages(databaseFolder);
|
await createdDBForScannedLanguages(databaseFolder, config);
|
||||||
|
|
||||||
const codeql = getCodeQL();
|
const codeql = getCodeQL();
|
||||||
for (const language of config.languages) {
|
for (const language of config.languages) {
|
||||||
@@ -125,8 +123,8 @@ async function run() {
|
|||||||
let queriesStats: QueriesStatusReport | undefined = undefined;
|
let queriesStats: QueriesStatusReport | undefined = undefined;
|
||||||
let uploadStats: upload_lib.UploadStatusReport | undefined = undefined;
|
let uploadStats: upload_lib.UploadStatusReport | undefined = undefined;
|
||||||
try {
|
try {
|
||||||
if (util.should_abort('finish', true) ||
|
util.prepareLocalRunEnvironment();
|
||||||
!await util.sendStatusReport(await util.createStatusReportBase('finish', 'starting', startedAt), true)) {
|
if (!await util.sendStatusReport(await util.createStatusReportBase('finish', 'starting', startedAt), true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const config = await configUtils.getConfig();
|
const config = await configUtils.getConfig();
|
||||||
@@ -134,10 +132,10 @@ async function run() {
|
|||||||
core.exportVariable(sharedEnv.ODASA_TRACER_CONFIGURATION, '');
|
core.exportVariable(sharedEnv.ODASA_TRACER_CONFIGURATION, '');
|
||||||
delete process.env[sharedEnv.ODASA_TRACER_CONFIGURATION];
|
delete process.env[sharedEnv.ODASA_TRACER_CONFIGURATION];
|
||||||
|
|
||||||
const databaseFolder = util.getRequiredEnvParam(sharedEnv.CODEQL_ACTION_DATABASE_DIR);
|
const databaseFolder = util.getCodeQLDatabasesDir();
|
||||||
|
|
||||||
const sarifFolder = core.getInput('output');
|
const sarifFolder = core.getInput('output');
|
||||||
await io.mkdirP(sarifFolder);
|
fs.mkdirSync(sarifFolder, { recursive: true });
|
||||||
|
|
||||||
core.info('Finalizing database creation');
|
core.info('Finalizing database creation');
|
||||||
await finalizeDatabaseCreation(databaseFolder, config);
|
await finalizeDatabaseCreation(databaseFolder, config);
|
||||||
@@ -151,6 +149,7 @@ async function run() {
|
|||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
|
console.log(error);
|
||||||
await sendStatusReport(startedAt, queriesStats, uploadStats, error);
|
await sendStatusReport(startedAt, queriesStats, uploadStats, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
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 io from '@actions/io';
|
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import * as analysisPaths from './analysis-paths';
|
import * as analysisPaths from './analysis-paths';
|
||||||
import { CodeQL, setupCodeQL } from './codeql';
|
import { CodeQL, isTracedLanguage, setupCodeQL } from './codeql';
|
||||||
import * as configUtils from './config-utils';
|
import * as configUtils from './config-utils';
|
||||||
import * as sharedEnv from './shared-environment';
|
|
||||||
import * as util from './util';
|
import * as util from './util';
|
||||||
|
|
||||||
type TracerConfig = {
|
type TracerConfig = {
|
||||||
@@ -54,7 +52,7 @@ async function tracerConfig(
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
function concatTracerConfigs(configs: { [lang: string]: TracerConfig }): TracerConfig {
|
function concatTracerConfigs(configs: TracerConfig[]): TracerConfig {
|
||||||
// A tracer config is a map containing additional environment variables and a tracer 'spec' file.
|
// A tracer config is a map containing additional environment variables and a tracer 'spec' file.
|
||||||
// A tracer 'spec' file has the following format [log_file, number_of_blocks, blocks_text]
|
// A tracer 'spec' file has the following format [log_file, number_of_blocks, blocks_text]
|
||||||
|
|
||||||
@@ -62,7 +60,7 @@ function concatTracerConfigs(configs: { [lang: string]: TracerConfig }): TracerC
|
|||||||
const env: { [key: string]: string; } = {};
|
const env: { [key: string]: string; } = {};
|
||||||
let copyExecutables = false;
|
let copyExecutables = false;
|
||||||
let envSize = 0;
|
let envSize = 0;
|
||||||
for (let v of Object.values(configs)) {
|
for (const v of configs) {
|
||||||
for (let e of Object.entries(v.env)) {
|
for (let e of Object.entries(v.env)) {
|
||||||
const name = e[0];
|
const name = e[0];
|
||||||
const value = e[1];
|
const value = e[1];
|
||||||
@@ -177,8 +175,8 @@ async function run() {
|
|||||||
let codeql: CodeQL;
|
let codeql: CodeQL;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (util.should_abort('init', false) ||
|
util.prepareLocalRunEnvironment();
|
||||||
!await util.sendStatusReport(await util.createStatusReportBase('init', 'starting', startedAt), true)) {
|
if (!await util.sendStatusReport(await util.createStatusReportBase('init', 'starting', startedAt), true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,6 +192,7 @@ async function run() {
|
|||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
core.setFailed(e.message);
|
core.setFailed(e.message);
|
||||||
|
console.log(e);
|
||||||
await util.sendStatusReport(await util.createStatusReportBase('init', 'aborted', startedAt, e.message));
|
await util.sendStatusReport(await util.createStatusReportBase('init', 'aborted', startedAt, e.message));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -213,11 +212,10 @@ async function run() {
|
|||||||
const codeqlRam = process.env['CODEQL_RAM'] || '6500';
|
const codeqlRam = process.env['CODEQL_RAM'] || '6500';
|
||||||
core.exportVariable('CODEQL_RAM', codeqlRam);
|
core.exportVariable('CODEQL_RAM', codeqlRam);
|
||||||
|
|
||||||
const databaseFolder = path.resolve(util.getRequiredEnvParam('RUNNER_TEMP'), 'codeql_databases');
|
const databaseFolder = util.getCodeQLDatabasesDir();
|
||||||
await io.mkdirP(databaseFolder);
|
fs.mkdirSync(databaseFolder, { recursive: true });
|
||||||
|
|
||||||
let tracedLanguages: { [key: string]: TracerConfig } = {};
|
let tracedLanguageConfigs: TracerConfig[] = [];
|
||||||
let scannedLanguages: string[] = [];
|
|
||||||
// TODO: replace this code once CodeQL supports multi-language tracing
|
// TODO: replace this code once CodeQL supports multi-language tracing
|
||||||
for (let language of config.languages) {
|
for (let language of config.languages) {
|
||||||
const languageDatabase = path.join(databaseFolder, language);
|
const languageDatabase = path.join(databaseFolder, language);
|
||||||
@@ -225,16 +223,13 @@ async function run() {
|
|||||||
// Init language database
|
// Init language database
|
||||||
await codeql.databaseInit(languageDatabase, language, sourceRoot);
|
await codeql.databaseInit(languageDatabase, language, sourceRoot);
|
||||||
// TODO: add better detection of 'traced languages' instead of using a hard coded list
|
// TODO: add better detection of 'traced languages' instead of using a hard coded list
|
||||||
if (['cpp', 'java', 'csharp'].includes(language)) {
|
if (isTracedLanguage(language)) {
|
||||||
const config: TracerConfig = await tracerConfig(codeql, languageDatabase);
|
const config: TracerConfig = await tracerConfig(codeql, languageDatabase);
|
||||||
tracedLanguages[language] = config;
|
tracedLanguageConfigs.push(config);
|
||||||
} else {
|
|
||||||
scannedLanguages.push(language);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const tracedLanguageKeys = Object.keys(tracedLanguages);
|
if (tracedLanguageConfigs.length > 0) {
|
||||||
if (tracedLanguageKeys.length > 0) {
|
const mainTracerConfig = concatTracerConfigs(tracedLanguageConfigs);
|
||||||
const mainTracerConfig = concatTracerConfigs(tracedLanguages);
|
|
||||||
if (mainTracerConfig.spec) {
|
if (mainTracerConfig.spec) {
|
||||||
for (let entry of Object.entries(mainTracerConfig.env)) {
|
for (let entry of Object.entries(mainTracerConfig.env)) {
|
||||||
core.exportVariable(entry[0], entry[1]);
|
core.exportVariable(entry[0], entry[1]);
|
||||||
@@ -258,15 +253,9 @@ async function run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
core.exportVariable(sharedEnv.CODEQL_ACTION_SCANNED_LANGUAGES, scannedLanguages.join(','));
|
|
||||||
core.exportVariable(sharedEnv.CODEQL_ACTION_TRACED_LANGUAGES, tracedLanguageKeys.join(','));
|
|
||||||
|
|
||||||
// TODO: make this a "private" environment variable of the action
|
|
||||||
core.exportVariable(sharedEnv.CODEQL_ACTION_DATABASE_DIR, databaseFolder);
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
|
console.log(error);
|
||||||
await util.sendStatusReport(await util.createStatusReportBase(
|
await util.sendStatusReport(await util.createStatusReportBase(
|
||||||
'init',
|
'init',
|
||||||
'failure',
|
'failure',
|
||||||
@@ -276,7 +265,6 @@ async function run() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await sendSuccessStatusReport(startedAt, config);
|
await sendSuccessStatusReport(startedAt, config);
|
||||||
core.exportVariable(sharedEnv.CODEQL_ACTION_INIT_COMPLETED, 'true');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
run().catch(e => {
|
run().catch(e => {
|
||||||
|
|||||||
@@ -1,13 +1,7 @@
|
|||||||
export const CODEQL_ACTION_DATABASE_DIR = 'CODEQL_ACTION_DATABASE_DIR';
|
|
||||||
export const CODEQL_ACTION_ANALYSIS_KEY = 'CODEQL_ACTION_ANALYSIS_KEY';
|
|
||||||
export const ODASA_TRACER_CONFIGURATION = 'ODASA_TRACER_CONFIGURATION';
|
export const ODASA_TRACER_CONFIGURATION = 'ODASA_TRACER_CONFIGURATION';
|
||||||
export const CODEQL_ACTION_SCANNED_LANGUAGES = 'CODEQL_ACTION_SCANNED_LANGUAGES';
|
|
||||||
export const CODEQL_ACTION_TRACED_LANGUAGES = 'CODEQL_ACTION_TRACED_LANGUAGES';
|
|
||||||
// The time at which the first action (normally init) started executing.
|
// The time at which the first action (normally init) started executing.
|
||||||
// If a workflow invokes a different action without first invoking the init
|
// If a workflow invokes a different action without first invoking the init
|
||||||
// action (i.e. the upload action is being used by a third-party integrator)
|
// action (i.e. the upload action is being used by a third-party integrator)
|
||||||
// then this variable will be assigned the start time of the action invoked
|
// then this variable will be assigned the start time of the action invoked
|
||||||
// rather that the init action.
|
// rather that the init action.
|
||||||
export const CODEQL_WORKFLOW_STARTED_AT = 'CODEQL_WORKFLOW_STARTED_AT';
|
export const CODEQL_WORKFLOW_STARTED_AT = 'CODEQL_WORKFLOW_STARTED_AT';
|
||||||
// Populated when the init action completes successfully
|
|
||||||
export const CODEQL_ACTION_INIT_COMPLETED = 'CODEQL_ACTION_INIT_COMPLETED';
|
|
||||||
|
|||||||
@@ -218,9 +218,12 @@ async function uploadFiles(sarifFiles: string[]): Promise<UploadStatusReport> {
|
|||||||
const numResultInSarif = countResultsInSarif(sarifPayload);
|
const numResultInSarif = countResultsInSarif(sarifPayload);
|
||||||
core.debug("Number of results in upload: " + numResultInSarif);
|
core.debug("Number of results in upload: " + numResultInSarif);
|
||||||
|
|
||||||
// Make the upload
|
if (!util.isLocalRun()) {
|
||||||
await uploadPayload(payload);
|
// Make the upload
|
||||||
|
await uploadPayload(payload);
|
||||||
|
} else {
|
||||||
|
core.debug("Not uploading because this is a local run.");
|
||||||
|
}
|
||||||
core.endGroup();
|
core.endGroup();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -16,8 +16,7 @@ async function sendSuccessStatusReport(startedAt: Date, uploadStats: upload_lib.
|
|||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
const startedAt = new Date();
|
const startedAt = new Date();
|
||||||
if (util.should_abort('upload-sarif', false) ||
|
if (!await util.sendStatusReport(await util.createStatusReportBase('upload-sarif', 'starting', startedAt), true)) {
|
||||||
!await util.sendStatusReport(await util.createStatusReportBase('upload-sarif', 'starting', startedAt), true)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,6 +26,7 @@ async function run() {
|
|||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
|
console.log(error);
|
||||||
await util.sendStatusReport(await util.createStatusReportBase(
|
await util.sendStatusReport(await util.createStatusReportBase(
|
||||||
'upload-sarif',
|
'upload-sarif',
|
||||||
'failure',
|
'failure',
|
||||||
|
|||||||
@@ -67,3 +67,52 @@ test('getRef() throws on the empty string', t => {
|
|||||||
process.env["GITHUB_REF"] = "";
|
process.env["GITHUB_REF"] = "";
|
||||||
t.throws(util.getRef);
|
t.throws(util.getRef);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('isLocalRun() runs correctly', t => {
|
||||||
|
const origLocalRun = process.env.CODEQL_LOCAL_RUN;
|
||||||
|
|
||||||
|
process.env.CODEQL_LOCAL_RUN = '';
|
||||||
|
t.assert(!util.isLocalRun());
|
||||||
|
|
||||||
|
process.env.CODEQL_LOCAL_RUN = 'false';
|
||||||
|
t.assert(!util.isLocalRun());
|
||||||
|
|
||||||
|
process.env.CODEQL_LOCAL_RUN = '0';
|
||||||
|
t.assert(!util.isLocalRun());
|
||||||
|
|
||||||
|
process.env.CODEQL_LOCAL_RUN = 'true';
|
||||||
|
t.assert(util.isLocalRun());
|
||||||
|
|
||||||
|
process.env.CODEQL_LOCAL_RUN = 'hucairz';
|
||||||
|
t.assert(util.isLocalRun());
|
||||||
|
|
||||||
|
process.env.CODEQL_LOCAL_RUN = origLocalRun;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('prepareEnvironment() when a local run', t => {
|
||||||
|
const origLocalRun = process.env.CODEQL_LOCAL_RUN;
|
||||||
|
|
||||||
|
process.env.CODEQL_LOCAL_RUN = 'false';
|
||||||
|
process.env.GITHUB_JOB = 'YYY';
|
||||||
|
|
||||||
|
util.prepareLocalRunEnvironment();
|
||||||
|
|
||||||
|
// unchanged
|
||||||
|
t.deepEqual(process.env.GITHUB_JOB, 'YYY');
|
||||||
|
|
||||||
|
process.env.CODEQL_LOCAL_RUN = 'true';
|
||||||
|
|
||||||
|
util.prepareLocalRunEnvironment();
|
||||||
|
|
||||||
|
// unchanged
|
||||||
|
t.deepEqual(process.env.GITHUB_JOB, 'YYY');
|
||||||
|
|
||||||
|
process.env.GITHUB_JOB = '';
|
||||||
|
|
||||||
|
util.prepareLocalRunEnvironment();
|
||||||
|
|
||||||
|
// updated
|
||||||
|
t.deepEqual(process.env.GITHUB_JOB, 'UNKNOWN-JOB');
|
||||||
|
|
||||||
|
process.env.CODEQL_LOCAL_RUN = origLocalRun;
|
||||||
|
});
|
||||||
|
|||||||
84
src/util.ts
84
src/util.ts
@@ -8,28 +8,23 @@ import * as api from './api-client';
|
|||||||
import * as sharedEnv from './shared-environment';
|
import * as sharedEnv from './shared-environment';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should the current action be aborted?
|
* The API URL for github.com.
|
||||||
*
|
|
||||||
* This method should be called at the start of all CodeQL actions and they
|
|
||||||
* should abort cleanly if this returns true without failing the action.
|
|
||||||
* This method will call `core.setFailed` if necessary.
|
|
||||||
*/
|
*/
|
||||||
export function should_abort(actionName: string, requireInitActionHasRun: boolean): boolean {
|
export const GITHUB_DOTCOM_API_URL = "https://api.github.com";
|
||||||
|
|
||||||
// Check that required aspects of the environment are present
|
/**
|
||||||
const ref = process.env['GITHUB_REF'];
|
* Get the API URL for the GitHub instance we are connected to.
|
||||||
if (ref === undefined) {
|
* May be for github.com or for an enterprise instance.
|
||||||
core.setFailed('GITHUB_REF must be set.');
|
*/
|
||||||
return true;
|
export function getInstanceAPIURL(): string {
|
||||||
}
|
return process.env["GITHUB_API_URL"] || GITHUB_DOTCOM_API_URL;
|
||||||
|
}
|
||||||
|
|
||||||
// If the init action is required, then check the it completed successfully.
|
/**
|
||||||
if (requireInitActionHasRun && process.env[sharedEnv.CODEQL_ACTION_INIT_COMPLETED] === undefined) {
|
* Are we running against a GitHub Enterpise instance, as opposed to github.com.
|
||||||
core.setFailed('The CodeQL ' + actionName + ' action cannot be used unless the CodeQL init action is run first. Aborting.');
|
*/
|
||||||
return true;
|
export function isEnterprise(): boolean {
|
||||||
}
|
return getInstanceAPIURL() !== GITHUB_DOTCOM_API_URL;
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,6 +39,26 @@ export function getRequiredEnvParam(paramName: string): string {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isLocalRun(): boolean {
|
||||||
|
return !!process.env.CODEQL_LOCAL_RUN
|
||||||
|
&& process.env.CODEQL_LOCAL_RUN !== 'false'
|
||||||
|
&& process.env.CODEQL_LOCAL_RUN !== '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures all required environment variables are set in the context of a local run.
|
||||||
|
*/
|
||||||
|
export function prepareLocalRunEnvironment() {
|
||||||
|
if (!isLocalRun()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
core.debug('Action is running locally.');
|
||||||
|
if (!process.env.GITHUB_JOB) {
|
||||||
|
core.exportVariable('GITHUB_JOB', 'UNKNOWN-JOB');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the SHA of the commit that is currently checked out.
|
* Gets the SHA of the commit that is currently checked out.
|
||||||
*/
|
*/
|
||||||
@@ -75,6 +90,9 @@ export async function getCommitOid(): Promise<string> {
|
|||||||
* Get the path of the currently executing workflow.
|
* Get the path of the currently executing workflow.
|
||||||
*/
|
*/
|
||||||
async function getWorkflowPath(): Promise<string> {
|
async function getWorkflowPath(): Promise<string> {
|
||||||
|
if (isLocalRun()) {
|
||||||
|
return 'LOCAL';
|
||||||
|
}
|
||||||
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];
|
||||||
@@ -101,7 +119,9 @@ async function getWorkflowPath(): Promise<string> {
|
|||||||
* the github API, but after that the result will be cached.
|
* the github API, but after that the result will be cached.
|
||||||
*/
|
*/
|
||||||
export async function getAnalysisKey(): Promise<string> {
|
export async function getAnalysisKey(): Promise<string> {
|
||||||
let analysisKey = process.env[sharedEnv.CODEQL_ACTION_ANALYSIS_KEY];
|
const analysisKeyEnvVar = 'CODEQL_ACTION_ANALYSIS_KEY';
|
||||||
|
|
||||||
|
let analysisKey = process.env[analysisKeyEnvVar];
|
||||||
if (analysisKey !== undefined) {
|
if (analysisKey !== undefined) {
|
||||||
return analysisKey;
|
return analysisKey;
|
||||||
}
|
}
|
||||||
@@ -110,7 +130,7 @@ export async function getAnalysisKey(): Promise<string> {
|
|||||||
const jobName = getRequiredEnvParam('GITHUB_JOB');
|
const jobName = getRequiredEnvParam('GITHUB_JOB');
|
||||||
|
|
||||||
analysisKey = workflowPath + ':' + jobName;
|
analysisKey = workflowPath + ':' + jobName;
|
||||||
core.exportVariable(sharedEnv.CODEQL_ACTION_ANALYSIS_KEY, analysisKey);
|
core.exportVariable(analysisKeyEnvVar, analysisKey);
|
||||||
return analysisKey;
|
return analysisKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +166,8 @@ export interface StatusReportBase {
|
|||||||
"job_name": string;
|
"job_name": string;
|
||||||
// Analysis key, normally composed from the workflow path and job name
|
// Analysis key, normally composed from the workflow path and job name
|
||||||
"analysis_key": string;
|
"analysis_key": string;
|
||||||
|
// Value of the matrix for this instantiation of the job
|
||||||
|
"matrix_vars"?: string;
|
||||||
// Commit oid that the workflow was triggered on
|
// Commit oid that the workflow was triggered on
|
||||||
"commit_oid": string;
|
"commit_oid": string;
|
||||||
// Ref that the workflow was triggered on
|
// Ref that the workflow was triggered on
|
||||||
@@ -227,7 +249,7 @@ export async function createStatusReportBase(
|
|||||||
}
|
}
|
||||||
let matrix: string | undefined = core.getInput('matrix');
|
let matrix: string | undefined = core.getInput('matrix');
|
||||||
if (matrix) {
|
if (matrix) {
|
||||||
// Temporarily do nothing.
|
statusReport.matrix_vars = matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
return statusReport;
|
return statusReport;
|
||||||
@@ -246,8 +268,17 @@ export async function sendStatusReport<S extends StatusReportBase>(
|
|||||||
statusReport: S,
|
statusReport: S,
|
||||||
ignoreFailures?: boolean): Promise<boolean> {
|
ignoreFailures?: boolean): Promise<boolean> {
|
||||||
|
|
||||||
const statusReportJSON = JSON.stringify(statusReport);
|
if (isEnterprise()) {
|
||||||
|
core.debug("Not sending status report to GitHub Enterprise");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLocalRun()) {
|
||||||
|
core.debug("Not sending status report because this is a local run");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusReportJSON = JSON.stringify(statusReport);
|
||||||
core.debug('Sending status report: ' + statusReportJSON);
|
core.debug('Sending status report: ' + statusReportJSON);
|
||||||
|
|
||||||
const nwo = getRequiredEnvParam("GITHUB_REPOSITORY");
|
const nwo = getRequiredEnvParam("GITHUB_REPOSITORY");
|
||||||
@@ -359,3 +390,10 @@ export function getThreadsFlag(): string {
|
|||||||
}
|
}
|
||||||
return `--threads=${numThreads}`;
|
return `--threads=${numThreads}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the directory where CodeQL databases should be placed.
|
||||||
|
*/
|
||||||
|
export function getCodeQLDatabasesDir() {
|
||||||
|
return path.resolve(getRequiredEnvParam('RUNNER_TEMP'), 'codeql_databases');
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user