Merge pull request #3064 from github/mbg/cq/allow-cq-only-analysis

Allow Code Quality only analysis
This commit is contained in:
Michael B. Gale
2025-09-08 16:13:19 +01:00
committed by GitHub
28 changed files with 929 additions and 470 deletions

View File

@@ -32,16 +32,58 @@ jobs:
include:
- os: ubuntu-latest
version: linked
analysis-kinds: code-scanning
- os: ubuntu-latest
version: linked
analysis-kinds: code-quality
- os: ubuntu-latest
version: linked
analysis-kinds: code-scanning,code-quality
- os: macos-latest
version: linked
analysis-kinds: code-scanning
- os: macos-latest
version: linked
analysis-kinds: code-quality
- os: macos-latest
version: linked
analysis-kinds: code-scanning,code-quality
- os: windows-latest
version: linked
analysis-kinds: code-scanning
- os: windows-latest
version: linked
analysis-kinds: code-quality
- os: windows-latest
version: linked
analysis-kinds: code-scanning,code-quality
- os: ubuntu-latest
version: nightly-latest
analysis-kinds: code-scanning
- os: ubuntu-latest
version: nightly-latest
analysis-kinds: code-quality
- os: ubuntu-latest
version: nightly-latest
analysis-kinds: code-scanning,code-quality
- os: macos-latest
version: nightly-latest
analysis-kinds: code-scanning
- os: macos-latest
version: nightly-latest
analysis-kinds: code-quality
- os: macos-latest
version: nightly-latest
analysis-kinds: code-scanning,code-quality
- os: windows-latest
version: nightly-latest
analysis-kinds: code-scanning
- os: windows-latest
version: nightly-latest
analysis-kinds: code-quality
- os: windows-latest
version: nightly-latest
analysis-kinds: code-scanning,code-quality
name: Quality queries input
permissions:
contents: read
@@ -61,25 +103,30 @@ jobs:
- uses: ./../action/init
with:
languages: javascript
quality-queries: code-quality
analysis-kinds: ${{ matrix.analysis-kinds }}
tools: ${{ steps.prepare-test.outputs.tools-url }}
- uses: ./../action/analyze
with:
output: ${{ runner.temp }}/results
upload-database: false
- name: Upload security SARIF
if: contains(matrix.analysis-kinds, 'code-scanning')
uses: actions/upload-artifact@v4
with:
name: quality-queries-${{ matrix.os }}-${{ matrix.version }}.sarif.json
name: |
quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.sarif.json
path: ${{ runner.temp }}/results/javascript.sarif
retention-days: 7
- name: Upload quality SARIF
if: contains(matrix.analysis-kinds, 'code-quality')
uses: actions/upload-artifact@v4
with:
name: quality-queries-${{ matrix.os }}-${{ matrix.version }}.quality.sarif.json
name: |
quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.quality.sarif.json
path: ${{ runner.temp }}/results/javascript.quality.sarif
retention-days: 7
- name: Check quality query does not appear in security SARIF
if: contains(matrix.analysis-kinds, 'code-scanning')
uses: actions/github-script@v7
env:
SARIF_PATH: ${{ runner.temp }}/results/javascript.sarif
@@ -87,6 +134,7 @@ jobs:
with:
script: ${{ env.CHECK_SCRIPT }}
- name: Check quality query appears in quality SARIF
if: contains(matrix.analysis-kinds, 'code-quality')
uses: actions/github-script@v7
env:
SARIF_PATH: ${{ runner.temp }}/results/javascript.quality.sarif

View File

@@ -73,7 +73,7 @@ jobs:
languages: cpp,csharp,java,javascript,python
config-file: ${{ github.repository }}/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{
github.sha }}
quality-queries: code-quality
analysis-kinds: code-scanning,code-quality
- name: Build code
shell: bash
run: ./build.sh

View File

