Compare commits

...

5 Commits

Author SHA1 Message Date
Michael B. Gale 9fe90880f7 Report undefined when FFs are unavailable 2026-01-28 13:14:57 +00:00
Michael B. Gale 1bfa34a866 Fix keys instead of values in test 2026-01-28 13:12:43 +00:00
Michael B. Gale 7159d66148 Fix typo in comment 2026-01-28 13:11:42 +00:00
Michael B. Gale f1779e26a8 Report queried feature flags in status reports 2026-01-28 12:57:45 +00:00
Michael B. Gale 9d2031faa4 Track outcomes of querying FFs with getValue 2026-01-28 12:03:10 +00:00
20 changed files with 330 additions and 27 deletions
+29 -3
View File
@@ -90761,6 +90761,12 @@ var Features = class {
);
}
gitHubFeatureFlags;
// Tracks features that have been queried at some point and the outcome.
queriedFeatures = {};
/** Gets a record of features that were queried and the corresponding outcomes. */
getQueriedFeatures() {
return this.queriedFeatures;
}
async getDefaultCliVersion(variant) {
return await this.gitHubFeatureFlags.getDefaultCliVersion(variant);
}
@@ -90777,6 +90783,11 @@ var Features = class {
* @throws if a `minimumVersion` is specified for the feature, and `codeql` is not provided.
*/
async getValue(feature, codeql) {
const value = await this.getValueInternal(feature, codeql);
this.queriedFeatures[feature] = { value };
return value;
}
async getValueInternal(feature, codeql) {
const config = featureConfig[feature];
if (!codeql && config.minimumVersion) {
throw new Error(
@@ -93713,7 +93724,7 @@ function setJobStatusIfUnsuccessful(actionStatus) {
);
}
}
async function createStatusReportBase(actionName, status, actionStartedAt, config, diskInfo, logger, cause, exception2) {
async function createStatusReportBase(actionName, status, actionStartedAt, config, queriedFeatures, diskInfo, logger, cause, exception2) {
try {
const commitOid = getOptionalInput("sha") || process.env["GITHUB_SHA"] || "";
const ref = await getRef();
@@ -93736,6 +93747,12 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi
core12.exportVariable("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment);
}
const isSteadyStateDefaultSetupRun = process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true";
let featureFlags = void 0;
if (queriedFeatures) {
featureFlags = Object.entries(queriedFeatures).map(
([feature, outcome]) => ({ feature, ...outcome })
);
}
const statusReport = {
action_name: actionName,
action_oid: "unknown",
@@ -93747,6 +93764,7 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi
analysis_key,
build_mode: config?.buildMode,
commit_oid: commitOid,
feature_flags: featureFlags,
first_party_analysis: isFirstPartyAnalysis(actionName),
job_name: jobName,
job_run_uuid: jobRunUUID,
@@ -93873,6 +93891,7 @@ async function sendUnhandledErrorStatusReport(actionName, actionStartedAt, error
"failure",
actionStartedAt,
void 0,
{},
void 0,
logger,
`Unhandled CodeQL Action error: ${getErrorMessage(error3)}`,
@@ -95721,13 +95740,14 @@ async function postProcessAndUploadSarif(logger, features, uploadKind, checkoutP
}
// src/analyze-action.ts
async function sendStatusReport2(startedAt2, config, stats, error3, trapCacheUploadTime, dbCreationTimings, didUploadTrapCaches, trapCacheCleanup, dependencyCacheResults, databaseUploadResults, logger) {
async function sendStatusReport2(startedAt2, config, features, stats, error3, trapCacheUploadTime, dbCreationTimings, didUploadTrapCaches, trapCacheCleanup, dependencyCacheResults, databaseUploadResults, logger) {
const status = getActionsStatus(error3, stats?.analyze_failure_language);
const statusReportBase = await createStatusReportBase(
"finish" /* Analyze */,
status,
startedAt2,
config,
features?.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
error3?.message,
@@ -95816,6 +95836,7 @@ async function run(startedAt2) {
let uploadResults = void 0;
let runStats = void 0;
let config = void 0;
let features = void 0;
let trapCacheCleanupTelemetry = void 0;
let trapCacheUploadTime = void 0;
let dbCreationTimings = void 0;
@@ -95831,6 +95852,7 @@ async function run(startedAt2) {
"starting",
startedAt2,
config,
void 0,
await checkDiskUsage(logger),
logger
);
@@ -95869,7 +95891,7 @@ async function run(startedAt2) {
const repositoryNwo = getRepositoryNwo();
const gitHubVersion = await getGitHubVersion();
checkActionVersion(getActionVersion(), gitHubVersion);
const features = new Features(
features = new Features(
gitHubVersion,
repositoryNwo,
getTemporaryDirectory(),
@@ -95998,6 +96020,7 @@ async function run(startedAt2) {
await sendStatusReport2(
startedAt2,
config,
features,
error3 instanceof CodeQLAnalysisError ? error3.queriesStatusReport : void 0,
error3 instanceof CodeQLAnalysisError ? error3.error : error3,
trapCacheUploadTime,
@@ -96014,6 +96037,7 @@ async function run(startedAt2) {
await sendStatusReport2(
startedAt2,
config,
features,
{
...runStats,
...uploadResults["code-scanning" /* CodeScanning */].statusReport
@@ -96031,6 +96055,7 @@ async function run(startedAt2) {
await sendStatusReport2(
startedAt2,
config,
features,
{ ...runStats },
void 0,
trapCacheUploadTime,
@@ -96045,6 +96070,7 @@ async function run(startedAt2) {
await sendStatusReport2(
startedAt2,
config,
features,
void 0,
void 0,
trapCacheUploadTime,
+22 -1
View File
@@ -87094,6 +87094,12 @@ var Features = class {
);
}
gitHubFeatureFlags;
// Tracks features that have been queried at some point and the outcome.
queriedFeatures = {};
/** Gets a record of features that were queried and the corresponding outcomes. */
getQueriedFeatures() {
return this.queriedFeatures;
}
async getDefaultCliVersion(variant) {
return await this.gitHubFeatureFlags.getDefaultCliVersion(variant);
}
@@ -87110,6 +87116,11 @@ var Features = class {
* @throws if a `minimumVersion` is specified for the feature, and `codeql` is not provided.
*/
async getValue(feature, codeql) {
const value = await this.getValueInternal(feature, codeql);
this.queriedFeatures[feature] = { value };
return value;
}
async getValueInternal(feature, codeql) {
const config = featureConfig[feature];
if (!codeql && config.minimumVersion) {
throw new Error(
@@ -88178,7 +88189,7 @@ function setJobStatusIfUnsuccessful(actionStatus) {
);
}
}
async function createStatusReportBase(actionName, status, actionStartedAt, config, diskInfo, logger, cause, exception2) {
async function createStatusReportBase(actionName, status, actionStartedAt, config, queriedFeatures, diskInfo, logger, cause, exception2) {
try {
const commitOid = getOptionalInput("sha") || process.env["GITHUB_SHA"] || "";
const ref = await getRef();
@@ -88201,6 +88212,12 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi
core12.exportVariable("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment);
}
const isSteadyStateDefaultSetupRun = process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true";
let featureFlags = void 0;
if (queriedFeatures) {
featureFlags = Object.entries(queriedFeatures).map(
([feature, outcome]) => ({ feature, ...outcome })
);
}
const statusReport = {
action_name: actionName,
action_oid: "unknown",
@@ -88212,6 +88229,7 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi
analysis_key,
build_mode: config?.buildMode,
commit_oid: commitOid,
feature_flags: featureFlags,
first_party_analysis: isFirstPartyAnalysis(actionName),
job_name: jobName,
job_run_uuid: jobRunUUID,
@@ -88338,6 +88356,7 @@ async function sendUnhandledErrorStatusReport(actionName, actionStartedAt, error
"failure",
actionStartedAt,
void 0,
{},
void 0,
logger,
`Unhandled CodeQL Action error: ${getErrorMessage(error3)}`,
@@ -88365,6 +88384,7 @@ async function sendCompletedStatusReport(config, logger, startedAt, allLanguages
status,
startedAt,
config,
void 0,
await checkDiskUsage(logger),
logger,
cause?.message,
@@ -88390,6 +88410,7 @@ async function run(startedAt) {
"starting",
startedAt,
config,
void 0,
await checkDiskUsage(logger),
logger
);
+24 -2
View File
@@ -131403,6 +131403,12 @@ var Features = class {
);
}
gitHubFeatureFlags;
// Tracks features that have been queried at some point and the outcome.
queriedFeatures = {};
/** Gets a record of features that were queried and the corresponding outcomes. */
getQueriedFeatures() {
return this.queriedFeatures;
}
async getDefaultCliVersion(variant) {
return await this.gitHubFeatureFlags.getDefaultCliVersion(variant);
}
@@ -131419,6 +131425,11 @@ var Features = class {
* @throws if a `minimumVersion` is specified for the feature, and `codeql` is not provided.
*/
async getValue(feature, codeql) {
const value = await this.getValueInternal(feature, codeql);
this.queriedFeatures[feature] = { value };
return value;
}
async getValueInternal(feature, codeql) {
const config = featureConfig[feature];
if (!codeql && config.minimumVersion) {
throw new Error(
@@ -135974,7 +135985,7 @@ function setJobStatusIfUnsuccessful(actionStatus) {
);
}
}
async function createStatusReportBase(actionName, status, actionStartedAt, config, diskInfo, logger, cause, exception2) {
async function createStatusReportBase(actionName, status, actionStartedAt, config, queriedFeatures, diskInfo, logger, cause, exception2) {
try {
const commitOid = getOptionalInput("sha") || process.env["GITHUB_SHA"] || "";
const ref = await getRef();
@@ -135997,6 +136008,12 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi
core15.exportVariable("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment);
}
const isSteadyStateDefaultSetupRun = process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true";
let featureFlags = void 0;
if (queriedFeatures) {
featureFlags = Object.entries(queriedFeatures).map(
([feature, outcome]) => ({ feature, ...outcome })
);
}
const statusReport = {
action_name: actionName,
action_oid: "unknown",
@@ -136008,6 +136025,7 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi
analysis_key,
build_mode: config?.buildMode,
commit_oid: commitOid,
feature_flags: featureFlags,
first_party_analysis: isFirstPartyAnalysis(actionName),
job_name: jobName,
job_run_uuid: jobRunUUID,
@@ -136134,6 +136152,7 @@ async function sendUnhandledErrorStatusReport(actionName, actionStartedAt, error
"failure",
actionStartedAt,
void 0,
{},
void 0,
logger,
`Unhandled CodeQL Action error: ${getErrorMessage(error3)}`,
@@ -136156,6 +136175,7 @@ async function sendUnhandledErrorStatusReport(actionName, actionStartedAt, error
async function run2(startedAt) {
const logger = getActionsLogger();
let config;
let features = void 0;
let uploadFailedSarifResult;
let dependencyCachingUsage;
try {
@@ -136163,7 +136183,7 @@ async function run2(startedAt) {
const gitHubVersion = await getGitHubVersion();
checkGitHubVersionInRange(gitHubVersion, logger);
const repositoryNwo = getRepositoryNwo();
const features = new Features(
features = new Features(
gitHubVersion,
repositoryNwo,
getTemporaryDirectory(),
@@ -136197,6 +136217,7 @@ async function run2(startedAt) {
getActionsStatus(error3),
startedAt,
config,
features?.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
error3.message,
@@ -136214,6 +136235,7 @@ async function run2(startedAt) {
"success",
startedAt,
config,
features.getQueriedFeatures(),
await checkDiskUsage(logger),
logger
);
+34 -5
View File
@@ -88252,6 +88252,12 @@ var Features = class {
);
}
gitHubFeatureFlags;
// Tracks features that have been queried at some point and the outcome.
queriedFeatures = {};
/** Gets a record of features that were queried and the corresponding outcomes. */
getQueriedFeatures() {
return this.queriedFeatures;
}
async getDefaultCliVersion(variant) {
return await this.gitHubFeatureFlags.getDefaultCliVersion(variant);
}
@@ -88268,6 +88274,11 @@ var Features = class {
* @throws if a `minimumVersion` is specified for the feature, and `codeql` is not provided.
*/
async getValue(feature, codeql) {
const value = await this.getValueInternal(feature, codeql);
this.queriedFeatures[feature] = { value };
return value;
}
async getValueInternal(feature, codeql) {
const config = featureConfig[feature];
if (!codeql && config.minimumVersion) {
throw new Error(
@@ -91509,7 +91520,7 @@ function setJobStatusIfUnsuccessful(actionStatus) {
);
}
}
async function createStatusReportBase(actionName, status, actionStartedAt, config, diskInfo, logger, cause, exception2) {
async function createStatusReportBase(actionName, status, actionStartedAt, config, queriedFeatures, diskInfo, logger, cause, exception2) {
try {
const commitOid = getOptionalInput("sha") || process.env["GITHUB_SHA"] || "";
const ref = await getRef();
@@ -91532,6 +91543,12 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi
core11.exportVariable("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment);
}
const isSteadyStateDefaultSetupRun = process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true";
let featureFlags = void 0;
if (queriedFeatures) {
featureFlags = Object.entries(queriedFeatures).map(
([feature, outcome]) => ({ feature, ...outcome })
);
}
const statusReport = {
action_name: actionName,
action_oid: "unknown",
@@ -91543,6 +91560,7 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi
analysis_key,
build_mode: config?.buildMode,
commit_oid: commitOid,
feature_flags: featureFlags,
first_party_analysis: isFirstPartyAnalysis(actionName),
job_name: jobName,
job_run_uuid: jobRunUUID,
@@ -91715,6 +91733,7 @@ async function sendUnhandledErrorStatusReport(actionName, actionStartedAt, error
"failure",
actionStartedAt,
void 0,
{},
void 0,
logger,
`Unhandled CodeQL Action error: ${getErrorMessage(error3)}`,
@@ -91927,12 +91946,13 @@ var internal2 = {
// src/init-action.ts
var CODEQL_VERSION_JAR_MINIMIZATION = "2.23.0";
async function sendStartingStatusReport(startedAt, config, logger) {
async function sendStartingStatusReport(startedAt, config, features, logger) {
const statusReportBase = await createStatusReportBase(
"init" /* Init */,
"starting",
startedAt,
config,
features?.getQueriedFeatures(),
await checkDiskUsage(logger),
logger
);
@@ -91940,12 +91960,13 @@ async function sendStartingStatusReport(startedAt, config, logger) {
await sendStatusReport(statusReportBase);
}
}
async function sendCompletedStatusReport(startedAt, config, configFile, toolsDownloadStatusReport, toolsFeatureFlagsValid, toolsSource, toolsVersion, overlayBaseDatabaseStats, dependencyCachingResults, logger, error3) {
async function sendCompletedStatusReport(startedAt, config, features, configFile, toolsDownloadStatusReport, toolsFeatureFlagsValid, toolsSource, toolsVersion, overlayBaseDatabaseStats, dependencyCachingResults, logger, error3) {
const statusReportBase = await createStatusReportBase(
"init" /* Init */,
getActionsStatus(error3),
startedAt,
config,
features?.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
error3?.message,
@@ -91994,7 +92015,7 @@ async function run(startedAt) {
let config;
let configFile;
let codeql;
let features;
let features = void 0;
let sourceRoot;
let toolsDownloadStatusReport;
let toolsFeatureFlagsValid;
@@ -92041,7 +92062,12 @@ async function run(startedAt) {
`Failed to parse analysis kinds for 'starting' status report: ${getErrorMessage(err)}`
);
}
await sendStartingStatusReport(startedAt, { analysisKinds }, logger);
await sendStartingStatusReport(
startedAt,
{ analysisKinds },
features,
logger
);
if (process.env["CODEQL_ACTION_SETUP_CODEQL_HAS_RUN" /* SETUP_CODEQL_ACTION_HAS_RUN */] === "true") {
throw new ConfigurationError(
`The 'init' action should not be run in the same workflow as 'setup-codeql'.`
@@ -92130,6 +92156,7 @@ async function run(startedAt) {
error3 instanceof ConfigurationError ? "user-error" : "aborted",
startedAt,
config,
features?.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
error3.message,
@@ -92377,6 +92404,7 @@ exec ${goBinaryPath} "$@"`
await sendCompletedStatusReport(
startedAt,
config,
features,
void 0,
// We only report config info on success.
toolsDownloadStatusReport,
@@ -92395,6 +92423,7 @@ exec ${goBinaryPath} "$@"`
await sendCompletedStatusReport(
startedAt,
config,
features,
configFile,
toolsDownloadStatusReport,
toolsFeatureFlagsValid,
+12 -1
View File
@@ -87793,7 +87793,7 @@ function setJobStatusIfUnsuccessful(actionStatus) {
);
}
}
async function createStatusReportBase(actionName, status, actionStartedAt, config, diskInfo, logger, cause, exception2) {
async function createStatusReportBase(actionName, status, actionStartedAt, config, queriedFeatures, diskInfo, logger, cause, exception2) {
try {
const commitOid = getOptionalInput("sha") || process.env["GITHUB_SHA"] || "";
const ref = await getRef();
@@ -87816,6 +87816,12 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi
core11.exportVariable("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment);
}
const isSteadyStateDefaultSetupRun = process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true";
let featureFlags = void 0;
if (queriedFeatures) {
featureFlags = Object.entries(queriedFeatures).map(
([feature, outcome]) => ({ feature, ...outcome })
);
}
const statusReport = {
action_name: actionName,
action_oid: "unknown",
@@ -87827,6 +87833,7 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi
analysis_key,
build_mode: config?.buildMode,
commit_oid: commitOid,
feature_flags: featureFlags,
first_party_analysis: isFirstPartyAnalysis(actionName),
job_name: jobName,
job_run_uuid: jobRunUUID,
@@ -87953,6 +87960,7 @@ async function sendUnhandledErrorStatusReport(actionName, actionStartedAt, error
"failure",
actionStartedAt,
void 0,
{},
void 0,
logger,
`Unhandled CodeQL Action error: ${getErrorMessage(error3)}`,
@@ -87982,6 +87990,7 @@ async function run(startedAt) {
"starting",
startedAt,
config,
void 0,
await checkDiskUsage(logger),
logger
);
@@ -88021,6 +88030,7 @@ async function run(startedAt) {
getActionsStatus(error3),
startedAt,
config,
void 0,
await checkDiskUsage(logger),
logger,
error3.message,
@@ -88037,6 +88047,7 @@ async function run(startedAt) {
"success",
startedAt,
config,
void 0,
await checkDiskUsage(logger),
logger
);
+27 -3
View File
@@ -86995,6 +86995,12 @@ var Features = class {
);
}
gitHubFeatureFlags;
// Tracks features that have been queried at some point and the outcome.
queriedFeatures = {};
/** Gets a record of features that were queried and the corresponding outcomes. */
getQueriedFeatures() {
return this.queriedFeatures;
}
async getDefaultCliVersion(variant) {
return await this.gitHubFeatureFlags.getDefaultCliVersion(variant);
}
@@ -87011,6 +87017,11 @@ var Features = class {
* @throws if a `minimumVersion` is specified for the feature, and `codeql` is not provided.
*/
async getValue(feature, codeql) {
const value = await this.getValueInternal(feature, codeql);
this.queriedFeatures[feature] = { value };
return value;
}
async getValueInternal(feature, codeql) {
const config = featureConfig[feature];
if (!codeql && config.minimumVersion) {
throw new Error(
@@ -89125,7 +89136,7 @@ function setJobStatusIfUnsuccessful(actionStatus) {
);
}
}
async function createStatusReportBase(actionName, status, actionStartedAt, config, diskInfo, logger, cause, exception2) {
async function createStatusReportBase(actionName, status, actionStartedAt, config, queriedFeatures, diskInfo, logger, cause, exception2) {
try {
const commitOid = getOptionalInput("sha") || process.env["GITHUB_SHA"] || "";
const ref = await getRef();
@@ -89148,6 +89159,12 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi
core11.exportVariable("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment);
}
const isSteadyStateDefaultSetupRun = process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true";
let featureFlags = void 0;
if (queriedFeatures) {
featureFlags = Object.entries(queriedFeatures).map(
([feature, outcome]) => ({ feature, ...outcome })
);
}
const statusReport = {
action_name: actionName,
action_oid: "unknown",
@@ -89159,6 +89176,7 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi
analysis_key,
build_mode: config?.buildMode,
commit_oid: commitOid,
feature_flags: featureFlags,
first_party_analysis: isFirstPartyAnalysis(actionName),
job_name: jobName,
job_run_uuid: jobRunUUID,
@@ -89285,6 +89303,7 @@ async function sendUnhandledErrorStatusReport(actionName, actionStartedAt, error
"failure",
actionStartedAt,
void 0,
{},
void 0,
logger,
`Unhandled CodeQL Action error: ${getErrorMessage(error3)}`,
@@ -89304,12 +89323,13 @@ async function sendUnhandledErrorStatusReport(actionName, actionStartedAt, error
}
// src/setup-codeql-action.ts
async function sendCompletedStatusReport(startedAt, toolsDownloadStatusReport, toolsFeatureFlagsValid, toolsSource, toolsVersion, logger, error3) {
async function sendCompletedStatusReport(startedAt, features, toolsDownloadStatusReport, toolsFeatureFlagsValid, toolsSource, toolsVersion, logger, error3) {
const statusReportBase = await createStatusReportBase(
"setup-codeql" /* SetupCodeQL */,
getActionsStatus(error3),
startedAt,
void 0,
features?.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
error3?.message,
@@ -89341,6 +89361,7 @@ async function run(startedAt) {
let toolsFeatureFlagsValid;
let toolsSource;
let toolsVersion;
let features = void 0;
try {
initializeEnvironment(getActionVersion());
const apiDetails = {
@@ -89353,7 +89374,7 @@ async function run(startedAt) {
checkGitHubVersionInRange(gitHubVersion, logger);
checkActionVersion(getActionVersion(), gitHubVersion);
const repositoryNwo = getRepositoryNwo();
const features = new Features(
features = new Features(
gitHubVersion,
repositoryNwo,
getTemporaryDirectory(),
@@ -89367,6 +89388,7 @@ async function run(startedAt) {
"starting",
startedAt,
void 0,
features.getQueriedFeatures(),
await checkDiskUsage(logger),
logger
);
@@ -89401,6 +89423,7 @@ async function run(startedAt) {
error3 instanceof ConfigurationError ? "user-error" : "failure",
startedAt,
void 0,
features?.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
error3.message,
@@ -89413,6 +89436,7 @@ async function run(startedAt) {
}
await sendCompletedStatusReport(
startedAt,
features,
toolsDownloadStatusReport,
toolsFeatureFlagsValid,
toolsSource,
+11 -1
View File
@@ -104012,7 +104012,7 @@ function setJobStatusIfUnsuccessful(actionStatus) {
);
}
}
async function createStatusReportBase(actionName, status, actionStartedAt, config, diskInfo, logger, cause, exception2) {
async function createStatusReportBase(actionName, status, actionStartedAt, config, queriedFeatures, diskInfo, logger, cause, exception2) {
try {
const commitOid = getOptionalInput("sha") || process.env["GITHUB_SHA"] || "";
const ref = await getRef();
@@ -104035,6 +104035,12 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi
core10.exportVariable("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment);
}
const isSteadyStateDefaultSetupRun = process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true";
let featureFlags = void 0;
if (queriedFeatures) {
featureFlags = Object.entries(queriedFeatures).map(
([feature, outcome]) => ({ feature, ...outcome })
);
}
const statusReport = {
action_name: actionName,
action_oid: "unknown",
@@ -104046,6 +104052,7 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi
analysis_key,
build_mode: config?.buildMode,
commit_oid: commitOid,
feature_flags: featureFlags,
first_party_analysis: isFirstPartyAnalysis(actionName),
job_name: jobName,
job_run_uuid: jobRunUUID,
@@ -104172,6 +104179,7 @@ async function sendUnhandledErrorStatusReport(actionName, actionStartedAt, error
"failure",
actionStartedAt,
void 0,
{},
void 0,
logger,
`Unhandled CodeQL Action error: ${getErrorMessage(error3)}`,
@@ -104243,6 +104251,7 @@ async function sendSuccessStatusReport(startedAt, config, registry_types, logger
"success",
startedAt,
config,
void 0,
await checkDiskUsage(logger),
logger
);
@@ -104303,6 +104312,7 @@ async function run(startedAt) {
{
languages: language && [language]
},
void 0,
await checkDiskUsage(logger),
logger,
"Error from start-proxy Action omitted"
+27 -3
View File
@@ -89949,6 +89949,12 @@ var Features = class {
);
}
gitHubFeatureFlags;
// Tracks features that have been queried at some point and the outcome.
queriedFeatures = {};
/** Gets a record of features that were queried and the corresponding outcomes. */
getQueriedFeatures() {
return this.queriedFeatures;
}
async getDefaultCliVersion(variant) {
return await this.gitHubFeatureFlags.getDefaultCliVersion(variant);
}
@@ -89965,6 +89971,11 @@ var Features = class {
* @throws if a `minimumVersion` is specified for the feature, and `codeql` is not provided.
*/
async getValue(feature, codeql) {
const value = await this.getValueInternal(feature, codeql);
this.queriedFeatures[feature] = { value };
return value;
}
async getValueInternal(feature, codeql) {
const config = featureConfig[feature];
if (!codeql && config.minimumVersion) {
throw new Error(
@@ -90356,7 +90367,7 @@ function setJobStatusIfUnsuccessful(actionStatus) {
);
}
}
async function createStatusReportBase(actionName, status, actionStartedAt, config, diskInfo, logger, cause, exception2) {
async function createStatusReportBase(actionName, status, actionStartedAt, config, queriedFeatures, diskInfo, logger, cause, exception2) {
try {
const commitOid = getOptionalInput("sha") || process.env["GITHUB_SHA"] || "";
const ref = await getRef();
@@ -90379,6 +90390,12 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi
core9.exportVariable("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment);
}
const isSteadyStateDefaultSetupRun = process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true";
let featureFlags = void 0;
if (queriedFeatures) {
featureFlags = Object.entries(queriedFeatures).map(
([feature, outcome]) => ({ feature, ...outcome })
);
}
const statusReport = {
action_name: actionName,
action_oid: "unknown",
@@ -90390,6 +90407,7 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi
analysis_key,
build_mode: config?.buildMode,
commit_oid: commitOid,
feature_flags: featureFlags,
first_party_analysis: isFirstPartyAnalysis(actionName),
job_name: jobName,
job_run_uuid: jobRunUUID,
@@ -90516,6 +90534,7 @@ async function sendUnhandledErrorStatusReport(actionName, actionStartedAt, error
"failure",
actionStartedAt,
void 0,
{},
void 0,
logger,
`Unhandled CodeQL Action error: ${getErrorMessage(error3)}`,
@@ -94158,12 +94177,13 @@ async function postProcessAndUploadSarif(logger, features, uploadKind, checkoutP
}
// src/upload-sarif-action.ts
async function sendSuccessStatusReport(startedAt, uploadStats, logger) {
async function sendSuccessStatusReport(startedAt, features, uploadStats, logger) {
const statusReportBase = await createStatusReportBase(
"upload-sarif" /* UploadSarif */,
"success",
startedAt,
void 0,
features?.getQueriedFeatures(),
await checkDiskUsage(logger),
logger
);
@@ -94177,13 +94197,14 @@ async function sendSuccessStatusReport(startedAt, uploadStats, logger) {
}
async function run(startedAt) {
const logger = getActionsLogger();
let features = void 0;
try {
initializeEnvironment(getActionVersion());
const gitHubVersion = await getGitHubVersion();
checkActionVersion(getActionVersion(), gitHubVersion);
persistInputs();
const repositoryNwo = getRepositoryNwo();
const features = new Features(
features = new Features(
gitHubVersion,
repositoryNwo,
getTemporaryDirectory(),
@@ -94194,6 +94215,7 @@ async function run(startedAt) {
"starting",
startedAt,
void 0,
features.getQueriedFeatures(),
await checkDiskUsage(logger),
logger
);
@@ -94236,6 +94258,7 @@ async function run(startedAt) {
}
await sendSuccessStatusReport(
startedAt,
features,
codeScanningResult?.statusReport || {},
logger
);
@@ -94248,6 +94271,7 @@ async function run(startedAt) {
getActionsStatus(error3),
startedAt,
void 0,
features?.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
message,
+9 -1
View File
@@ -76,6 +76,7 @@ interface FinishWithTrapUploadStatusReport extends FinishStatusReport {
async function sendStatusReport(
startedAt: Date,
config: Config | undefined,
features: Features | undefined,
stats: AnalysisStatusReport | undefined,
error: Error | undefined,
trapCacheUploadTime: number | undefined,
@@ -92,6 +93,7 @@ async function sendStatusReport(
status,
startedAt,
config,
features?.getQueriedFeatures(),
await util.checkDiskUsage(logger),
logger,
error?.message,
@@ -218,6 +220,7 @@ async function run(startedAt: Date) {
| undefined = undefined;
let runStats: QueriesStatusReport | undefined = undefined;
let config: Config | undefined = undefined;
let features: Features | undefined = undefined;
let trapCacheCleanupTelemetry: TrapCacheCleanupStatusReport | undefined =
undefined;
let trapCacheUploadTime: number | undefined = undefined;
@@ -239,6 +242,7 @@ async function run(startedAt: Date) {
"starting",
startedAt,
config,
undefined,
await util.checkDiskUsage(logger),
logger,
);
@@ -293,7 +297,7 @@ async function run(startedAt: Date) {
util.checkActionVersion(actionsUtil.getActionVersion(), gitHubVersion);
const features = new Features(
features = new Features(
gitHubVersion,
repositoryNwo,
actionsUtil.getTemporaryDirectory(),
@@ -460,6 +464,7 @@ async function run(startedAt: Date) {
await sendStatusReport(
startedAt,
config,
features,
error instanceof CodeQLAnalysisError
? error.queriesStatusReport
: undefined,
@@ -482,6 +487,7 @@ async function run(startedAt: Date) {
await sendStatusReport(
startedAt,
config,
features,
{
...runStats,
...uploadResults[analyses.AnalysisKind.CodeScanning].statusReport,
@@ -499,6 +505,7 @@ async function run(startedAt: Date) {
await sendStatusReport(
startedAt,
config,
features,
{ ...runStats },
undefined,
trapCacheUploadTime,
@@ -513,6 +520,7 @@ async function run(startedAt: Date) {
await sendStatusReport(
startedAt,
config,
features,
undefined,
undefined,
trapCacheUploadTime,
+2
View File
@@ -54,6 +54,7 @@ async function sendCompletedStatusReport(
status,
startedAt,
config,
undefined,
await checkDiskUsage(logger),
logger,
cause?.message,
@@ -83,6 +84,7 @@ async function run(startedAt: Date) {
"starting",
startedAt,
config,
undefined,
await checkDiskUsage(logger),
logger,
);
+26 -1
View File
@@ -92,6 +92,31 @@ test(`Feature flags are requested in GHEC-DR`, async (t) => {
});
});
test("Queried feature flags are recorded", async (t) => {
await withTmpDir(async (tmpDir) => {
const loggedMessages = [];
const features = setUpFeatureFlagTests(
tmpDir,
getRecordingLogger(loggedMessages),
{ type: GitHubVariant.DOTCOM },
);
mockFeatureFlagApiEndpoint(200, initializeFeatures(true));
// No features should have been queried initially.
t.is(Object.keys(features.getQueriedFeatures()).length, 0);
// Query all features.
const allFeatures = Object.values(Feature);
for (const feature of allFeatures) {
await getFeatureIncludingCodeQlIfRequired(features, feature);
}
// All features should have a been queried.
t.is(Object.keys(features.getQueriedFeatures()).length, allFeatures.length);
});
});
test("API response missing and features use default value", async (t) => {
await withTmpDir(async (tmpDir) => {
const loggedMessages: LoggedMessage[] = [];
@@ -562,7 +587,7 @@ function setUpFeatureFlagTests(
tmpDir: string,
logger = getRunnerLogger(true),
gitHubVersion = { type: GitHubVariant.DOTCOM } as util.GitHubVersion,
): FeatureEnablement {
): Features {
setupActionsVars(tmpDir, tmpDir);
return new Features(gitHubVersion, testRepositoryNwo, tmpDir, logger);
+28
View File
@@ -345,6 +345,17 @@ export interface FeatureEnablement {
*/
type GitHubFeatureFlagsApiResponse = Partial<Record<Feature, boolean>>;
// Even though we are currently only tracking the value of queried features, we use an object
// here rather than just a boolean to keep open the possibility of also tracking the reason
// for why a particular value was resolved (i.e. because of an environment variable or API result)
// in the future.
export interface QueriedFeatureStatus {
value: boolean;
}
/** A partial mapping of feature flags to the outcome of querying them. */
export type QueriedFeatures = Partial<Record<Feature, QueriedFeatureStatus>>;
export const FEATURE_FLAGS_FILE_NAME = "cached-feature-flags.json";
/**
@@ -355,6 +366,9 @@ export const FEATURE_FLAGS_FILE_NAME = "cached-feature-flags.json";
export class Features implements FeatureEnablement {
private gitHubFeatureFlags: GitHubFeatureFlags;
// Tracks features that have been queried at some point and the outcome.
private queriedFeatures: QueriedFeatures = {};
constructor(
gitHubVersion: util.GitHubVersion,
repositoryNwo: RepositoryNwo,
@@ -369,6 +383,11 @@ export class Features implements FeatureEnablement {
);
}
/** Gets a record of features that were queried and the corresponding outcomes. */
public getQueriedFeatures() {
return this.queriedFeatures;
}
async getDefaultCliVersion(
variant: util.GitHubVariant,
): Promise<CodeQLDefaultVersionInfo> {
@@ -388,6 +407,15 @@ export class Features implements FeatureEnablement {
* @throws if a `minimumVersion` is specified for the feature, and `codeql` is not provided.
*/
async getValue(feature: Feature, codeql?: CodeQL): Promise<boolean> {
const value = await this.getValueInternal(feature, codeql);
this.queriedFeatures[feature] = { value };
return value;
}
private async getValueInternal(
feature: Feature,
codeql?: CodeQL,
): Promise<boolean> {
// Narrow the type to FeatureConfig to avoid type errors. To avoid unsafe use of `as`, we
// check that the required properties exist using `satisfies`.
const config = featureConfig[
+4 -1
View File
@@ -50,6 +50,7 @@ async function run(startedAt: Date) {
const logger = getActionsLogger();
let config: Config | undefined;
let features: Features | undefined = undefined;
let uploadFailedSarifResult:
| initActionPostHelper.UploadFailedSarifResult
| undefined;
@@ -62,7 +63,7 @@ async function run(startedAt: Date) {
checkGitHubVersionInRange(gitHubVersion, logger);
const repositoryNwo = getRepositoryNwo();
const features = new Features(
features = new Features(
gitHubVersion,
repositoryNwo,
getTemporaryDirectory(),
@@ -107,6 +108,7 @@ async function run(startedAt: Date) {
getActionsStatus(error),
startedAt,
config,
features?.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
error.message,
@@ -125,6 +127,7 @@ async function run(startedAt: Date) {
"success",
startedAt,
config,
features.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
);
+14 -2
View File
@@ -108,6 +108,7 @@ export const CODEQL_VERSION_JAR_MINIMIZATION = "2.23.0";
async function sendStartingStatusReport(
startedAt: Date,
config: Partial<configUtils.Config> | undefined,
features: Features | undefined,
logger: Logger,
) {
const statusReportBase = await createStatusReportBase(
@@ -115,6 +116,7 @@ async function sendStartingStatusReport(
"starting",
startedAt,
config,
features?.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
);
@@ -126,6 +128,7 @@ async function sendStartingStatusReport(
async function sendCompletedStatusReport(
startedAt: Date,
config: configUtils.Config | undefined,
features: Features | undefined,
configFile: string | undefined,
toolsDownloadStatusReport: ToolsDownloadStatusReport | undefined,
toolsFeatureFlagsValid: boolean | undefined,
@@ -141,6 +144,7 @@ async function sendCompletedStatusReport(
getActionsStatus(error),
startedAt,
config,
features?.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
error?.message,
@@ -203,7 +207,7 @@ async function run(startedAt: Date) {
let config: configUtils.Config | undefined;
let configFile: string | undefined;
let codeql: CodeQL;
let features: Features;
let features: Features | undefined = undefined;
let sourceRoot: string;
let toolsDownloadStatusReport: ToolsDownloadStatusReport | undefined;
let toolsFeatureFlagsValid: boolean | undefined;
@@ -277,7 +281,12 @@ async function run(startedAt: Date) {
}
// Send a status report indicating that an analysis is starting.
await sendStartingStatusReport(startedAt, { analysisKinds }, logger);
await sendStartingStatusReport(
startedAt,
{ analysisKinds },
features,
logger,
);
// Throw a `ConfigurationError` if the `setup-codeql` action has been run.
if (process.env[EnvVar.SETUP_CODEQL_ACTION_HAS_RUN] === "true") {
@@ -383,6 +392,7 @@ async function run(startedAt: Date) {
error instanceof ConfigurationError ? "user-error" : "aborted",
startedAt,
config,
features?.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
error.message,
@@ -754,6 +764,7 @@ async function run(startedAt: Date) {
await sendCompletedStatusReport(
startedAt,
config,
features,
undefined, // We only report config info on success.
toolsDownloadStatusReport,
toolsFeatureFlagsValid,
@@ -771,6 +782,7 @@ async function run(startedAt: Date) {
await sendCompletedStatusReport(
startedAt,
config,
features,
configFile,
toolsDownloadStatusReport,
toolsFeatureFlagsValid,
+3
View File
@@ -44,6 +44,7 @@ async function run(startedAt: Date) {
"starting",
startedAt,
config,
undefined,
await checkDiskUsage(logger),
logger,
);
@@ -91,6 +92,7 @@ async function run(startedAt: Date) {
getActionsStatus(error),
startedAt,
config,
undefined,
await checkDiskUsage(logger),
logger,
error.message,
@@ -109,6 +111,7 @@ async function run(startedAt: Date) {
"success",
startedAt,
config,
undefined,
await checkDiskUsage(logger),
logger,
);
+7 -1
View File
@@ -42,6 +42,7 @@ import {
*/
async function sendCompletedStatusReport(
startedAt: Date,
features: Features | undefined,
toolsDownloadStatusReport: ToolsDownloadStatusReport | undefined,
toolsFeatureFlagsValid: boolean | undefined,
toolsSource: ToolsSource,
@@ -54,6 +55,7 @@ async function sendCompletedStatusReport(
getActionsStatus(error),
startedAt,
undefined,
features?.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
error?.message,
@@ -97,6 +99,7 @@ async function run(startedAt: Date): Promise<void> {
let toolsFeatureFlagsValid: boolean | undefined;
let toolsSource: ToolsSource;
let toolsVersion: string;
let features: Features | undefined = undefined;
try {
initializeEnvironment(getActionVersion());
@@ -114,7 +117,7 @@ async function run(startedAt: Date): Promise<void> {
const repositoryNwo = getRepositoryNwo();
const features = new Features(
features = new Features(
gitHubVersion,
repositoryNwo,
getTemporaryDirectory(),
@@ -130,6 +133,7 @@ async function run(startedAt: Date): Promise<void> {
"starting",
startedAt,
undefined,
features.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
);
@@ -166,6 +170,7 @@ async function run(startedAt: Date): Promise<void> {
error instanceof ConfigurationError ? "user-error" : "failure",
startedAt,
undefined,
features?.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
error.message,
@@ -179,6 +184,7 @@ async function run(startedAt: Date): Promise<void> {
await sendCompletedStatusReport(
startedAt,
features,
toolsDownloadStatusReport,
toolsFeatureFlagsValid,
toolsSource,
+2
View File
@@ -111,6 +111,7 @@ async function sendSuccessStatusReport(
"success",
startedAt,
config,
undefined,
await util.checkDiskUsage(logger),
logger,
);
@@ -193,6 +194,7 @@ async function run(startedAt: Date) {
{
languages: language && [language],
},
undefined,
await util.checkDiskUsage(logger),
logger,
"Error from start-proxy Action omitted",
+18
View File
@@ -4,6 +4,7 @@ import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
import { Config } from "./config-utils";
import { EnvVar } from "./environment";
import { Feature, QueriedFeatures } from "./feature-flags";
import { KnownLanguage } from "./languages";
import { getRunnerLogger } from "./logging";
import { ToolsSource } from "./setup-codeql";
@@ -46,6 +47,10 @@ test("createStatusReportBase", async (t) => {
await withTmpDir(async (tmpDir: string) => {
setupEnvironmentAndStub(tmpDir);
const features: QueriedFeatures = Object.fromEntries(
Object.values(Feature).map((key) => [key, { value: true }]),
);
const statusReport = await createStatusReportBase(
ActionName.Init,
"failure",
@@ -54,6 +59,7 @@ test("createStatusReportBase", async (t) => {
buildMode: BuildMode.None,
languages: [KnownLanguage.java, KnownLanguage.swift],
}),
features,
{ numAvailableBytes: 100, numTotalBytes: 500 },
getRunnerLogger(false),
"failure cause",
@@ -75,6 +81,9 @@ test("createStatusReportBase", async (t) => {
t.is(statusReport.cause, "failure cause");
t.is(statusReport.commit_oid, process.env["GITHUB_SHA"]!);
t.is(statusReport.exception, "exception stack trace");
if (t.assert(statusReport.feature_flags)) {
t.is(statusReport.feature_flags.length, Object.keys(features).length);
}
t.is(statusReport.job_name, process.env["GITHUB_JOB"] || "");
t.is(typeof statusReport.job_run_uuid, "string");
t.is(statusReport.languages, "java,swift");
@@ -101,6 +110,7 @@ test("createStatusReportBase - empty configuration", async (t) => {
"success",
new Date("May 19, 2023 05:19:00"),
{},
undefined,
{ numAvailableBytes: 100, numTotalBytes: 500 },
getRunnerLogger(false),
);
@@ -123,6 +133,7 @@ test("createStatusReportBase - partial configuration", async (t) => {
{
languages: ["go"],
},
undefined,
{ numAvailableBytes: 100, numTotalBytes: 500 },
getRunnerLogger(false),
);
@@ -146,6 +157,7 @@ test("createStatusReportBase_firstParty", async (t) => {
"failure",
new Date("May 19, 2023 05:19:00"),
createTestConfig({}),
undefined,
{ numAvailableBytes: 100, numTotalBytes: 500 },
getRunnerLogger(false),
"failure cause",
@@ -162,6 +174,7 @@ test("createStatusReportBase_firstParty", async (t) => {
"failure",
new Date("May 19, 2023 05:19:00"),
createTestConfig({}),
undefined,
{ numAvailableBytes: 100, numTotalBytes: 500 },
getRunnerLogger(false),
"failure cause",
@@ -179,6 +192,7 @@ test("createStatusReportBase_firstParty", async (t) => {
"failure",
new Date("May 19, 2023 05:19:00"),
createTestConfig({}),
undefined,
{ numAvailableBytes: 100, numTotalBytes: 500 },
getRunnerLogger(false),
"failure cause",
@@ -195,6 +209,7 @@ test("createStatusReportBase_firstParty", async (t) => {
"failure",
new Date("May 19, 2023 05:19:00"),
createTestConfig({}),
undefined,
{ numAvailableBytes: 100, numTotalBytes: 500 },
getRunnerLogger(false),
"failure cause",
@@ -212,6 +227,7 @@ test("createStatusReportBase_firstParty", async (t) => {
"failure",
new Date("May 19, 2023 05:19:00"),
createTestConfig({}),
undefined,
{ numAvailableBytes: 100, numTotalBytes: 500 },
getRunnerLogger(false),
"failure cause",
@@ -228,6 +244,7 @@ test("createStatusReportBase_firstParty", async (t) => {
"failure",
new Date("May 19, 2023 05:19:00"),
createTestConfig({}),
undefined,
{ numAvailableBytes: 100, numTotalBytes: 500 },
getRunnerLogger(false),
"failure cause",
@@ -307,6 +324,7 @@ const testCreateInitWithConfigStatusReport = test.macro({
"failure",
new Date("May 19, 2023 05:19:00"),
config,
undefined,
{ numAvailableBytes: 100, numTotalBytes: 500 },
getRunnerLogger(false),
"failure cause",
+24 -1
View File
@@ -16,6 +16,7 @@ import { parseRegistriesWithoutCredentials, type Config } from "./config-utils";
import { DependencyCacheRestoreStatusReport } from "./dependency-caching";
import { DocUrl } from "./doc-url";
import { EnvVar } from "./environment";
import { QueriedFeatures, QueriedFeatureStatus } from "./feature-flags";
import { getRef } from "./git-utils";
import { Logger } from "./logging";
import { OverlayBaseDatabaseDownloadStats } from "./overlay-database-utils";
@@ -83,6 +84,12 @@ export enum JobStatus {
ConfigErrorStatus = "JOB_STATUS_CONFIGURATION_ERROR",
}
/** Information about the outcome of a querying a feature flag during this step. */
export interface QueriedFeatureStatusReport extends QueriedFeatureStatus {
// The name of the feature.
feature: string;
}
export interface StatusReportBase {
/** Name of the action being executed. */
action_name: ActionName;
@@ -112,6 +119,8 @@ export interface StatusReportBase {
completed_at?: string;
/** Stack trace of the failure (or undefined if status is not failure). */
exception?: string;
/** Outcomes of querying feature flags during this step. */
feature_flags?: QueriedFeatureStatusReport[];
/** Whether this is a first-party (CodeQL) run of the action. */
first_party_analysis: boolean;
/** Job name from the workflow. */
@@ -253,6 +262,10 @@ export interface EventReport {
* @param actionName The name of the action, e.g. 'init', 'finish', 'upload-sarif'
* @param status The status. Must be 'success', 'failure', or 'starting'
* @param actionStartedAt The time this action started executing.
* @param config The configuration for the action, even partially, if any.
* @param queriedFeatures Information about queried feature flags, if available.
* @param diskInfo Information about disk usage, if available.
* @param logger The logger to use.
* @param cause Cause of failure (only supply if status is 'failure')
* @param exception Exception (only supply if status is 'failure')
* @returns undefined if an exception was thrown.
@@ -262,6 +275,7 @@ export async function createStatusReportBase(
status: ActionStatus,
actionStartedAt: Date,
config: Partial<Config> | undefined,
queriedFeatures: QueriedFeatures | undefined,
diskInfo: DiskUsage | undefined,
logger: Logger,
cause?: string,
@@ -294,6 +308,13 @@ export async function createStatusReportBase(
const isSteadyStateDefaultSetupRun =
process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true";
let featureFlags: QueriedFeatureStatusReport[] | undefined = undefined;
if (queriedFeatures) {
featureFlags = Object.entries(queriedFeatures).map(
([feature, outcome]) => ({ feature, ...outcome }),
);
}
const statusReport: StatusReportBase = {
action_name: actionName,
action_oid: "unknown", // TODO decide if it's possible to fill this in
@@ -304,6 +325,7 @@ export async function createStatusReportBase(
analysis_key,
build_mode: config?.buildMode,
commit_oid: commitOid,
feature_flags: featureFlags,
first_party_analysis: isFirstPartyAnalysis(actionName),
job_name: jobName,
job_run_uuid: jobRunUUID,
@@ -518,7 +540,7 @@ export interface InitWithConfigStatusReport extends InitStatusReport {
/** Stringified JSON array of registry configuration objects, from the 'registries' config field
or workflow input. **/
registries: string;
/** Stringified JSON object representing a query-filters, from the 'query-filters' config field. **/
/** Stringified JSON object representing query-filters, from the 'query-filters' config field. **/
query_filters: string;
/** Path to the specified code scanning config file, from the 'config-file' config field. */
config_file: string;
@@ -623,6 +645,7 @@ export async function sendUnhandledErrorStatusReport(
"failure",
actionStartedAt,
undefined,
{},
undefined,
logger,
`Unhandled CodeQL Action error: ${getErrorMessage(error)}`,
+7 -1
View File
@@ -34,6 +34,7 @@ interface UploadSarifStatusReport
async function sendSuccessStatusReport(
startedAt: Date,
features: Features | undefined,
uploadStats: upload_lib.UploadStatusReport,
logger: Logger,
) {
@@ -42,6 +43,7 @@ async function sendSuccessStatusReport(
"success",
startedAt,
undefined,
features?.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
);
@@ -59,6 +61,7 @@ async function run(startedAt: Date) {
// possible, and only use safe functions outside.
const logger = getActionsLogger();
let features: Features | undefined = undefined;
try {
initializeEnvironment(getActionVersion());
@@ -70,7 +73,7 @@ async function run(startedAt: Date) {
actionsUtil.persistInputs();
const repositoryNwo = getRepositoryNwo();
const features = new Features(
features = new Features(
gitHubVersion,
repositoryNwo,
getTemporaryDirectory(),
@@ -82,6 +85,7 @@ async function run(startedAt: Date) {
"starting",
startedAt,
undefined,
features.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
);
@@ -135,6 +139,7 @@ async function run(startedAt: Date) {
}
await sendSuccessStatusReport(
startedAt,
features,
codeScanningResult?.statusReport || {},
logger,
);
@@ -152,6 +157,7 @@ async function run(startedAt: Date) {
getActionsStatus(error),
startedAt,
undefined,
features?.getQueriedFeatures(),
await checkDiskUsage(logger),
logger,
message,