mirror of
https://github.com/github/codeql-action.git
synced 2026-10-21 02:01:27 +00:00
Store partial configuration when init is aborted
This commit is contained in:
54
lib/entry-points.js
generated
54
lib/entry-points.js
generated
@@ -175095,20 +175095,45 @@ function getLocalConfig(logger2, configFile, validateConfig) {
|
||||
function getPathToParsedConfigFile(tempDir) {
|
||||
return path11.join(tempDir, "config");
|
||||
}
|
||||
async function saveConfig(config, logger2) {
|
||||
function getPathToFailedConfigFile(tempDir) {
|
||||
return path11.join(tempDir, "failed-config");
|
||||
}
|
||||
function saveConfigFile(logger2, configFilePath, config) {
|
||||
const configString = JSON.stringify(config);
|
||||
const configFile = getPathToParsedConfigFile(config.tempDir);
|
||||
fs11.mkdirSync(path11.dirname(configFile), { recursive: true });
|
||||
fs11.writeFileSync(configFile, configString, "utf8");
|
||||
fs11.mkdirSync(path11.dirname(configFilePath), { recursive: true });
|
||||
fs11.writeFileSync(configFilePath, configString, "utf8");
|
||||
logger2.debug("Saved config:");
|
||||
logger2.debug(configString);
|
||||
}
|
||||
async function getConfig(tempDir, logger2) {
|
||||
const configFile = getPathToParsedConfigFile(tempDir);
|
||||
if (!fs11.existsSync(configFile)) {
|
||||
async function saveConfig(config, logger2) {
|
||||
const configFile = getPathToParsedConfigFile(config.tempDir);
|
||||
saveConfigFile(logger2, configFile, config);
|
||||
}
|
||||
function saveAbortedInitConfig(action, config) {
|
||||
if (action.name !== "init" /* Init */) {
|
||||
return;
|
||||
}
|
||||
const failedConfig = {
|
||||
version: config.version,
|
||||
tempDir: config.tempDir,
|
||||
codeQLCmd: config.codeQLCmd,
|
||||
debugMode: config.debugMode,
|
||||
gitHubVersion: config.gitHubVersion,
|
||||
languages: config.languages,
|
||||
analysisKinds: config.analysisKinds
|
||||
};
|
||||
action.logger.debug(`Saving config for failed init step.`);
|
||||
saveConfigFile(
|
||||
action.logger,
|
||||
getPathToFailedConfigFile(config.tempDir),
|
||||
failedConfig
|
||||
);
|
||||
}
|
||||
function readConfigFile(logger2, configFilePath) {
|
||||
if (!fs11.existsSync(configFilePath)) {
|
||||
return void 0;
|
||||
}
|
||||
const configString = fs11.readFileSync(configFile, "utf8");
|
||||
const configString = fs11.readFileSync(configFilePath, "utf8");
|
||||
logger2.debug("Loaded config:");
|
||||
logger2.debug(configString);
|
||||
const config = JSON.parse(configString);
|
||||
@@ -175129,6 +175154,10 @@ async function getConfig(tempDir, logger2) {
|
||||
}
|
||||
return config;
|
||||
}
|
||||
async function getConfig(tempDir, logger2) {
|
||||
const configFile = getPathToParsedConfigFile(tempDir);
|
||||
return readConfigFile(logger2, configFile);
|
||||
}
|
||||
async function generateRegistries(registriesInput, tempDir, logger2) {
|
||||
const registries = parseRegistries(registriesInput);
|
||||
let registriesAuthTokens;
|
||||
@@ -186570,6 +186599,15 @@ async function run3(actionState) {
|
||||
}
|
||||
await checkInstallPython311(config.languages, codeql);
|
||||
} catch (unwrappedError) {
|
||||
if (config !== void 0) {
|
||||
try {
|
||||
saveAbortedInitConfig(actionState, config);
|
||||
} catch (configSaveError) {
|
||||
logger2.warning(
|
||||
`Unable to save configuration for '${"init-post" /* InitPost */}' step: ${getErrorMessage(configSaveError)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
const error3 = wrapError(unwrappedError);
|
||||
core19.setFailed(error3.message);
|
||||
const statusReportBase = await createStatusReportBase(
|
||||
|
||||
@@ -21,7 +21,11 @@ import {
|
||||
import * as api from "./api-client";
|
||||
import { getCachingKind } from "./caching-utils";
|
||||
import { type CodeQL } from "./codeql";
|
||||
import { type ActionConfig, type Config } from "./config/action-config";
|
||||
import {
|
||||
type AbortedInitConfig,
|
||||
type ActionConfig,
|
||||
type Config,
|
||||
} from "./config/action-config";
|
||||
import {
|
||||
calculateAugmentation,
|
||||
ExcludeQueryFilter,
|
||||
@@ -71,6 +75,7 @@ import {
|
||||
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
|
||||
import { shouldSkipOverlayAnalysis } from "./overlay/status";
|
||||
import { RepositoryNwo } from "./repository";
|
||||
import { ActionName } from "./status-report";
|
||||
import { ToolsFeature } from "./tools-features";
|
||||
import { downloadTrapCaches } from "./trap-caching";
|
||||
import {
|
||||
@@ -1379,31 +1384,84 @@ export function getPathToParsedConfigFile(tempDir: string): string {
|
||||
return path.join(tempDir, "config");
|
||||
}
|
||||
|
||||
function getPathToFailedConfigFile(tempDir: string): string {
|
||||
return path.join(tempDir, "failed-config");
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the given config to the path returned from getPathToParsedConfigFile.
|
||||
* Writes {@link config} to {@link configFilePath}.
|
||||
*
|
||||
* This function is not intended to be called, other than by
|
||||
* {@link saveConfig} and {@link saveFailedConfig} below.
|
||||
*/
|
||||
export async function saveConfig(config: Config, logger: Logger) {
|
||||
function saveConfigFile(
|
||||
logger: Logger,
|
||||
configFilePath: string,
|
||||
config: Partial<Config>,
|
||||
) {
|
||||
const configString = JSON.stringify(config);
|
||||
const configFile = getPathToParsedConfigFile(config.tempDir);
|
||||
fs.mkdirSync(path.dirname(configFile), { recursive: true });
|
||||
fs.writeFileSync(configFile, configString, "utf8");
|
||||
fs.mkdirSync(path.dirname(configFilePath), { recursive: true });
|
||||
fs.writeFileSync(configFilePath, configString, "utf8");
|
||||
logger.debug("Saved config:");
|
||||
logger.debug(configString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the config that has been saved to the given temp dir.
|
||||
* If the config could not be found then returns undefined.
|
||||
* Store the given config to the path returned from getPathToParsedConfigFile.
|
||||
*/
|
||||
export async function getConfig(
|
||||
tempDir: string,
|
||||
export async function saveConfig(config: Config, logger: Logger) {
|
||||
const configFile = getPathToParsedConfigFile(config.tempDir);
|
||||
saveConfigFile(logger, configFile, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store parts of {@link config} as a failed configuration file.
|
||||
*
|
||||
* The file will only contain parts of {@link config} that are relevant to
|
||||
* the `init-post` step in the workflow.
|
||||
*/
|
||||
export function saveAbortedInitConfig(
|
||||
action: ActionState<["Base", "Logger"]>,
|
||||
config: Config,
|
||||
) {
|
||||
// Should only be called by init.
|
||||
if (action.name !== ActionName.Init) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a copy of the input `Config` that only contains the keys we want.
|
||||
const failedConfig: AbortedInitConfig = {
|
||||
version: config.version,
|
||||
tempDir: config.tempDir,
|
||||
codeQLCmd: config.codeQLCmd,
|
||||
debugMode: config.debugMode,
|
||||
gitHubVersion: config.gitHubVersion,
|
||||
languages: config.languages,
|
||||
analysisKinds: config.analysisKinds,
|
||||
};
|
||||
|
||||
action.logger.debug(`Saving config for failed init step.`);
|
||||
saveConfigFile(
|
||||
action.logger,
|
||||
getPathToFailedConfigFile(config.tempDir),
|
||||
failedConfig,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to read a {@link Config} from {@link configFilePath}.
|
||||
*
|
||||
* This function is not intended to be called, other than by
|
||||
* {@link getConfig} and {@link getAbortedInitConfig} below.
|
||||
*/
|
||||
function readConfigFile(
|
||||
logger: Logger,
|
||||
): Promise<Config | undefined> {
|
||||
const configFile = getPathToParsedConfigFile(tempDir);
|
||||
if (!fs.existsSync(configFile)) {
|
||||
configFilePath: string,
|
||||
): Config | undefined {
|
||||
if (!fs.existsSync(configFilePath)) {
|
||||
return undefined;
|
||||
}
|
||||
const configString = fs.readFileSync(configFile, "utf8");
|
||||
const configString = fs.readFileSync(configFilePath, "utf8");
|
||||
logger.debug("Loaded config:");
|
||||
logger.debug(configString);
|
||||
|
||||
@@ -1428,6 +1486,36 @@ export async function getConfig(
|
||||
return config as Config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the config that has been saved to the given temp dir.
|
||||
* If the config could not be found then returns undefined.
|
||||
*/
|
||||
export async function getConfig(
|
||||
tempDir: string,
|
||||
logger: Logger,
|
||||
): Promise<Config | undefined> {
|
||||
const configFile = getPathToParsedConfigFile(tempDir);
|
||||
return readConfigFile(logger, configFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a {@link AbortedInitConfig} from a failed `init` step if it exists.
|
||||
*
|
||||
* The result will only contain parts of a {@link Config} that are relevant to
|
||||
* the `init-post` step in the workflow.
|
||||
*/
|
||||
export function getAbortedInitConfig(
|
||||
action: ActionState<["Base", "Logger"]>,
|
||||
tempDir: string,
|
||||
): AbortedInitConfig | undefined {
|
||||
// Only intended to be called by the `init-post` action.
|
||||
if (action.name !== ActionName.InitPost) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return readConfigFile(action.logger, getPathToFailedConfigFile(tempDir));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a `qlconfig.yml` file from the `registries` input.
|
||||
* This file is used by the CodeQL CLI to list the registries to use for each
|
||||
|
||||
@@ -142,3 +142,14 @@ export type ActionConfigProperties = keyof Config;
|
||||
export type ActionConfig<
|
||||
T extends ActionConfigProperties = ActionConfigProperties,
|
||||
> = Partial<Config> & Pick<Config, T>;
|
||||
|
||||
/** A minimal configuration that we can make available even when `init` aborts. */
|
||||
export type AbortedInitConfig = ActionConfig<
|
||||
| "version"
|
||||
| "tempDir"
|
||||
| "gitHubVersion"
|
||||
| "debugMode"
|
||||
| "languages"
|
||||
| "analysisKinds"
|
||||
| "codeQLCmd"
|
||||
>;
|
||||
|
||||
@@ -456,6 +456,18 @@ async function run(
|
||||
|
||||
await checkInstallPython311(config.languages, codeql);
|
||||
} catch (unwrappedError) {
|
||||
// If we have initialised the Action state, then try to save a subset of it for use by the `init-post` action
|
||||
// so that it can try to create and upload additional diagnostic information.
|
||||
if (config !== undefined) {
|
||||
try {
|
||||
configUtils.saveAbortedInitConfig(actionState, config);
|
||||
} catch (configSaveError) {
|
||||
logger.warning(
|
||||
`Unable to save configuration for '${ActionName.InitPost}' step: ${getErrorMessage(configSaveError)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const error = wrapError(unwrappedError);
|
||||
core.setFailed(error.message);
|
||||
const statusReportBase = await createStatusReportBase(
|
||||
|
||||
Reference in New Issue
Block a user