@@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -31821,14 +31821,14 @@ var require_typeGuards = __commonJS({
"node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) {
"use strict";
Object.defineProperty(exports2, "__esModule", { value: true });
exports2.isDefined = isDefined;
exports2.isDefined = isDefined2;
exports2.isObjectWithProperties = isObjectWithProperties;
exports2.objectHasProperty = objectHasProperty;
function isDefined(thing) {
function isDefined2(thing) {
return typeof thing !== "undefined" && thing !== null;
}
function isObjectWithProperties(thing, properties) {
if (!isDefined(thing) || typeof thing !== "object") {
if (!isDefined2(thing) || typeof thing !== "object") {
return false;
}
for (const property of properties) {
@@ -31839,7 +31839,7 @@ var require_typeGuards = __commonJS({
return true;
}
function objectHasProperty(thing, property) {
return isDefined(thing) && typeof thing === "object" && property in thing;
return isDefined2(thing) && typeof thing === "object" && property in thing;
}
}
});
@@ -102910,7 +102910,7 @@ var require_dist_node16 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -102918,7 +102918,7 @@ var require_dist_node16 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -102928,12 +102928,12 @@ var require_dist_node16 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(encodeValue(operator, value2, isKeyOperator(operator) ? key : ""));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -102941,12 +102941,12 @@ var require_dist_node16 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -102961,7 +102961,7 @@ var require_dist_node16 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {

170
lib/analyze-action.js generated
View File

@@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -37670,14 +37670,14 @@ var require_typeGuards = __commonJS({
"node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) {
"use strict";
Object.defineProperty(exports2, "__esModule", { value: true });
exports2.isDefined = isDefined;
exports2.isDefined = isDefined2;
exports2.isObjectWithProperties = isObjectWithProperties;
exports2.objectHasProperty = objectHasProperty;
function isDefined(thing) {
function isDefined2(thing) {
return typeof thing !== "undefined" && thing !== null;
}
function isObjectWithProperties(thing, properties) {
if (!isDefined(thing) || typeof thing !== "object") {
if (!isDefined2(thing) || typeof thing !== "object") {
return false;
}
for (const property of properties) {
@@ -37688,7 +37688,7 @@ var require_typeGuards = __commonJS({
return true;
}
function objectHasProperty(thing, property) {
return isDefined(thing) && typeof thing === "object" && property in thing;
return isDefined2(thing) && typeof thing === "object" && property in thing;
}
}
});
@@ -90113,12 +90113,6 @@ function fixCodeQualityCategory(logger, category) {
return category;
}
// src/analyze.ts
var fs15 = __toESM(require("fs"));
var path16 = __toESM(require("path"));
var import_perf_hooks2 = require("perf_hooks");
var io5 = __toESM(require_io());
// src/analyses.ts
var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => {
AnalysisKind2["CodeScanning"] = "code-scanning";
@@ -90127,6 +90121,28 @@ var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => {
})(AnalysisKind || {});
var supportedAnalysisKinds = new Set(Object.values(AnalysisKind));
var codeQualityQueries = ["code-quality"];
var CodeScanning = {
kind: "code-scanning" /* CodeScanning */,
name: "code scanning",
target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */,
sarifExtension: ".sarif",
sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name),
sentinelPrefix: "CODEQL_UPLOAD_SARIF_"
};
var CodeQuality = {
kind: "code-quality" /* CodeQuality */,
name: "code quality",
target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */,
sarifExtension: ".quality.sarif",
sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension),
sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_"
};
// src/analyze.ts
var fs15 = __toESM(require("fs"));
var path16 = __toESM(require("path"));
var import_perf_hooks2 = require("perf_hooks");
var io5 = __toESM(require_io());
// src/api-client.ts
var core5 = __toESM(require_core());
@@ -91624,9 +91640,18 @@ function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) {
}
return augmentedConfig;
}
function isCodeScanningEnabled(config) {
return config.analysisKinds.includes("code-scanning" /* CodeScanning */);
}
function isCodeQualityEnabled(config) {
return config.analysisKinds.includes("code-quality" /* CodeQuality */);
}
function getPrimaryAnalysisKind(config) {
return isCodeScanningEnabled(config) ? "code-scanning" /* CodeScanning */ : "code-quality" /* CodeQuality */;
}
function getPrimaryAnalysisConfig(config) {
return getPrimaryAnalysisKind(config) === "code-scanning" /* CodeScanning */ ? CodeScanning : CodeQuality;
}
// src/setup-codeql.ts
var fs12 = __toESM(require("fs"));
@@ -93583,6 +93608,9 @@ function resolveQuerySuiteAlias(language, maybeSuite) {
}
return maybeSuite;
}
function addSarifExtension(analysis, base) {
return `${base}${analysis.sarifExtension}`;
}
async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, diffRangePackDir, automationDetailsId, codeql, config, logger, features) {
const statusReport = {};
const queryFlags = [memoryFlag, threadsFlag];
@@ -93602,14 +93630,16 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag,
incrementalMode.push("overlay");
}
const sarifRunPropertyFlag = incrementalMode.length > 0 ? `--sarif-run-property=incrementalMode=${incrementalMode.join(",")}` : void 0;
const dbAnalysisConfig = getPrimaryAnalysisConfig(config);
for (const language of config.languages) {
try {
const sarifFile = path16.join(sarifFolder, `${language}.sarif`);
const queries = [];
if (isCodeQualityEnabled(config)) {
if (config.analysisKinds.length > 1) {
queries.push(getGeneratedSuitePath(config, language));
for (const qualityQuery of codeQualityQueries) {
queries.push(resolveQuerySuiteAlias(language, qualityQuery));
if (isCodeQualityEnabled(config)) {
for (const qualityQuery of codeQualityQueries) {
queries.push(resolveQuerySuiteAlias(language, qualityQuery));
}
}
}
logger.startGroup(`Running queries for ${language}`);
@@ -93618,35 +93648,24 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag,
await codeql.databaseRunQueries(databasePath, queryFlags, queries);
logger.debug(`Finished running queries for ${language}.`);
statusReport[`analyze_builtin_queries_${language}_duration_ms`] = (/* @__PURE__ */ new Date()).getTime() - startTimeRunQueries;
logger.startGroup(`Interpreting results for ${language}`);
const startTimeInterpretResults = /* @__PURE__ */ new Date();
const analysisSummary = await runInterpretResults(
const { summary: analysisSummary, sarifFile } = await runInterpretResultsFor(
dbAnalysisConfig,
language,
void 0,
sarifFile,
config.debugMode,
automationDetailsId
config.debugMode
);
let qualityAnalysisSummary;
if (isCodeQualityEnabled(config)) {
logger.info(`Interpreting quality results for ${language}`);
const qualityCategory = fixCodeQualityCategory(
logger,
automationDetailsId
);
const qualitySarifFile = path16.join(
sarifFolder,
`${language}.quality.sarif`
);
qualityAnalysisSummary = await runInterpretResults(
if (config.analysisKinds.length > 1 && isCodeQualityEnabled(config)) {
const qualityResult = await runInterpretResultsFor(
CodeQuality,
language,
codeQualityQueries.map(
(i) => resolveQuerySuiteAlias(language, i)
),
qualitySarifFile,
config.debugMode,
qualityCategory
config.debugMode
);
qualityAnalysisSummary = qualityResult.summary;
}
const endTimeInterpretResults = /* @__PURE__ */ new Date();
statusReport[`interpret_results_${language}_duration_ms`] = endTimeInterpretResults.getTime() - startTimeInterpretResults.getTime();
@@ -93682,6 +93701,25 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag,
}
}
return statusReport;
async function runInterpretResultsFor(analysis, language, queries, enableDebugLogging) {
logger.info(`Interpreting ${analysis.name} results for ${language}`);
let category = automationDetailsId;
if (dbAnalysisConfig.kind === "code-quality" /* CodeQuality */) {
category = fixCodeQualityCategory(logger, automationDetailsId);
}
const sarifFile = path16.join(
sarifFolder,
addSarifExtension(analysis, language)
);
const summary = await runInterpretResults(
language,
queries,
sarifFile,
enableDebugLogging,
category
);
return { summary, sarifFile };
}
async function runInterpretResults(language, queries, sarifFile, enableDebugLogging, category) {
const databasePath = getCodeQLDatabasePath(config, language);
return await codeql.databaseInterpretResults(
@@ -95521,18 +95559,6 @@ function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, wo
}
return payloadObj;
}
var CodeScanningTarget = {
name: "code scanning",
target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */,
sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name),
sentinelPrefix: "CODEQL_UPLOAD_SARIF_"
};
var CodeQualityTarget = {
name: "code quality",
target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */,
sarifPredicate: (name) => name.endsWith(".quality.sarif"),
sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_"
};
async function uploadFiles(inputSarifPath, checkoutPath, category, features, logger, uploadTarget) {
const sarifPaths = getSarifFilePaths(
inputSarifPath,
@@ -95547,7 +95573,7 @@ async function uploadFiles(inputSarifPath, checkoutPath, category, features, log
uploadTarget
);
}
async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanningTarget) {
async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget) {
logger.startGroup(`Uploading ${uploadTarget.name} results`);
logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`);
const gitHubVersion = await getGitHubVersion();
@@ -95718,7 +95744,7 @@ function handleProcessingResultForUnsuccessfulExecution(response, status, logger
assertNever(status);
}
}
function validateUniqueCategory(sarif, sentinelPrefix = CodeScanningTarget.sentinelPrefix) {
function validateUniqueCategory(sarif, sentinelPrefix) {
const categories = {};
for (const run2 of sarif.runs) {
const id = run2?.automationDetails?.id;
@@ -95968,15 +95994,17 @@ async function run() {
core14.setOutput("sarif-output", import_path4.default.resolve(outputDir));
const uploadInput = getOptionalInput("upload");
if (runStats && getUploadValue(uploadInput) === "always") {
uploadResult = await uploadFiles(
outputDir,
getRequiredInput("checkout_path"),
getOptionalInput("category"),
features,
logger,
CodeScanningTarget
);
core14.setOutput("sarif-id", uploadResult.sarifID);
if (isCodeScanningEnabled(config)) {
uploadResult = await uploadFiles(
outputDir,
getRequiredInput("checkout_path"),
getOptionalInput("category"),
features,
logger,
CodeScanning
);
core14.setOutput("sarif-id", uploadResult.sarifID);
}
if (isCodeQualityEnabled(config)) {
const qualityUploadResult = await uploadFiles(
outputDir,
@@ -95987,7 +96015,7 @@ async function run() {
),
features,
logger,
CodeQualityTarget
CodeQuality
);
core14.setOutput("quality-sarif-id", qualityUploadResult.sarifID);
}

View File

@@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -31821,14 +31821,14 @@ var require_typeGuards = __commonJS({
"node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) {
"use strict";
Object.defineProperty(exports2, "__esModule", { value: true });
exports2.isDefined = isDefined;
exports2.isDefined = isDefined2;
exports2.isObjectWithProperties = isObjectWithProperties;
exports2.objectHasProperty = objectHasProperty;
function isDefined(thing) {
function isDefined2(thing) {
return typeof thing !== "undefined" && thing !== null;
}
function isObjectWithProperties(thing, properties) {
if (!isDefined(thing) || typeof thing !== "object") {
if (!isDefined2(thing) || typeof thing !== "object") {
return false;
}
for (const property of properties) {
@@ -31839,7 +31839,7 @@ var require_typeGuards = __commonJS({
return true;
}
function objectHasProperty(thing, property) {
return isDefined(thing) && typeof thing === "object" && property in thing;
return isDefined2(thing) && typeof thing === "object" && property in thing;
}
}
});

View File

@@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({
}
function getValues(context3, operator, key, modifier) {
var value = context3[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({
}
function getValues(context3, operator, key, modifier) {
var value = context3[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -37670,14 +37670,14 @@ var require_typeGuards = __commonJS({
"node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) {
"use strict";
Object.defineProperty(exports2, "__esModule", { value: true });
exports2.isDefined = isDefined;
exports2.isDefined = isDefined2;
exports2.isObjectWithProperties = isObjectWithProperties;
exports2.objectHasProperty = objectHasProperty;
function isDefined(thing) {
function isDefined2(thing) {
return typeof thing !== "undefined" && thing !== null;
}
function isObjectWithProperties(thing, properties) {
if (!isDefined(thing) || typeof thing !== "object") {
if (!isDefined2(thing) || typeof thing !== "object") {
return false;
}
for (const property of properties) {
@@ -37688,7 +37688,7 @@ var require_typeGuards = __commonJS({
return true;
}
function objectHasProperty(thing, property) {
return isDefined(thing) && typeof thing === "object" && property in thing;
return isDefined2(thing) && typeof thing === "object" && property in thing;
}
}
});
@@ -108759,7 +108759,7 @@ var require_dist_node16 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -108767,7 +108767,7 @@ var require_dist_node16 = __commonJS({
}
function getValues(context3, operator, key, modifier) {
var value = context3[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -108777,12 +108777,12 @@ var require_dist_node16 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(encodeValue(operator, value2, isKeyOperator(operator) ? key : ""));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -108790,12 +108790,12 @@ var require_dist_node16 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -108810,7 +108810,7 @@ var require_dist_node16 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -128754,6 +128754,22 @@ var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => {
return AnalysisKind2;
})(AnalysisKind || {});
var supportedAnalysisKinds = new Set(Object.values(AnalysisKind));
var CodeScanning = {
kind: "code-scanning" /* CodeScanning */,
name: "code scanning",
target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */,
sarifExtension: ".sarif",
sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name),
sentinelPrefix: "CODEQL_UPLOAD_SARIF_"
};
var CodeQuality = {
kind: "code-quality" /* CodeQuality */,
name: "code quality",
target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */,
sarifExtension: ".quality.sarif",
sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension),
sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_"
};
// src/caching-utils.ts
var core6 = __toESM(require_core());
@@ -132980,18 +132996,6 @@ function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, wo
}
return payloadObj;
}
var CodeScanningTarget = {
name: "code scanning",
target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */,
sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name),
sentinelPrefix: "CODEQL_UPLOAD_SARIF_"
};
var CodeQualityTarget = {
name: "code quality",
target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */,
sarifPredicate: (name) => name.endsWith(".quality.sarif"),
sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_"
};
async function uploadFiles(inputSarifPath, checkoutPath, category, features, logger, uploadTarget) {
const sarifPaths = getSarifFilePaths(
inputSarifPath,
@@ -133006,7 +133010,7 @@ async function uploadFiles(inputSarifPath, checkoutPath, category, features, log
uploadTarget
);
}
async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanningTarget) {
async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget) {
logger.startGroup(`Uploading ${uploadTarget.name} results`);
logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`);
const gitHubVersion = await getGitHubVersion();
@@ -133177,7 +133181,7 @@ function handleProcessingResultForUnsuccessfulExecution(response, status, logger
assertNever(status);
}
}
function validateUniqueCategory(sarif, sentinelPrefix = CodeScanningTarget.sentinelPrefix) {
function validateUniqueCategory(sarif, sentinelPrefix) {
const categories = {};
for (const run2 of sarif.runs) {
const id = run2?.automationDetails?.id;
@@ -133402,7 +133406,7 @@ async function maybeUploadFailedSarif(config, repositoryNwo, features, logger) {
category,
features,
logger,
CodeScanningTarget
CodeScanning
);
await waitForProcessing(
repositoryNwo,

57
lib/init-action.js generated
View File

@@ -22196,7 +22196,7 @@ var require_dist_node2 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -22204,7 +22204,7 @@ var require_dist_node2 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -22216,14 +22216,14 @@ var require_dist_node2 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -22231,12 +22231,12 @@ var require_dist_node2 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -22251,7 +22251,7 @@ var require_dist_node2 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -22936,7 +22936,7 @@ var require_dist_node6 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -22944,7 +22944,7 @@ var require_dist_node6 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -22956,14 +22956,14 @@ var require_dist_node6 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -22971,12 +22971,12 @@ var require_dist_node6 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -22991,7 +22991,7 @@ var require_dist_node6 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -37670,14 +37670,14 @@ var require_typeGuards = __commonJS({
"node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) {
"use strict";
Object.defineProperty(exports2, "__esModule", { value: true });
exports2.isDefined = isDefined;
exports2.isDefined = isDefined2;
exports2.isObjectWithProperties = isObjectWithProperties;
exports2.objectHasProperty = objectHasProperty;
function isDefined(thing) {
function isDefined2(thing) {
return typeof thing !== "undefined" && thing !== null;
}
function isObjectWithProperties(thing, properties) {
if (!isDefined(thing) || typeof thing !== "object") {
if (!isDefined2(thing) || typeof thing !== "object") {
return false;
}
for (const property of properties) {
@@ -37688,7 +37688,7 @@ var require_typeGuards = __commonJS({
return true;
}
function objectHasProperty(thing, property) {
return isDefined(thing) && typeof thing === "object" && property in thing;
return isDefined2(thing) && typeof thing === "object" && property in thing;
}
}
});
@@ -85784,6 +85784,9 @@ async function asyncSome(array, predicate) {
const results = await Promise.all(array.map(predicate));
return results.some((result) => result);
}
function isDefined(value) {
return value !== void 0 && value !== null;
}
// src/actions-util.ts
var pkg = require_package();
@@ -86192,6 +86195,7 @@ async function parseAnalysisKinds(input) {
new Set(components.map((component) => component))
);
}
var codeQualityQueries = ["code-quality"];
// src/feature-flags.ts
var fs7 = __toESM(require("fs"));
@@ -87616,6 +87620,9 @@ function dbLocationOrDefault(dbLocation, tempDir) {
function userConfigFromActionPath(tempDir) {
return path10.resolve(tempDir, "user-config-from-action.yml");
}
function hasQueryCustomisation(userConfig) {
return isDefined(userConfig["disable-default-queries"]) || isDefined(userConfig.queries) || isDefined(userConfig["query-filters"]);
}
async function initConfig(inputs) {
const { logger, tempDir } = inputs;
if (inputs.configInput) {
@@ -87641,6 +87648,17 @@ async function initConfig(inputs) {
);
}
const config = await initActionState(inputs, userConfig);
if (config.analysisKinds.length === 1 && isCodeQualityEnabled(config)) {
if (hasQueryCustomisation(config.computedConfig)) {
throw new ConfigurationError(
"Query customizations are unsupported, because only `code-quality` analysis is enabled."
);
}
const queries = codeQualityQueries.map((v) => ({ uses: v }));
config.computedConfig["disable-default-queries"] = true;
config.computedConfig.queries = queries;
config.computedConfig["query-filters"] = [];
}
const { overlayDatabaseMode, useOverlayDatabaseCaching } = await getOverlayDatabaseMode(
inputs.codeql,
inputs.repository,
@@ -87874,6 +87892,9 @@ function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) {
}
return augmentedConfig;
}
function isCodeQualityEnabled(config) {
return config.analysisKinds.includes("code-quality" /* CodeQuality */);
}
// src/dependency-caching.ts
var os2 = __toESM(require("os"));

View File

@@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -31821,14 +31821,14 @@ var require_typeGuards = __commonJS({
"node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) {
"use strict";
Object.defineProperty(exports2, "__esModule", { value: true });
exports2.isDefined = isDefined;
exports2.isDefined = isDefined2;
exports2.isObjectWithProperties = isObjectWithProperties;
exports2.objectHasProperty = objectHasProperty;
function isDefined(thing) {
function isDefined2(thing) {
return typeof thing !== "undefined" && thing !== null;
}
function isObjectWithProperties(thing, properties) {
if (!isDefined(thing) || typeof thing !== "object") {
if (!isDefined2(thing) || typeof thing !== "object") {
return false;
}
for (const property of properties) {
@@ -31839,7 +31839,7 @@ var require_typeGuards = __commonJS({
return true;
}
function objectHasProperty(thing, property) {
return isDefined(thing) && typeof thing === "object" && property in thing;
return isDefined2(thing) && typeof thing === "object" && property in thing;
}
}
});

View File

@@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -31821,14 +31821,14 @@ var require_typeGuards = __commonJS({
"node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) {
"use strict";
Object.defineProperty(exports2, "__esModule", { value: true });
exports2.isDefined = isDefined;
exports2.isDefined = isDefined2;
exports2.isObjectWithProperties = isObjectWithProperties;
exports2.objectHasProperty = objectHasProperty;
function isDefined(thing) {
function isDefined2(thing) {
return typeof thing !== "undefined" && thing !== null;
}
function isObjectWithProperties(thing, properties) {
if (!isDefined(thing) || typeof thing !== "object") {
if (!isDefined2(thing) || typeof thing !== "object") {
return false;
}
for (const property of properties) {
@@ -31839,7 +31839,7 @@ var require_typeGuards = __commonJS({
return true;
}
function objectHasProperty(thing, property) {
return isDefined(thing) && typeof thing === "object" && property in thing;
return isDefined2(thing) && typeof thing === "object" && property in thing;
}
}
});
@@ -101570,7 +101570,7 @@ var require_dist_node16 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -101578,7 +101578,7 @@ var require_dist_node16 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -101588,12 +101588,12 @@ var require_dist_node16 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(encodeValue(operator, value2, isKeyOperator(operator) ? key : ""));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -101601,12 +101601,12 @@ var require_dist_node16 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -101621,7 +101621,7 @@ var require_dist_node16 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {

View File

@@ -47753,6 +47753,9 @@ async function delay(milliseconds, opts) {
function getErrorMessage(error2) {
return error2 instanceof Error ? error2.message : String(error2);
}
function isDefined(value) {
return value !== void 0 && value !== null;
}
// src/actions-util.ts
var pkg = require_package();
@@ -47825,9 +47828,6 @@ var LANGUAGE_TO_REGISTRY_TYPE = {
rust: ["cargo_registry"],
go: ["goproxy_server", "git_source"]
};
function isDefined(value) {
return value !== void 0 && value !== null;
}
function getCredentials(logger, registrySecrets, registriesCredentials, languageString) {
const language = languageString ? parseLanguage(languageString) : void 0;
const registryTypeForLanguage = language ? LANGUAGE_TO_REGISTRY_TYPE[language] : void 0;

63
lib/upload-lib.js generated
View File

@@ -21585,7 +21585,7 @@ var require_dist_node2 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -21593,7 +21593,7 @@ var require_dist_node2 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -21605,14 +21605,14 @@ var require_dist_node2 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -21620,12 +21620,12 @@ var require_dist_node2 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -21640,7 +21640,7 @@ var require_dist_node2 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -22325,7 +22325,7 @@ var require_dist_node6 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -22333,7 +22333,7 @@ var require_dist_node6 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -22345,14 +22345,14 @@ var require_dist_node6 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -22360,12 +22360,12 @@ var require_dist_node6 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -22380,7 +22380,7 @@ var require_dist_node6 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -38967,14 +38967,14 @@ var require_typeGuards = __commonJS({
"node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) {
"use strict";
Object.defineProperty(exports2, "__esModule", { value: true });
exports2.isDefined = isDefined;
exports2.isDefined = isDefined2;
exports2.isObjectWithProperties = isObjectWithProperties;
exports2.objectHasProperty = objectHasProperty;
function isDefined(thing) {
function isDefined2(thing) {
return typeof thing !== "undefined" && thing !== null;
}
function isObjectWithProperties(thing, properties) {
if (!isDefined(thing) || typeof thing !== "object") {
if (!isDefined2(thing) || typeof thing !== "object") {
return false;
}
for (const property of properties) {
@@ -38985,7 +38985,7 @@ var require_typeGuards = __commonJS({
return true;
}
function objectHasProperty(thing, property) {
return isDefined(thing) && typeof thing === "object" && property in thing;
return isDefined2(thing) && typeof thing === "object" && property in thing;
}
}
});
@@ -84778,10 +84778,7 @@ var require_sarif_schema_2_1_0 = __commonJS({
// src/upload-lib.ts
var upload_lib_exports = {};
__export(upload_lib_exports, {
CodeQualityTarget: () => CodeQualityTarget,
CodeScanningTarget: () => CodeScanningTarget,
InvalidSarifUploadError: () => InvalidSarifUploadError,
SARIF_UPLOAD_ENDPOINT: () => SARIF_UPLOAD_ENDPOINT,
buildPayload: () => buildPayload,
findSarifFilesInDir: () => findSarifFilesInDir,
getSarifFilePaths: () => getSarifFilePaths,
@@ -92203,11 +92200,6 @@ function getAutomationID2(category, analysis_key, environment) {
}
return computeAutomationID(analysis_key, environment);
}
var SARIF_UPLOAD_ENDPOINT = /* @__PURE__ */ ((SARIF_UPLOAD_ENDPOINT2) => {
SARIF_UPLOAD_ENDPOINT2["CODE_SCANNING"] = "PUT /repos/:owner/:repo/code-scanning/analysis";
SARIF_UPLOAD_ENDPOINT2["CODE_QUALITY"] = "PUT /repos/:owner/:repo/code-quality/analysis";
return SARIF_UPLOAD_ENDPOINT2;
})(SARIF_UPLOAD_ENDPOINT || {});
async function uploadPayload(payload, repositoryNwo, logger, target) {
logger.info("Uploading results");
if (isInTestMode()) {
@@ -92376,18 +92368,6 @@ function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, wo
}
return payloadObj;
}
var CodeScanningTarget = {
name: "code scanning",
target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */,
sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name),
sentinelPrefix: "CODEQL_UPLOAD_SARIF_"
};
var CodeQualityTarget = {
name: "code quality",
target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */,
sarifPredicate: (name) => name.endsWith(".quality.sarif"),
sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_"
};
async function uploadFiles(inputSarifPath, checkoutPath, category, features, logger, uploadTarget) {
const sarifPaths = getSarifFilePaths(
inputSarifPath,
@@ -92402,7 +92382,7 @@ async function uploadFiles(inputSarifPath, checkoutPath, category, features, log
uploadTarget
);
}
async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanningTarget) {
async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget) {
logger.startGroup(`Uploading ${uploadTarget.name} results`);
logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`);
const gitHubVersion = await getGitHubVersion();
@@ -92573,7 +92553,7 @@ function handleProcessingResultForUnsuccessfulExecution(response, status, logger
assertNever(status);
}
}
function validateUniqueCategory(sarif, sentinelPrefix = CodeScanningTarget.sentinelPrefix) {
function validateUniqueCategory(sarif, sentinelPrefix) {
const categories = {};
for (const run of sarif.runs) {
const id = run?.automationDetails?.id;
@@ -92630,10 +92610,7 @@ function filterAlertsByDiffRange(logger, sarif) {
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
CodeQualityTarget,
CodeScanningTarget,
InvalidSarifUploadError,
SARIF_UPLOAD_ENDPOINT,
buildPayload,
findSarifFilesInDir,
getSarifFilePaths,

View File

@@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -35658,14 +35658,14 @@ var require_typeGuards = __commonJS({
"node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) {
"use strict";
Object.defineProperty(exports2, "__esModule", { value: true });
exports2.isDefined = isDefined;
exports2.isDefined = isDefined2;
exports2.isObjectWithProperties = isObjectWithProperties;
exports2.objectHasProperty = objectHasProperty;
function isDefined(thing) {
function isDefined2(thing) {
return typeof thing !== "undefined" && thing !== null;
}
function isObjectWithProperties(thing, properties) {
if (!isDefined(thing) || typeof thing !== "object") {
if (!isDefined2(thing) || typeof thing !== "object") {
return false;
}
for (const property of properties) {
@@ -35676,7 +35676,7 @@ var require_typeGuards = __commonJS({
return true;
}
function objectHasProperty(thing, property) {
return isDefined(thing) && typeof thing === "object" && property in thing;
return isDefined2(thing) && typeof thing === "object" && property in thing;
}
}
});
@@ -95692,7 +95692,7 @@ var require_dist_node16 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -95700,7 +95700,7 @@ var require_dist_node16 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -95710,12 +95710,12 @@ var require_dist_node16 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(encodeValue(operator, value2, isKeyOperator(operator) ? key : ""));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -95723,12 +95723,12 @@ var require_dist_node16 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -95743,7 +95743,7 @@ var require_dist_node16 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {

View File

@@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({
return value;
}
}
function isDefined(value) {
function isDefined2(value) {
return value !== void 0 && value !== null;
}
function isKeyOperator(operator) {
@@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({
}
function getValues(context2, operator, key, modifier) {
var value = context2[key], result = [];
if (isDefined(value) && value !== "") {
if (isDefined2(value) && value !== "") {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
value = value.toString();
if (modifier && modifier !== "*") {
@@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({
} else {
if (modifier === "*") {
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
result.push(
encodeValue(operator, value2, isKeyOperator(operator) ? key : "")
);
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
result.push(encodeValue(operator, value[k], k));
}
});
@@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({
} else {
const tmp = [];
if (Array.isArray(value)) {
value.filter(isDefined).forEach(function(value2) {
value.filter(isDefined2).forEach(function(value2) {
tmp.push(encodeValue(operator, value2));
});
} else {
Object.keys(value).forEach(function(k) {
if (isDefined(value[k])) {
if (isDefined2(value[k])) {
tmp.push(encodeUnreserved(k));
tmp.push(encodeValue(operator, value[k].toString()));
}
@@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({
}
} else {
if (operator === ";") {
if (isDefined(value)) {
if (isDefined2(value)) {
result.push(encodeUnreserved(key));
}
} else if (value === "" && (operator === "&" || operator === "?")) {
@@ -37670,14 +37670,14 @@ var require_typeGuards = __commonJS({
"node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) {
"use strict";
Object.defineProperty(exports2, "__esModule", { value: true });
exports2.isDefined = isDefined;
exports2.isDefined = isDefined2;
exports2.isObjectWithProperties = isObjectWithProperties;
exports2.objectHasProperty = objectHasProperty;
function isDefined(thing) {
function isDefined2(thing) {
return typeof thing !== "undefined" && thing !== null;
}
function isObjectWithProperties(thing, properties) {
if (!isDefined(thing) || typeof thing !== "object") {
if (!isDefined2(thing) || typeof thing !== "object") {
return false;
}
for (const property of properties) {
@@ -37688,7 +37688,7 @@ var require_typeGuards = __commonJS({
return true;
}
function objectHasProperty(thing, property) {
return isDefined(thing) && typeof thing === "object" && property in thing;
return isDefined2(thing) && typeof thing === "object" && property in thing;
}
}
});
@@ -88718,6 +88718,30 @@ function fixCodeQualityCategory(logger, category) {
return category;
}
// src/analyses.ts
var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => {
AnalysisKind2["CodeScanning"] = "code-scanning";
AnalysisKind2["CodeQuality"] = "code-quality";
return AnalysisKind2;
})(AnalysisKind || {});
var supportedAnalysisKinds = new Set(Object.values(AnalysisKind));
var CodeScanning = {
kind: "code-scanning" /* CodeScanning */,
name: "code scanning",
target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */,
sarifExtension: ".sarif",
sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name),
sentinelPrefix: "CODEQL_UPLOAD_SARIF_"
};
var CodeQuality = {
kind: "code-quality" /* CodeQuality */,
name: "code quality",
target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */,
sarifExtension: ".quality.sarif",
sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension),
sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_"
};
// src/api-client.ts
var core5 = __toESM(require_core());
var githubUtils = __toESM(require_utils4());
@@ -89585,14 +89609,6 @@ var fs8 = __toESM(require("fs"));
var path10 = __toESM(require("path"));
var semver4 = __toESM(require_semver2());
// src/analyses.ts
var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => {
AnalysisKind2["CodeScanning"] = "code-scanning";
AnalysisKind2["CodeQuality"] = "code-quality";
return AnalysisKind2;
})(AnalysisKind || {});
var supportedAnalysisKinds = new Set(Object.values(AnalysisKind));
// src/caching-utils.ts
var core8 = __toESM(require_core());
@@ -93053,18 +93069,6 @@ function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, wo
}
return payloadObj;
}
var CodeScanningTarget = {
name: "code scanning",
target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */,
sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name),
sentinelPrefix: "CODEQL_UPLOAD_SARIF_"
};
var CodeQualityTarget = {
name: "code quality",
target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */,
sarifPredicate: (name) => name.endsWith(".quality.sarif"),
sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_"
};
async function uploadFiles(inputSarifPath, checkoutPath, category, features, logger, uploadTarget) {
const sarifPaths = getSarifFilePaths(
inputSarifPath,
@@ -93079,7 +93083,7 @@ async function uploadFiles(inputSarifPath, checkoutPath, category, features, log
uploadTarget
);
}
async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanningTarget) {
async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget) {
logger.startGroup(`Uploading ${uploadTarget.name} results`);
logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`);
const gitHubVersion = await getGitHubVersion();
@@ -93250,7 +93254,7 @@ function handleProcessingResultForUnsuccessfulExecution(response, status, logger
assertNever(status);
}
}
function validateUniqueCategory(sarif, sentinelPrefix = CodeScanningTarget.sentinelPrefix) {
function validateUniqueCategory(sarif, sentinelPrefix) {
const categories = {};
for (const run2 of sarif.runs) {
const id = run2?.automationDetails?.id;
@@ -93359,13 +93363,13 @@ async function run() {
category,
features,
logger,
CodeScanningTarget
CodeScanning
);
core13.setOutput("sarif-id", uploadResult.sarifID);
if (fs15.lstatSync(sarifPath).isDirectory()) {
const qualitySarifFiles = findSarifFilesInDir(
sarifPath,
CodeQualityTarget.sarifPredicate
CodeQuality.sarifPredicate
);
if (qualitySarifFiles.length !== 0) {
await uploadSpecifiedFiles(
@@ -93374,7 +93378,7 @@ async function run() {
fixCodeQualityCategory(logger, category),
features,
logger,
CodeQualityTarget
CodeQuality
);
}
}

View File

@@ -1,6 +1,7 @@
name: "Quality queries input"
description: "Tests that queries specified in the quality-queries input are used."
versions: ["linked", "nightly-latest"]
analysisKinds: ["code-scanning", "code-quality", "code-scanning,code-quality"]
env:
CHECK_SCRIPT: |
const fs = require('fs');
@@ -29,25 +30,30 @@ steps:
- uses: ./../action/init
with:
languages: javascript
quality-queries: code-quality
analysis-kinds: ${{ matrix.analysis-kinds }}
tools: ${{ steps.prepare-test.outputs.tools-url }}
- uses: ./../action/analyze
with:
output: "${{ runner.temp }}/results"
upload-database: false
- name: Upload security SARIF
if: contains(matrix.analysis-kinds, 'code-scanning')
uses: actions/upload-artifact@v4
with:
name: quality-queries-${{ matrix.os }}-${{ matrix.version }}.sarif.json
name: |
quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.sarif.json
path: "${{ runner.temp }}/results/javascript.sarif"
retention-days: 7
- name: Upload quality SARIF
if: contains(matrix.analysis-kinds, 'code-quality')
uses: actions/upload-artifact@v4
with:
name: quality-queries-${{ matrix.os }}-${{ matrix.version }}.quality.sarif.json
name: |
quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.quality.sarif.json
path: "${{ runner.temp }}/results/javascript.quality.sarif"
retention-days: 7
- name: Check quality query does not appear in security SARIF
if: contains(matrix.analysis-kinds, 'code-scanning')
uses: actions/github-script@v7
env:
SARIF_PATH: "${{ runner.temp }}/results/javascript.sarif"
@@ -55,6 +61,7 @@ steps:
with:
script: ${{ env.CHECK_SCRIPT }}
- name: Check quality query appears in quality SARIF
if: contains(matrix.analysis-kinds, 'code-quality')
uses: actions/github-script@v7
env:
SARIF_PATH: "${{ runner.temp }}/results/javascript.quality.sarif"

View File

@@ -8,7 +8,7 @@ steps:
tools: ${{ steps.prepare-test.outputs.tools-url }}
languages: cpp,csharp,java,javascript,python
config-file: ${{ github.repository }}/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{ github.sha }}
quality-queries: code-quality
analysis-kinds: code-scanning,code-quality
- name: Build code
shell: bash
run: ./build.sh

View File

@@ -102,6 +102,18 @@ for file in sorted((this_dir / 'checks').glob('*.yml')):
if checkSpecification.get('useAllPlatformBundle'):
useAllPlatformBundle = checkSpecification['useAllPlatformBundle']
if 'analysisKinds' in checkSpecification:
newMatrix = []
for matrixInclude in matrix:
for analysisKind in checkSpecification.get('analysisKinds'):
newMatrix.append(
matrixInclude |
{ 'analysis-kinds': analysisKind }
)
matrix = newMatrix
# Construct the workflow steps needed for this check.
steps = [
{
'name': 'Check out repository',

View File

@@ -41,3 +41,48 @@ export async function parseAnalysisKinds(
/** The queries to use for Code Quality analyses. */
export const codeQualityQueries: string[] = ["code-quality"];
// Enumerates API endpoints that accept SARIF files.
export enum SARIF_UPLOAD_ENDPOINT {
CODE_SCANNING = "PUT /repos/:owner/:repo/code-scanning/analysis",
CODE_QUALITY = "PUT /repos/:owner/:repo/code-quality/analysis",
}
// Represents configurations for different analysis kinds.
export interface AnalysisConfig {
/** The analysis kind the configuration is for. */
kind: AnalysisKind;
/** A display friendly name for logs. */
name: string;
/** The API endpoint to upload SARIF files to. */
target: SARIF_UPLOAD_ENDPOINT;
/** The file extension for SARIF files generated by this kind of analysis. */
sarifExtension: string;
/** A predicate on filenames to decide whether a SARIF file
* belongs to this kind of analysis. */
sarifPredicate: (name: string) => boolean;
/** A prefix for environment variables used to track the uniqueness of SARIF uploads. */
sentinelPrefix: string;
}
// Represents the Code Scanning analysis configuration.
export const CodeScanning: AnalysisConfig = {
kind: AnalysisKind.CodeScanning,
name: "code scanning",
target: SARIF_UPLOAD_ENDPOINT.CODE_SCANNING,
sarifExtension: ".sarif",
sarifPredicate: (name) =>
name.endsWith(CodeScanning.sarifExtension) &&
!CodeQuality.sarifPredicate(name),
sentinelPrefix: "CODEQL_UPLOAD_SARIF_",
};
// Represents the Code Quality analysis configuration.
export const CodeQuality: AnalysisConfig = {
kind: AnalysisKind.CodeQuality,
name: "code quality",
target: SARIF_UPLOAD_ENDPOINT.CODE_QUALITY,
sarifExtension: ".quality.sarif",
sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension),
sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_",
};

View File

@@ -5,6 +5,7 @@ import { performance } from "perf_hooks";
import * as core from "@actions/core";
import * as actionsUtil from "./actions-util";
import * as analyses from "./analyses";
import {
CodeQLAnalysisError,
dbIsFinalized,
@@ -18,7 +19,12 @@ import { getApiDetails, getGitHubVersion } from "./api-client";
import { runAutobuild } from "./autobuild";
import { getTotalCacheSize, shouldStoreCache } from "./caching-utils";
import { getCodeQL } from "./codeql";
import { Config, getConfig, isCodeQualityEnabled } from "./config-utils";
import {
Config,
getConfig,
isCodeQualityEnabled,
isCodeScanningEnabled,
} from "./config-utils";
import { uploadDatabases } from "./database-upload";
import { uploadDependencyCaches } from "./dependency-caching";
import { getDiffInformedAnalysisBranches } from "./diff-informed-analysis-utils";
@@ -326,15 +332,17 @@ async function run() {
core.setOutput("sarif-output", path.resolve(outputDir));
const uploadInput = actionsUtil.getOptionalInput("upload");
if (runStats && actionsUtil.getUploadValue(uploadInput) === "always") {
uploadResult = await uploadLib.uploadFiles(
outputDir,
actionsUtil.getRequiredInput("checkout_path"),
actionsUtil.getOptionalInput("category"),
features,
logger,
uploadLib.CodeScanningTarget,
);
core.setOutput("sarif-id", uploadResult.sarifID);
if (isCodeScanningEnabled(config)) {
uploadResult = await uploadLib.uploadFiles(
outputDir,
actionsUtil.getRequiredInput("checkout_path"),
actionsUtil.getOptionalInput("category"),
features,
logger,
analyses.CodeScanning,
);
core.setOutput("sarif-id", uploadResult.sarifID);
}
if (isCodeQualityEnabled(config)) {
const qualityUploadResult = await uploadLib.uploadFiles(
@@ -346,7 +354,7 @@ async function run() {
),
features,
logger,
uploadLib.CodeQualityTarget,
analyses.CodeQuality,
);
core.setOutput("quality-sarif-id", qualityUploadResult.sarifID);
}

View File

@@ -5,11 +5,13 @@ import test from "ava";
import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
import { CodeQuality, CodeScanning } from "./analyses";
import {
exportedForTesting,
runQueries,
defaultSuites,
resolveQuerySuiteAlias,
addSarifExtension,
} from "./analyze";
import { createStubCodeQL } from "./codeql";
import { Feature } from "./feature-flags";
@@ -348,3 +350,13 @@ test("resolveQuerySuiteAlias", (t) => {
t.deepEqual(resolveQuerySuiteAlias(KnownLanguage.go, name), name);
}
});
test("addSarifExtension", (t) => {
for (const language of Object.values(KnownLanguage)) {
t.deepEqual(addSarifExtension(CodeScanning, language), `${language}.sarif`);
t.deepEqual(
addSarifExtension(CodeQuality, language),
`${language}.quality.sarif`,
);
}
});

View File

@@ -608,6 +608,16 @@ export function resolveQuerySuiteAlias(
return maybeSuite;
}
/**
* Adds the appropriate file extension for the given analysis configuration to the given base filename.
*/
export function addSarifExtension(
analysis: analyses.AnalysisConfig,
base: string,
): string {
return `${base}${analysis.sarifExtension}`;
}
// Runs queries and creates sarif files in the given folder
export async function runQueries(
sarifFolder: string,
@@ -650,15 +660,25 @@ export async function runQueries(
? `--sarif-run-property=incrementalMode=${incrementalMode.join(",")}`
: undefined;
const dbAnalysisConfig = configUtils.getPrimaryAnalysisConfig(config);
for (const language of config.languages) {
try {
const sarifFile = path.join(sarifFolder, `${language}.sarif`);
// This should be empty to run only the query suite that was generated when
// the database was initialised.
const queries: string[] = [];
if (configUtils.isCodeQualityEnabled(config)) {
// If multiple analysis kinds are enabled, the database is initialised for Code Scanning.
// To avoid duplicate work, we want to run queries for all analyses at the same time.
// To do this, we invoke `run-queries` once with the generated query suite that was created
// when the database was initialised + the queries for other analysis kinds.
if (config.analysisKinds.length > 1) {
queries.push(util.getGeneratedSuitePath(config, language));
for (const qualityQuery of analyses.codeQualityQueries) {
queries.push(resolveQuerySuiteAlias(language, qualityQuery));
if (configUtils.isCodeQualityEnabled(config)) {
for (const qualityQuery of analyses.codeQualityQueries) {
queries.push(resolveQuerySuiteAlias(language, qualityQuery));
}
}
}
@@ -676,48 +696,49 @@ export async function runQueries(
statusReport[`analyze_builtin_queries_${language}_duration_ms`] =
new Date().getTime() - startTimeRunQueries;
logger.startGroup(`Interpreting results for ${language}`);
// There is always at least one analysis kind enabled. Running `interpret-results`
// produces the SARIF file for the analysis kind that the database was initialised with.
const startTimeInterpretResults = new Date();
const analysisSummary = await runInterpretResults(
language,
undefined,
sarifFile,
config.debugMode,
automationDetailsId,
);
const { summary: analysisSummary, sarifFile } =
await runInterpretResultsFor(
dbAnalysisConfig,
language,
undefined,
config.debugMode,
);
// This case is only needed if Code Quality is not the sole analysis kind.
// In this case, we will have run queries for all analysis kinds. The previous call to
// `interpret-results` will have produced a SARIF file for Code Scanning and we now
// need to produce an additional SARIF file for Code Quality.
let qualityAnalysisSummary: string | undefined;
if (configUtils.isCodeQualityEnabled(config)) {
logger.info(`Interpreting quality results for ${language}`);
const qualityCategory = fixCodeQualityCategory(
logger,
automationDetailsId,
);
const qualitySarifFile = path.join(
sarifFolder,
`${language}.quality.sarif`,
);
qualityAnalysisSummary = await runInterpretResults(
if (
config.analysisKinds.length > 1 &&
configUtils.isCodeQualityEnabled(config)
) {
const qualityResult = await runInterpretResultsFor(
analyses.CodeQuality,
language,
analyses.codeQualityQueries.map((i) =>
resolveQuerySuiteAlias(language, i),
),
qualitySarifFile,
config.debugMode,
qualityCategory,
);
qualityAnalysisSummary = qualityResult.summary;
}
const endTimeInterpretResults = new Date();
statusReport[`interpret_results_${language}_duration_ms`] =
endTimeInterpretResults.getTime() - startTimeInterpretResults.getTime();
logger.endGroup();
logger.info(analysisSummary);
logger.info(analysisSummary);
if (qualityAnalysisSummary) {
logger.info(qualityAnalysisSummary);
}
if (await features.getValue(Feature.QaTelemetryEnabled)) {
// Note: QA adds the `code-quality` query suite to the `queries` input,
// so this is fine since there is no `.quality.sarif`.
const perQueryAlertCounts = getPerQueryAlertCounts(sarifFile);
const perQueryAlertCountEventReport: EventReport = {
@@ -748,6 +769,37 @@ export async function runQueries(
return statusReport;
async function runInterpretResultsFor(
analysis: analyses.AnalysisConfig,
language: Language,
queries: string[] | undefined,
enableDebugLogging: boolean,
): Promise<{ summary: string; sarifFile: string }> {
logger.info(`Interpreting ${analysis.name} results for ${language}`);
// If this is a Code Quality analysis, correct the category to one
// accepted by the Code Quality backend.
let category = automationDetailsId;
if (dbAnalysisConfig.kind === analyses.AnalysisKind.CodeQuality) {
category = fixCodeQualityCategory(logger, automationDetailsId);
}
const sarifFile = path.join(
sarifFolder,
addSarifExtension(analysis, language),
);
const summary = await runInterpretResults(
language,
queries,
sarifFile,
enableDebugLogging,
category,
);
return { summary, sarifFile };
}
async function runInterpretResults(
language: Language,
queries: string[] | undefined,

View File

@@ -171,6 +171,63 @@ test("load empty config", async (t) => {
});
});
test("load code quality config", async (t) => {
return await withTmpDir(async (tempDir) => {
const logger = getRunnerLogger(true);
const languages = "actions";
const codeql = createStubCodeQL({
async betterResolveLanguages() {
return {
extractors: {
actions: [{ extractor_root: "" }],
},
};
},
});
const config = await configUtils.initConfig(
createTestInitConfigInputs({
analysisKindsInput: "code-quality",
languagesInput: languages,
repository: { owner: "github", repo: "example" },
tempDir,
codeql,
logger,
}),
);
// And the config we expect it to result in
const expectedConfig: configUtils.Config = {
analysisKinds: [AnalysisKind.CodeQuality],
languages: [KnownLanguage.actions],
buildMode: undefined,
originalUserInput: {},
// This gets set because we only have `AnalysisKind.CodeQuality`
computedConfig: {
"disable-default-queries": true,
queries: [{ uses: "code-quality" }],
"query-filters": [],
},
tempDir,
codeQLCmd: codeql.getPath(),
gitHubVersion: githubVersion,
dbLocation: path.resolve(tempDir, "codeql_databases"),
debugMode: false,
debugArtifactName: "",
debugDatabaseName: "",
trapCaches: {},
trapCacheDownloadTime: 0,
dependencyCachingEnabled: CachingKind.None,
extraQueryExclusions: [],
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
};
t.deepEqual(config, expectedConfig);
});
});
test("loading config saves config", async (t) => {
return await withTmpDir(async (tempDir) => {
const logger = getRunnerLogger(true);

View File

@@ -6,7 +6,14 @@ import * as yaml from "js-yaml";
import * as semver from "semver";
import { isAnalyzingPullRequest } from "./actions-util";
import { AnalysisKind, parseAnalysisKinds } from "./analyses";
import {
AnalysisConfig,
AnalysisKind,
CodeQuality,
codeQualityQueries,
CodeScanning,
parseAnalysisKinds,
} from "./analyses";
import * as api from "./api-client";
import { CachingKind, getCachingKind } from "./caching-utils";
import { type CodeQL } from "./codeql";
@@ -28,6 +35,7 @@ import {
BuildMode,
codeQlVersionAtLeast,
cloneObject,
isDefined,
} from "./util";
// Property names from the user-supplied config file.
@@ -1074,6 +1082,19 @@ function userConfigFromActionPath(tempDir: string): string {
return path.resolve(tempDir, "user-config-from-action.yml");
}
/**
* Checks whether the given `UserConfig` contains any query customisations.
*
* @returns Returns `true` if the `UserConfig` customises which queries are run.
*/
function hasQueryCustomisation(userConfig: UserConfig): boolean {
return (
isDefined(userConfig["disable-default-queries"]) ||
isDefined(userConfig.queries) ||
isDefined(userConfig["query-filters"])
);
}
/**
* Load and return the config.
*
@@ -1110,6 +1131,25 @@ export async function initConfig(inputs: InitConfigInputs): Promise<Config> {
const config = await initActionState(inputs, userConfig);
// If Code Quality analysis is the only enabled analysis kind, then we will initialise
// the database for Code Quality. That entails disabling the default queries and only
// running quality queries. We do not currently support query customisations in that case.
if (config.analysisKinds.length === 1 && isCodeQualityEnabled(config)) {
// Warn if any query customisations are present in the computed configuration.
if (hasQueryCustomisation(config.computedConfig)) {
throw new ConfigurationError(
"Query customizations are unsupported, because only `code-quality` analysis is enabled.",
);
}
const queries = codeQualityQueries.map((v) => ({ uses: v }));
// Set the query customisation options for Code Quality only analysis.
config.computedConfig["disable-default-queries"] = true;
config.computedConfig.queries = queries;
config.computedConfig["query-filters"] = [];
}
// The choice of overlay database mode depends on the selection of languages
// and queries, which in turn depends on the user config and the augmentation
// properties. So we need to calculate the overlay database mode after the
@@ -1509,9 +1549,41 @@ export function appendExtraQueryExclusions(
return augmentedConfig;
}
/**
* Returns `true` if Code Scanning analysis is enabled, or `false` if not.
*/
export function isCodeScanningEnabled(config: Config): boolean {
return config.analysisKinds.includes(AnalysisKind.CodeScanning);
}
/**
* Returns `true` if Code Quality analysis is enabled, or `false` if not.
*/
export function isCodeQualityEnabled(config: Config): boolean {
return config.analysisKinds.includes(AnalysisKind.CodeQuality);
}
/**
* Returns the primary analysis kind that the Action is initialised with. This is
* always `AnalysisKind.CodeScanning` unless `AnalysisKind.CodeScanning` is not enabled.
*
* @returns Returns `AnalysisKind.CodeScanning` if `AnalysisKind.CodeScanning` is enabled;
* otherwise `AnalysisKind.CodeQuality`.
*/
export function getPrimaryAnalysisKind(config: Config): AnalysisKind {
return isCodeScanningEnabled(config)
? AnalysisKind.CodeScanning
: AnalysisKind.CodeQuality;
}
/**
* Returns the primary analysis configuration that the Action is initialised with. This is
* always `CodeScanning` unless `CodeScanning` is not enabled.
*
* @returns Returns `CodeScanning` if `AnalysisKind.CodeScanning` is enabled; otherwise `CodeQuality`.
*/
export function getPrimaryAnalysisConfig(config: Config): AnalysisConfig {
return getPrimaryAnalysisKind(config) === AnalysisKind.CodeScanning
? CodeScanning
: CodeQuality;
}

View File

@@ -4,6 +4,7 @@ import * as core from "@actions/core";
import * as github from "@actions/github";
import * as actionsUtil from "./actions-util";
import { CodeScanning } from "./analyses";
import { getApiClient } from "./api-client";
import { CodeQL, getCodeQL } from "./codeql";
import { Config } from "./config-utils";
@@ -104,7 +105,7 @@ async function maybeUploadFailedSarif(
category,
features,
logger,
uploadLib.CodeScanningTarget,
CodeScanning,
);
await uploadLib.waitForProcessing(
repositoryNwo,

View File

@@ -2,7 +2,7 @@ import * as core from "@actions/core";
import { KnownLanguage } from "./languages";
import { Logger } from "./logging";
import { ConfigurationError } from "./util";
import { ConfigurationError, isDefined } from "./util";
export type Credential = {
type: string;
@@ -65,15 +65,6 @@ const LANGUAGE_TO_REGISTRY_TYPE: Partial<Record<KnownLanguage, string[]>> = {
go: ["goproxy_server", "git_source"],
} as const;
/**
* Checks that `value` is neither `undefined` nor `null`.
* @param value The value to test.
* @returns Narrows the type of `value` to exclude `undefined` and `null`.
*/
function isDefined<T>(value: T | null | undefined): value is T {
return value !== undefined && value !== null;
}
// getCredentials returns registry credentials from action inputs.
// It prefers `registries_credentials` over `registry_secrets`.
// If neither is set, it returns an empty array.

View File

@@ -3,6 +3,7 @@ import * as path from "path";
import test from "ava";
import { CodeQuality, CodeScanning } from "./analyses";
import { getRunnerLogger, Logger } from "./logging";
import { setupTests } from "./testing-utils";
import * as uploadLib from "./upload-lib";
@@ -128,7 +129,7 @@ test("finding SARIF files", async (t) => {
const sarifFiles = uploadLib.findSarifFilesInDir(
tmpDir,
uploadLib.CodeScanningTarget.sarifPredicate,
CodeScanning.sarifPredicate,
);
t.deepEqual(sarifFiles, [
@@ -140,7 +141,7 @@ test("finding SARIF files", async (t) => {
const qualitySarifFiles = uploadLib.findSarifFilesInDir(
tmpDir,
uploadLib.CodeQualityTarget.sarifPredicate,
CodeQuality.sarifPredicate,
);
t.deepEqual(qualitySarifFiles, [
@@ -211,109 +212,237 @@ test("populateRunAutomationDetails", (t) => {
});
test("validateUniqueCategory when empty", (t) => {
t.notThrows(() => uploadLib.validateUniqueCategory(createMockSarif()));
t.throws(() => uploadLib.validateUniqueCategory(createMockSarif()));
t.notThrows(() =>
uploadLib.validateUniqueCategory(
createMockSarif(),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(
createMockSarif(),
CodeScanning.sentinelPrefix,
),
);
});
test("validateUniqueCategory for automation details id", (t) => {
t.notThrows(() => uploadLib.validateUniqueCategory(createMockSarif("abc")));
t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc")));
t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("AbC")));
t.notThrows(() =>
uploadLib.validateUniqueCategory(
createMockSarif("abc"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(
createMockSarif("abc"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(
createMockSarif("AbC"),
CodeScanning.sentinelPrefix,
),
);
t.notThrows(() => uploadLib.validateUniqueCategory(createMockSarif("def")));
t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("def")));
t.notThrows(() =>
uploadLib.validateUniqueCategory(
createMockSarif("def"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(
createMockSarif("def"),
CodeScanning.sentinelPrefix,
),
);
// Our category sanitization is not perfect. Here are some examples
// of where we see false clashes
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif("abc/def")),
uploadLib.validateUniqueCategory(
createMockSarif("abc/def"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(
createMockSarif("abc@def"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(
createMockSarif("abc_def"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(
createMockSarif("abc def"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc@def")));
t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc_def")));
t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc def")));
// this one is fine
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif("abc_ def")),
uploadLib.validateUniqueCategory(
createMockSarif("abc_ def"),
CodeScanning.sentinelPrefix,
),
);
});
test("validateUniqueCategory for tool name", (t) => {
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc")),
uploadLib.validateUniqueCategory(
createMockSarif(undefined, "abc"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc")),
uploadLib.validateUniqueCategory(
createMockSarif(undefined, "abc"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "AbC")),
uploadLib.validateUniqueCategory(
createMockSarif(undefined, "AbC"),
CodeScanning.sentinelPrefix,
),
);
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "def")),
uploadLib.validateUniqueCategory(
createMockSarif(undefined, "def"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "def")),
uploadLib.validateUniqueCategory(
createMockSarif(undefined, "def"),
CodeScanning.sentinelPrefix,
),
);
// Our category sanitization is not perfect. Here are some examples
// of where we see false clashes
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc/def")),
uploadLib.validateUniqueCategory(
createMockSarif(undefined, "abc/def"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc@def")),
uploadLib.validateUniqueCategory(
createMockSarif(undefined, "abc@def"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc_def")),
uploadLib.validateUniqueCategory(
createMockSarif(undefined, "abc_def"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc def")),
uploadLib.validateUniqueCategory(
createMockSarif(undefined, "abc def"),
CodeScanning.sentinelPrefix,
),
);
// this one is fine
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif("abc_ def")),
uploadLib.validateUniqueCategory(
createMockSarif("abc_ def"),
CodeScanning.sentinelPrefix,
),
);
});
test("validateUniqueCategory for automation details id and tool name", (t) => {
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif("abc", "abc")),
uploadLib.validateUniqueCategory(
createMockSarif("abc", "abc"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif("abc", "abc")),
uploadLib.validateUniqueCategory(
createMockSarif("abc", "abc"),
CodeScanning.sentinelPrefix,
),
);
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif("abc_", "def")),
uploadLib.validateUniqueCategory(
createMockSarif("abc_", "def"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif("abc_", "def")),
uploadLib.validateUniqueCategory(
createMockSarif("abc_", "def"),
CodeScanning.sentinelPrefix,
),
);
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif("ghi", "_jkl")),
uploadLib.validateUniqueCategory(
createMockSarif("ghi", "_jkl"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif("ghi", "_jkl")),
uploadLib.validateUniqueCategory(
createMockSarif("ghi", "_jkl"),
CodeScanning.sentinelPrefix,
),
);
// Our category sanitization is not perfect. Here are some examples
// of where we see false clashes
t.notThrows(() => uploadLib.validateUniqueCategory(createMockSarif("abc")));
t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc", "_")));
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif("abc", "def__")),
);
t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc_def")));
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif("mno_", "pqr")),
uploadLib.validateUniqueCategory(
createMockSarif("abc"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif("mno", "_pqr")),
uploadLib.validateUniqueCategory(
createMockSarif("abc", "_"),
CodeScanning.sentinelPrefix,
),
);
t.notThrows(() =>
uploadLib.validateUniqueCategory(
createMockSarif("abc", "def__"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(
createMockSarif("abc_def"),
CodeScanning.sentinelPrefix,
),
);
t.notThrows(() =>
uploadLib.validateUniqueCategory(
createMockSarif("mno_", "pqr"),
CodeScanning.sentinelPrefix,
),
);
t.throws(() =>
uploadLib.validateUniqueCategory(
createMockSarif("mno", "_pqr"),
CodeScanning.sentinelPrefix,
),
);
});
@@ -323,19 +452,30 @@ test("validateUniqueCategory for multiple runs", (t) => {
// duplicate categories are allowed within the same sarif file
const multiSarif = { runs: [sarif1.runs[0], sarif1.runs[0], sarif2.runs[0]] };
t.notThrows(() => uploadLib.validateUniqueCategory(multiSarif));
t.notThrows(() =>
uploadLib.validateUniqueCategory(multiSarif, CodeScanning.sentinelPrefix),
);
// should throw if there are duplicate categories in separate validations
t.throws(() => uploadLib.validateUniqueCategory(sarif1));
t.throws(() => uploadLib.validateUniqueCategory(sarif2));
t.throws(() =>
uploadLib.validateUniqueCategory(sarif1, CodeScanning.sentinelPrefix),
);
t.throws(() =>
uploadLib.validateUniqueCategory(sarif2, CodeScanning.sentinelPrefix),
);
});
test("validateUniqueCategory with different prefixes", (t) => {
t.notThrows(() => uploadLib.validateUniqueCategory(createMockSarif()));
t.notThrows(() =>
uploadLib.validateUniqueCategory(
createMockSarif(),
uploadLib.CodeQualityTarget.sentinelPrefix,
CodeScanning.sentinelPrefix,
),
);
t.notThrows(() =>
uploadLib.validateUniqueCategory(
createMockSarif(),
CodeQuality.sentinelPrefix,
),
);
});

View File

@@ -8,6 +8,7 @@ import { OctokitResponse } from "@octokit/types";
import * as jsonschema from "jsonschema";
import * as actionsUtil from "./actions-util";
import * as analyses from "./analyses";
import * as api from "./api-client";
import { getGitHubVersion, wrapApiConfigurationError } from "./api-client";
import { CodeQL, getCodeQL } from "./codeql";
@@ -345,19 +346,13 @@ function getAutomationID(
return api.computeAutomationID(analysis_key, environment);
}
// Enumerates API endpoints that accept SARIF files.
export enum SARIF_UPLOAD_ENDPOINT {
CODE_SCANNING = "PUT /repos/:owner/:repo/code-scanning/analysis",
CODE_QUALITY = "PUT /repos/:owner/:repo/code-quality/analysis",
}
// Upload the given payload.
// If the request fails then this will retry a small number of times.
async function uploadPayload(
payload: any,
repositoryNwo: RepositoryNwo,
logger: Logger,
target: SARIF_UPLOAD_ENDPOINT,
target: analyses.SARIF_UPLOAD_ENDPOINT,
): Promise<string> {
logger.info("Uploading results");
@@ -616,31 +611,6 @@ export function buildPayload(
return payloadObj;
}
// Represents configurations for different services that we can upload SARIF to.
export interface UploadTarget {
name: string;
target: SARIF_UPLOAD_ENDPOINT;
sarifPredicate: (name: string) => boolean;
sentinelPrefix: string;
}
// Represents the Code Scanning upload target.
export const CodeScanningTarget: UploadTarget = {
name: "code scanning",
target: SARIF_UPLOAD_ENDPOINT.CODE_SCANNING,
sarifPredicate: (name) =>
name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name),
sentinelPrefix: "CODEQL_UPLOAD_SARIF_",
};
// Represents the Code Quality upload target.
export const CodeQualityTarget: UploadTarget = {
name: "code quality",
target: SARIF_UPLOAD_ENDPOINT.CODE_QUALITY,
sarifPredicate: (name) => name.endsWith(".quality.sarif"),
sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_",
};
/**
* Uploads a single SARIF file or a directory of SARIF files depending on what `inputSarifPath` refers
* to.
@@ -651,7 +621,7 @@ export async function uploadFiles(
category: string | undefined,
features: FeatureEnablement,
logger: Logger,
uploadTarget: UploadTarget,
uploadTarget: analyses.AnalysisConfig,
): Promise<UploadResult> {
const sarifPaths = getSarifFilePaths(
inputSarifPath,
@@ -677,7 +647,7 @@ export async function uploadSpecifiedFiles(
category: string | undefined,
features: FeatureEnablement,
logger: Logger,
uploadTarget: UploadTarget = CodeScanningTarget,
uploadTarget: analyses.AnalysisConfig,
): Promise<UploadResult> {
logger.startGroup(`Uploading ${uploadTarget.name} results`);
logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`);
@@ -943,7 +913,7 @@ function handleProcessingResultForUnsuccessfulExecution(
export function validateUniqueCategory(
sarif: SarifFile,
sentinelPrefix: string = CodeScanningTarget.sentinelPrefix,
sentinelPrefix: string,
): void {
// duplicate categories are allowed in the same sarif file
// but not across multiple sarif files

View File

@@ -4,6 +4,7 @@ import * as core from "@actions/core";
import * as actionsUtil from "./actions-util";
import { getActionVersion, getTemporaryDirectory } from "./actions-util";
import * as analyses from "./analyses";
import { getGitHubVersion } from "./api-client";
import { Features } from "./feature-flags";
import { Logger, getActionsLogger } from "./logging";
@@ -95,7 +96,7 @@ async function run() {
category,
features,
logger,
upload_lib.CodeScanningTarget,
analyses.CodeScanning,
);
core.setOutput("sarif-id", uploadResult.sarifID);
@@ -105,7 +106,7 @@ async function run() {
if (fs.lstatSync(sarifPath).isDirectory()) {
const qualitySarifFiles = upload_lib.findSarifFilesInDir(
sarifPath,
upload_lib.CodeQualityTarget.sarifPredicate,
analyses.CodeQuality.sarifPredicate,
);
if (qualitySarifFiles.length !== 0) {
@@ -115,7 +116,7 @@ async function run() {
actionsUtil.fixCodeQualityCategory(logger, category),
features,
logger,
upload_lib.CodeQualityTarget,
analyses.CodeQuality,
);
}
}

View File

@@ -1278,3 +1278,12 @@ export async function asyncSome<T>(
const results = await Promise.all(array.map(predicate));
return results.some((result) => result);
}
/**
* Checks that `value` is neither `undefined` nor `null`.
* @param value The value to test.
* @returns Narrows the type of `value` to exclude `undefined` and `null`.
*/
export function isDefined<T>(value: T | null | undefined): value is T {
return value !== undefined && value !== null;
}