Move xcodeVersion to platform.ts

This commit is contained in:
Michael B. Gale
2026-10-16 17:45:30 +01:00
parent 61cb554113
commit b09f3c6b4d
5 changed files with 375 additions and 362 deletions

329
lib/entry-points.js generated
View File

@@ -34719,7 +34719,7 @@ var require_cacheUtils = __commonJS({
var crypto3 = __importStar2(require("crypto"));
var fs34 = __importStar2(require("fs"));
var path30 = __importStar2(require("path"));
var semver13 = __importStar2(require_semver3());
var semver12 = __importStar2(require_semver3());
var util4 = __importStar2(require("util"));
var constants_1 = require_constants7();
var versionSalt = "1.0";
@@ -34812,7 +34812,7 @@ var require_cacheUtils = __commonJS({
function getCompressionMethod() {
return __awaiter2(this, void 0, void 0, function* () {
const versionOutput = yield getVersion("zstd", ["--quiet"]);
const version = semver13.clean(versionOutput);
const version = semver12.clean(versionOutput);
core29.debug(`zstd version: ${version}`);
if (versionOutput === "") {
return constants_1.CompressionMethod.Gzip;
@@ -42967,11 +42967,11 @@ var require_tracingPolicy = __commonJS({
var import_log = require_log3();
var import_core_util = require_commonjs4();
var import_restError = require_restError3();
var import_util60 = require_internal3();
var import_util61 = require_internal3();
var tracingPolicyName2 = "tracingPolicy";
function tracingPolicy2(options = {}) {
const userAgentPromise = (0, import_userAgent.getUserAgentValue)(options.userAgentPrefix);
const sanitizer = new import_util60.Sanitizer({
const sanitizer = new import_util61.Sanitizer({
additionalAllowedQueryParameters: options.additionalAllowedQueryParameters
});
const tracingClient = tryCreateTracingClient();
@@ -46597,11 +46597,11 @@ var require_response2 = __commonJS({
});
module2.exports = __toCommonJS2(response_exports);
var import_core_rest_pipeline = require_commonjs6();
var import_util60 = require_util9();
var import_util61 = require_util9();
var originalResponse = /* @__PURE__ */ Symbol("Original FullOperationResponse");
function toCompatResponse2(response, options) {
let request3 = (0, import_util60.toWebResourceLike)(response.request);
let headers = (0, import_util60.toHttpHeadersLike)(response.headers);
let request3 = (0, import_util61.toWebResourceLike)(response.request);
let headers = (0, import_util61.toHttpHeadersLike)(response.headers);
if (options?.createProxy) {
return new Proxy(response, {
get(target, prop, receiver) {
@@ -46642,7 +46642,7 @@ var require_response2 = __commonJS({
return {
...compatResponse,
headers,
request: (0, import_util60.toPipelineRequest)(compatResponse.request)
request: (0, import_util61.toPipelineRequest)(compatResponse.request)
};
}
}
@@ -46749,7 +46749,7 @@ var require_requestPolicyFactoryPolicy = __commonJS({
requestPolicyFactoryPolicyName: () => requestPolicyFactoryPolicyName2
});
module2.exports = __toCommonJS2(requestPolicyFactoryPolicy_exports);
var import_util60 = require_util9();
var import_util61 = require_util9();
var import_response = require_response2();
var HttpPipelineLogLevel2 = /* @__PURE__ */ ((HttpPipelineLogLevel22) => {
HttpPipelineLogLevel22[HttpPipelineLogLevel22["ERROR"] = 1] = "ERROR";
@@ -46773,14 +46773,14 @@ var require_requestPolicyFactoryPolicy = __commonJS({
async sendRequest(request3, next) {
let httpPipeline = {
async sendRequest(httpRequest) {
const response2 = await next((0, import_util60.toPipelineRequest)(httpRequest));
const response2 = await next((0, import_util61.toPipelineRequest)(httpRequest));
return (0, import_response.toCompatResponse)(response2, { createProxy: true });
}
};
for (const factory of orderedFactories) {
httpPipeline = factory.create(httpPipeline, mockRequestPolicyOptions);
}
const webResourceLike = (0, import_util60.toWebResourceLike)(request3, { createProxy: true });
const webResourceLike = (0, import_util61.toWebResourceLike)(request3, { createProxy: true });
const response = await httpPipeline.sendRequest(webResourceLike);
return (0, import_response.toPipelineResponse)(response);
}
@@ -46815,12 +46815,12 @@ var require_httpClientAdapter = __commonJS({
});
module2.exports = __toCommonJS2(httpClientAdapter_exports);
var import_response = require_response2();
var import_util60 = require_util9();
var import_util61 = require_util9();
function convertHttpClient2(requestPolicyClient) {
return {
sendRequest: async (request3) => {
const response = await requestPolicyClient.sendRequest(
(0, import_util60.toWebResourceLike)(request3, { createProxy: true })
(0, import_util61.toWebResourceLike)(request3, { createProxy: true })
);
return (0, import_response.toPipelineResponse)(response);
}
@@ -46858,7 +46858,7 @@ var require_commonjs9 = __commonJS({
disableKeepAlivePolicyName: () => import_disableKeepAlivePolicy.disableKeepAlivePolicyName,
requestPolicyFactoryPolicyName: () => import_requestPolicyFactoryPolicy.requestPolicyFactoryPolicyName,
toCompatResponse: () => import_response.toCompatResponse,
toHttpHeadersLike: () => import_util60.toHttpHeadersLike
toHttpHeadersLike: () => import_util61.toHttpHeadersLike
});
module2.exports = __toCommonJS2(src_exports);
var import_extendedClient = require_extendedClient();
@@ -46866,7 +46866,7 @@ var require_commonjs9 = __commonJS({
var import_requestPolicyFactoryPolicy = require_requestPolicyFactoryPolicy();
var import_disableKeepAlivePolicy = require_disableKeepAlivePolicy();
var import_httpClientAdapter = require_httpClientAdapter();
var import_util60 = require_util9();
var import_util61 = require_util9();
}
});
@@ -106361,7 +106361,7 @@ var require_manifest = __commonJS({
exports2._findMatch = _findMatch;
exports2._getOsVersion = _getOsVersion;
exports2._readLinuxVersionFile = _readLinuxVersionFile;
var semver13 = __importStar2(require_semver2());
var semver12 = __importStar2(require_semver2());
var core_1 = require_core();
var os8 = require("os");
var cp = require("child_process");
@@ -106375,7 +106375,7 @@ var require_manifest = __commonJS({
for (const candidate of candidates) {
const version = candidate.version;
(0, core_1.debug)(`check ${version} satisfies ${versionSpec}`);
if (semver13.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) {
if (semver12.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) {
file = candidate.files.find((item) => {
(0, core_1.debug)(`${item.arch}===${archFilter} && ${item.platform}===${platFilter}`);
let chk = item.arch === archFilter && item.platform === platFilter;
@@ -106384,7 +106384,7 @@ var require_manifest = __commonJS({
if (osVersion === item.platform_version) {
chk = true;
} else {
chk = semver13.satisfies(osVersion, item.platform_version);
chk = semver12.satisfies(osVersion, item.platform_version);
}
}
return chk;
@@ -106644,7 +106644,7 @@ var require_tool_cache = __commonJS({
var os8 = __importStar2(require("os"));
var path30 = __importStar2(require("path"));
var httpm = __importStar2(require_lib());
var semver13 = __importStar2(require_semver2());
var semver12 = __importStar2(require_semver2());
var stream2 = __importStar2(require("stream"));
var util4 = __importStar2(require("util"));
var assert_1 = require("assert");
@@ -106917,7 +106917,7 @@ var require_tool_cache = __commonJS({
}
function cacheDir2(sourceDir, tool, version, arch2) {
return __awaiter2(this, void 0, void 0, function* () {
version = semver13.clean(version) || version;
version = semver12.clean(version) || version;
arch2 = arch2 || os8.arch();
core29.debug(`Caching tool ${tool} ${version} ${arch2}`);
core29.debug(`source dir: ${sourceDir}`);
@@ -106935,7 +106935,7 @@ var require_tool_cache = __commonJS({
}
function cacheFile(sourceFile, targetFile, tool, version, arch2) {
return __awaiter2(this, void 0, void 0, function* () {
version = semver13.clean(version) || version;
version = semver12.clean(version) || version;
arch2 = arch2 || os8.arch();
core29.debug(`Caching tool ${tool} ${version} ${arch2}`);
core29.debug(`source file: ${sourceFile}`);
@@ -106965,7 +106965,7 @@ var require_tool_cache = __commonJS({
}
let toolPath = "";
if (versionSpec) {
versionSpec = semver13.clean(versionSpec) || "";
versionSpec = semver12.clean(versionSpec) || "";
const cachePath = path30.join(_getCacheDirectory(), toolName, versionSpec, arch2);
core29.debug(`checking cache: ${cachePath}`);
if (fs34.existsSync(cachePath) && fs34.existsSync(`${cachePath}.complete`)) {
@@ -107045,7 +107045,7 @@ var require_tool_cache = __commonJS({
}
function _createToolPath(tool, version, arch2) {
return __awaiter2(this, void 0, void 0, function* () {
const folderPath = path30.join(_getCacheDirectory(), tool, semver13.clean(version) || version, arch2 || "");
const folderPath = path30.join(_getCacheDirectory(), tool, semver12.clean(version) || version, arch2 || "");
core29.debug(`destination ${folderPath}`);
const markerPath = `${folderPath}.complete`;
yield io9.rmRF(folderPath);
@@ -107055,15 +107055,15 @@ var require_tool_cache = __commonJS({
});
}
function _completeToolPath(tool, version, arch2) {
const folderPath = path30.join(_getCacheDirectory(), tool, semver13.clean(version) || version, arch2 || "");
const folderPath = path30.join(_getCacheDirectory(), tool, semver12.clean(version) || version, arch2 || "");
const markerPath = `${folderPath}.complete`;
fs34.writeFileSync(markerPath, "");
core29.debug("finished caching tool");
}
function isExplicitVersion(versionSpec) {
const c = semver13.clean(versionSpec) || "";
const c = semver12.clean(versionSpec) || "";
core29.debug(`isExplicit: ${c}`);
const valid4 = semver13.valid(c) != null;
const valid4 = semver12.valid(c) != null;
core29.debug(`explicit? ${valid4}`);
return valid4;
}
@@ -107071,14 +107071,14 @@ var require_tool_cache = __commonJS({
let version = "";
core29.debug(`evaluating ${versions.length} versions`);
versions = versions.sort((a, b) => {
if (semver13.gt(a, b)) {
if (semver12.gt(a, b)) {
return 1;
}
return -1;
});
for (let i = versions.length - 1; i >= 0; i--) {
const potential = versions[i];
const satisfied = semver13.satisfies(potential, versionSpec);
const satisfied = semver12.satisfies(potential, versionSpec);
if (satisfied) {
version = potential;
break;
@@ -166068,7 +166068,7 @@ __export(entry_points_exports, {
module.exports = __toCommonJS(entry_points_exports);
// src/analyze-action.ts
var fs24 = __toESM(require("fs"));
var fs25 = __toESM(require("fs"));
var import_path5 = __toESM(require("path"));
var import_perf_hooks6 = require("perf_hooks");
var core14 = __toESM(require_core());
@@ -172680,13 +172680,13 @@ var SarifScanOrder = [
];
// src/analyze.ts
var fs18 = __toESM(require("fs"));
var fs19 = __toESM(require("fs"));
var path16 = __toESM(require("path"));
var import_perf_hooks5 = require("perf_hooks");
var io5 = __toESM(require_io());
// src/codeql.ts
var fs17 = __toESM(require("fs"));
var fs18 = __toESM(require("fs"));
var path15 = __toESM(require("path"));
var core12 = __toESM(require_core());
var toolrunner3 = __toESM(require_toolrunner());
@@ -175366,7 +175366,7 @@ async function logGeneratedFilesTelemetry(config, duration, generatedFilesCount)
}
// src/setup-codeql.ts
var fs15 = __toESM(require("fs"));
var fs16 = __toESM(require("fs"));
var path13 = __toESM(require("path"));
var import_perf_hooks4 = require("perf_hooks");
var toolcache3 = __toESM(require_tool_cache());
@@ -175702,6 +175702,7 @@ async function getCodeQlVersionsForOverlayBaseDatabases(rawLanguages, logger2) {
var semver7 = __toESM(require_semver2());
// src/platform.ts
var import_fs = __toESM(require("fs"));
var semver6 = __toESM(require_semver2());
function getBundlePlatform(platform2 = process.platform, arch2 = process.arch) {
switch (platform2) {
@@ -175725,6 +175726,47 @@ function macOSVersion(action) {
}
return version;
}
var XCODE_SELECT_LINK_PATH = "/private/var/db/xcode_select_link";
var XCODE_APP_FILENAME_PATTERN = new RegExp(
/(?<filename>Xcode_(?<majorMinor>\d+.\d+).app)/
);
function xcodeVersion(logger2) {
try {
const stats = import_fs.default.statSync(XCODE_SELECT_LINK_PATH);
if (!stats.isSymbolicLink()) {
logger2.warning(
`${XCODE_SELECT_LINK_PATH} exists, but is not a symbolic link.`
);
return void 0;
}
const xcodePath = import_fs.default.readlinkSync(XCODE_SELECT_LINK_PATH);
if (xcodePath === "") {
logger2.warning(
`Resolving ${XCODE_SELECT_LINK_PATH} unexpectedly returned nothing.`
);
return void 0;
}
const matchResult = xcodePath.match(XCODE_APP_FILENAME_PATTERN);
if (matchResult?.groups === void 0) {
logger2.warning(
`Xcode path '${xcodePath}' does not contain expected pattern.`
);
return void 0;
}
const majorMinor = matchResult.groups["majorMinor"];
const version = semver6.coerce(majorMinor);
if (version === null) {
logger2.warning(`Couldn't parse '${majorMinor}' as a semantic version.`);
return void 0;
}
return version;
} catch (err) {
logger2.warning(
`Unable to determine Xcode version: ${getErrorMessage(err)}`
);
return void 0;
}
}
// src/per-language-bundles.ts
var MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION = "2.27.1";
@@ -175910,7 +175952,7 @@ async function getCodeQLAssetDownloadURL(action, apiDetails, tagName, assetName,
// src/tar.ts
var import_child_process = require("child_process");
var fs13 = __toESM(require("fs"));
var fs14 = __toESM(require("fs"));
var stream = __toESM(require("stream"));
var import_toolrunner = __toESM(require_toolrunner());
var io4 = __toESM(require_io());
@@ -175983,7 +176025,7 @@ async function isZstdAvailable(logger2) {
}
}
async function extract(tarPath, dest, compressionMethod, tarVersion, logger2) {
fs13.mkdirSync(dest, { recursive: true });
fs14.mkdirSync(dest, { recursive: true });
switch (compressionMethod) {
case "gzip":
return await toolcache.extractTar(tarPath, dest);
@@ -176069,7 +176111,7 @@ function inferCompressionMethod(tarPath) {
}
// src/tools-download.ts
var fs14 = __toESM(require("fs"));
var fs15 = __toESM(require("fs"));
var os5 = __toESM(require("os"));
var path12 = __toESM(require("path"));
var import_perf_hooks3 = require("perf_hooks");
@@ -176155,7 +176197,7 @@ async function downloadAndExtract(codeqlURL, compressionMethod, dest, authorizat
};
}
async function downloadAndExtractZstdWithStreaming(codeqlURL, dest, authorization, headers, tarVersion, logger2) {
fs14.mkdirSync(dest, { recursive: true });
fs15.mkdirSync(dest, { recursive: true });
const agent = new import_http_client.HttpClient().getAgent(codeqlURL);
headers = Object.assign(
{ "User-Agent": "CodeQL Action" },
@@ -176214,7 +176256,7 @@ function getToolcacheDirectory(version) {
}
function isToolcacheOnWorkspaceFilesystem(logger2) {
try {
return fs14.statSync(getRequiredEnvParam("RUNNER_TOOL_CACHE")).dev === fs14.statSync(getRequiredEnvParam("GITHUB_WORKSPACE")).dev;
return fs15.statSync(getRequiredEnvParam("RUNNER_TOOL_CACHE")).dev === fs15.statSync(getRequiredEnvParam("GITHUB_WORKSPACE")).dev;
} catch (e) {
logger2.debug(
`Could not determine whether the toolcache is on the same filesystem as the workspace: ${getErrorMessage(e)}`
@@ -176236,7 +176278,7 @@ async function deleteToolcacheBundles({
return { deletedVersions: [], failed: true };
}
try {
if ((await fs14.promises.lstat(toolDirectory)).isSymbolicLink()) {
if ((await fs15.promises.lstat(toolDirectory)).isSymbolicLink()) {
logger2.info(
`Not deleting the CodeQL tools from the toolcache since '${toolDirectory}' is a symlink.`
);
@@ -176255,7 +176297,7 @@ async function deleteToolcacheBundles({
return { deletedVersions: [], failed: true };
}
try {
const entries = await fs14.promises.readdir(toolDirectory, {
const entries = await fs15.promises.readdir(toolDirectory, {
withFileTypes: true
});
const deletedVersions = [];
@@ -176269,7 +176311,7 @@ async function deleteToolcacheBundles({
}
const versionDirectory = path12.join(toolDirectory, entry.name);
try {
await fs14.promises.rm(versionDirectory, {
await fs15.promises.rm(versionDirectory, {
force: true,
recursive: true
});
@@ -176294,7 +176336,7 @@ async function deleteToolcacheBundles({
}
function writeToolcacheMarkerFile(extractedPath, logger2) {
const markerFilePath = `${extractedPath}.complete`;
fs14.writeFileSync(markerFilePath, "");
fs15.writeFileSync(markerFilePath, "");
logger2.info(`Created toolcache marker file ${markerFilePath}`);
}
@@ -176346,7 +176388,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger2) {
const candidates = toolcache3.findAllVersions("CodeQL").filter(isGoodVersion).map((version) => ({
folder: toolcache3.find("CodeQL", version),
version
})).filter(({ folder }) => fs15.existsSync(path13.join(folder, "pinned-version")));
})).filter(({ folder }) => fs16.existsSync(path13.join(folder, "pinned-version")));
if (candidates.length === 1) {
const candidate = candidates[0];
logger2.debug(
@@ -177008,7 +177050,7 @@ function isReservedToolsValue(tools) {
}
// src/tracer-config.ts
var fs16 = __toESM(require("fs"));
var fs17 = __toESM(require("fs"));
var path14 = __toESM(require("path"));
async function shouldEnableIndirectTracing(codeql, config) {
if (config.buildMode === "none" /* None */) {
@@ -177028,14 +177070,14 @@ async function endTracingForCluster(codeql, config, logger2) {
config.dbLocation,
"temp/tracingEnvironment/end-tracing.json"
);
if (!fs16.existsSync(envVariablesFile)) {
if (!fs17.existsSync(envVariablesFile)) {
throw new Error(
`Environment file for ending tracing not found: ${envVariablesFile}`
);
}
try {
const endTracingEnvVariables = JSON.parse(
fs16.readFileSync(envVariablesFile, "utf8")
fs17.readFileSync(envVariablesFile, "utf8")
);
for (const [key, value] of Object.entries(endTracingEnvVariables)) {
if (value !== null) {
@@ -177056,7 +177098,7 @@ async function getTracerConfigForCluster(logger2, config) {
"temp/tracingEnvironment/start-tracing.json"
);
try {
const tracingEnvVariables = JSON.parse(fs16.readFileSync(filePath, "utf8"));
const tracingEnvVariables = JSON.parse(fs17.readFileSync(filePath, "utf8"));
return {
env: tracingEnvVariables
};
@@ -177178,7 +177220,7 @@ async function getCodeQLForCmd(logger2, cmd, checkVersion, env = getEnv()) {
"tools",
"tracing-config.lua"
);
return fs17.existsSync(tracingConfigPath);
return fs18.existsSync(tracingConfigPath);
},
async isScannedLanguage(language) {
return !await this.isTracedLanguage(language);
@@ -177465,7 +177507,7 @@ async function getCodeQLForCmd(logger2, cmd, checkVersion, env = getEnv()) {
},
async diagnosticsExport(sarifFile, automationDetailsId, config, diagnosticDir) {
let configPath = getGeneratedCodeScanningConfigPath(config);
if (diagnosticDir !== void 0 && !fs17.existsSync(configPath)) {
if (diagnosticDir !== void 0 && !fs18.existsSync(configPath)) {
configPath = void 0;
}
const args = [
@@ -177642,7 +177684,7 @@ async function writeCodeScanningConfigFile(config, logger2) {
logger2.startGroup("Augmented user configuration file contents");
logger2.info(dump(augmentedConfig));
logger2.endGroup();
fs17.writeFileSync(codeScanningConfigFile, dump(augmentedConfig));
fs18.writeFileSync(codeScanningConfigFile, dump(augmentedConfig));
return codeScanningConfigFile;
}
var TRAP_CACHE_SIZE_MB = 1024;
@@ -178138,7 +178180,7 @@ function dbIsFinalized(config, language, logger2) {
const dbPath = getCodeQLDatabasePath(config, language);
try {
const dbInfo = load(
fs18.readFileSync(path16.resolve(dbPath, "codeql-database.yml"), "utf8")
fs19.readFileSync(path16.resolve(dbPath, "codeql-database.yml"), "utf8")
);
return !("inProgress" in dbInfo);
} catch {
@@ -178222,8 +178264,8 @@ function writeDiffRangeDataExtensionPack(logger2, ranges, checkoutPath) {
ranges = [{ path: "", startLine: 0, endLine: 0 }];
}
const diffRangeDir = path16.join(getTemporaryDirectory(), "pr-diff-range");
fs18.mkdirSync(diffRangeDir, { recursive: true });
fs18.writeFileSync(
fs19.mkdirSync(diffRangeDir, { recursive: true });
fs19.writeFileSync(
path16.join(diffRangeDir, "qlpack.yml"),
`
name: codeql-action/pr-diff-range
@@ -178240,7 +178282,7 @@ dataExtensions:
checkoutPath
);
const extensionFilePath = path16.join(diffRangeDir, "pr-diff-range.yml");
fs18.writeFileSync(extensionFilePath, extensionContents);
fs19.writeFileSync(extensionFilePath, extensionContents);
logger2.debug(
`Wrote pr-diff-range extension pack to ${extensionFilePath}:
${extensionContents}`
@@ -178385,7 +178427,7 @@ async function runQueries(sarifFolder, memoryFlag, threadsFlag, diffRangePackDir
}
function getPerQueryAlertCounts(sarifPath) {
const sarifObject = JSON.parse(
fs18.readFileSync(sarifPath, "utf8")
fs19.readFileSync(sarifPath, "utf8")
);
const perQueryAlertCounts = {};
for (const sarifRun of sarifObject.runs) {
@@ -178403,13 +178445,13 @@ async function runQueries(sarifFolder, memoryFlag, threadsFlag, diffRangePackDir
}
async function runFinalize(features, outputDir, threadsFlag, memoryFlag, codeql, config, logger2) {
try {
await fs18.promises.rm(outputDir, { force: true, recursive: true });
await fs19.promises.rm(outputDir, { force: true, recursive: true });
} catch (error3) {
if (error3?.code !== "ENOENT") {
throw error3;
}
}
await fs18.promises.mkdir(outputDir, { recursive: true });
await fs19.promises.mkdir(outputDir, { recursive: true });
const timings = await finalizeDatabaseCreation(
codeql,
features,
@@ -178453,7 +178495,7 @@ async function warnIfGoInstalledAfterInit(config, logger2) {
}
// src/database-upload.ts
var fs19 = __toESM(require("fs"));
var fs20 = __toESM(require("fs"));
async function cleanupAndUploadDatabases(action, repositoryNwo, codeql, config, apiDetails, checkoutPath) {
const logger2 = action.logger;
if (getRequiredInput("upload-database") !== "true") {
@@ -178490,7 +178532,7 @@ async function cleanupAndUploadDatabases(action, repositoryNwo, codeql, config,
const bundledDb = await bundleDb(config, language, codeql, language, {
includeDiagnostics: false
});
bundledDbSize = fs19.statSync(bundledDb).size;
bundledDbSize = fs20.statSync(bundledDb).size;
const commitOid = await getCommitOid(action.env, checkoutPath);
const maxAttempts = 4;
let uploadDurationMs;
@@ -178568,7 +178610,7 @@ async function recordClearCleanupSizes(codeql, config, reports, logger2) {
const bundledDb = await bundleDb(config, language, codeql, language, {
includeDiagnostics: false
});
report.clear_cleanup_zipped_size_bytes = fs19.statSync(bundledDb).size;
report.clear_cleanup_zipped_size_bytes = fs20.statSync(bundledDb).size;
logger2.debug(
`Database for ${language} is ${report.clear_cleanup_zipped_size_bytes} bytes zipped at the '${"clear" /* Clear */}' cleanup level (vs. ${report.zipped_upload_size_bytes ?? "unknown"} bytes at the '${"overlay" /* Overlay */}' level).`
);
@@ -178591,7 +178633,7 @@ async function uploadBundledDatabase(repositoryNwo, language, commitOid, bundled
if (uploadsBaseUrl.endsWith("/")) {
uploadsBaseUrl = uploadsBaseUrl.slice(0, -1);
}
const bundledDbReadStream = fs19.createReadStream(bundledDb);
const bundledDbReadStream = fs20.createReadStream(bundledDb);
try {
const startTime = performance.now();
await client.request(
@@ -178643,7 +178685,7 @@ __export(upload_lib_exports, {
waitForProcessing: () => waitForProcessing,
writePostProcessedFiles: () => writePostProcessedFiles
});
var fs23 = __toESM(require("fs"));
var fs24 = __toESM(require("fs"));
var path19 = __toESM(require("path"));
var url = __toESM(require("url"));
var import_zlib = __toESM(require("zlib"));
@@ -178651,7 +178693,7 @@ var core13 = __toESM(require_core());
var jsonschema2 = __toESM(require_lib2());
// src/fingerprints.ts
var fs20 = __toESM(require("fs"));
var fs21 = __toESM(require("fs"));
var import_path4 = __toESM(require("path"));
// node_modules/long/index.js
@@ -179639,7 +179681,7 @@ async function hash(callback, filepath) {
}
updateHash(current);
};
const readStream = fs20.createReadStream(filepath, "utf8");
const readStream = fs21.createReadStream(filepath, "utf8");
for await (const data of readStream) {
for (let i = 0; i < data.length; ++i) {
processCharacter(data.charCodeAt(i));
@@ -179714,11 +179756,11 @@ function resolveUriToFile(location, artifacts, sourceRoot, logger2) {
if (!import_path4.default.isAbsolute(uri)) {
uri = srcRootPrefix + uri;
}
if (!fs20.existsSync(uri)) {
if (!fs21.existsSync(uri)) {
logger2.debug(`Unable to compute fingerprint for non-existent file: ${uri}`);
return void 0;
}
if (fs20.statSync(uri).isDirectory()) {
if (fs21.statSync(uri).isDirectory()) {
logger2.debug(`Unable to compute fingerprint for directory: ${uri}`);
return void 0;
}
@@ -179773,7 +179815,7 @@ async function addFingerprints(sarifLog, sourceRoot, logger2) {
}
// src/init.ts
var fs21 = __toESM(require("fs"));
var fs22 = __toESM(require("fs"));
var path18 = __toESM(require("path"));
var toolrunner4 = __toESM(require_toolrunner());
var github3 = __toESM(require_github());
@@ -179808,7 +179850,7 @@ async function initConfig2(actionState, inputs) {
});
}
async function runDatabaseInitCluster(databaseInitEnvironment, codeql, config, sourceRoot, processName, qlconfigFile) {
fs21.mkdirSync(config.dbLocation, { recursive: true });
fs22.mkdirSync(config.dbLocation, { recursive: true });
await wrapEnvironment(
databaseInitEnvironment,
async () => await codeql.databaseInitCluster(
@@ -179843,24 +179885,24 @@ async function checkPacksForOverlayCompatibility(codeql, config, logger2) {
function checkPackForOverlayCompatibility(packDir, codeQlOverlayVersion, logger2) {
try {
let qlpackPath = path18.join(packDir, "qlpack.yml");
if (!fs21.existsSync(qlpackPath)) {
if (!fs22.existsSync(qlpackPath)) {
qlpackPath = path18.join(packDir, "codeql-pack.yml");
}
const qlpackContents = load(
fs21.readFileSync(qlpackPath, "utf8")
fs22.readFileSync(qlpackPath, "utf8")
);
if (!qlpackContents.buildMetadata) {
return true;
}
const packInfoPath = path18.join(packDir, ".packinfo");
if (!fs21.existsSync(packInfoPath)) {
if (!fs22.existsSync(packInfoPath)) {
logger2.warning(
`The query pack at ${packDir} does not have a .packinfo file, so it cannot support overlay analysis. Recompiling the query pack with the latest CodeQL CLI should solve this problem.`
);
return false;
}
const packInfoFileContents = JSON.parse(
fs21.readFileSync(packInfoPath, "utf8")
fs22.readFileSync(packInfoPath, "utf8")
);
const packOverlayVersion = packInfoFileContents.overlayVersion;
if (typeof packOverlayVersion !== "number") {
@@ -179895,8 +179937,8 @@ async function checkInstallPython311(languages, codeql) {
]).exec();
}
}
function cleanupDatabaseClusterDirectory(config, logger2, options = {}, rmSync5 = fs21.rmSync) {
if (fs21.existsSync(config.dbLocation) && (fs21.statSync(config.dbLocation).isFile() || fs21.readdirSync(config.dbLocation).length > 0)) {
function cleanupDatabaseClusterDirectory(config, logger2, options = {}, rmSync5 = fs22.rmSync) {
if (fs22.existsSync(config.dbLocation) && (fs22.statSync(config.dbLocation).isFile() || fs22.readdirSync(config.dbLocation).length > 0)) {
if (!options.disableExistingDirectoryWarning) {
logger2.warning(
`The database cluster directory ${config.dbLocation} must be empty. Attempting to clean it up.`
@@ -180001,7 +180043,7 @@ To opt out of this change, ${envVarOptOut}`;
}
// src/sarif/index.ts
var fs22 = __toESM(require("fs"));
var fs23 = __toESM(require("fs"));
var InvalidSarifUploadError = class extends Error {
};
function getToolNames(sarifFile) {
@@ -180017,7 +180059,7 @@ function getToolNames(sarifFile) {
}
function readSarifFile(sarifFilePath) {
try {
return JSON.parse(fs22.readFileSync(sarifFilePath, "utf8"));
return JSON.parse(fs23.readFileSync(sarifFilePath, "utf8"));
} catch (err) {
throw new Error(
`Parsing SARIF file at '${sarifFilePath}' failed: ${getErrorMessage(err)}`
@@ -180158,8 +180200,8 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo
codeQL = initCodeQLResult.codeql;
}
const baseTempDir = path19.resolve(tempDir, "combined-sarif");
fs23.mkdirSync(baseTempDir, { recursive: true });
const outputDirectory = fs23.mkdtempSync(path19.resolve(baseTempDir, "output-"));
fs24.mkdirSync(baseTempDir, { recursive: true });
const outputDirectory = fs24.mkdtempSync(path19.resolve(baseTempDir, "output-"));
const outputFile = path19.resolve(outputDirectory, "combined-sarif.sarif");
await codeQL.mergeResults(sarifFiles, outputFile, {
mergeRunsFromEqualCategory: true
@@ -180204,7 +180246,7 @@ async function uploadPayload(payload, repositoryNwo, logger2, analysis) {
`SARIF upload disabled by an environment variable. Saving to ${payloadSaveFile}`
);
logger2.info(`Payload: ${JSON.stringify(payload, null, 2)}`);
fs23.writeFileSync(payloadSaveFile, JSON.stringify(payload, null, 2));
fs24.writeFileSync(payloadSaveFile, JSON.stringify(payload, null, 2));
return "dummy-sarif-id";
}
const client = getApiClient();
@@ -180238,7 +180280,7 @@ async function uploadPayload(payload, repositoryNwo, logger2, analysis) {
function findSarifFilesInDir(sarifPath, isSarif) {
const sarifFiles = [];
const walkSarifFiles = (dir) => {
const entries = fs23.readdirSync(dir, { withFileTypes: true });
const entries = fs24.readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
if (entry.isFile() && isSarif(entry.name)) {
sarifFiles.push(path19.resolve(dir, entry.name));
@@ -180251,11 +180293,11 @@ function findSarifFilesInDir(sarifPath, isSarif) {
return sarifFiles;
}
function getSarifFilePaths(sarifPath, isSarif) {
if (!fs23.existsSync(sarifPath)) {
if (!fs24.existsSync(sarifPath)) {
throw new ConfigurationError(`Path does not exist: ${sarifPath}`);
}
let sarifFiles;
if (fs23.lstatSync(sarifPath).isDirectory()) {
if (fs24.lstatSync(sarifPath).isDirectory()) {
sarifFiles = findSarifFilesInDir(sarifPath, isSarif);
if (sarifFiles.length === 0) {
throw new ConfigurationError(
@@ -180268,7 +180310,7 @@ function getSarifFilePaths(sarifPath, isSarif) {
return sarifFiles;
}
async function getGroupedSarifFilePaths(logger2, sarifPath) {
const stats = fs23.statSync(sarifPath, { throwIfNoEntry: false });
const stats = fs24.statSync(sarifPath, { throwIfNoEntry: false });
if (stats === void 0) {
throw new ConfigurationError(`Path does not exist: ${sarifPath}`);
}
@@ -180403,7 +180445,7 @@ function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, wo
payloadObj.base_sha = mergeBaseCommitOid;
} else if (process.env.GITHUB_EVENT_PATH) {
const githubEvent = JSON.parse(
fs23.readFileSync(process.env.GITHUB_EVENT_PATH, "utf8")
fs24.readFileSync(process.env.GITHUB_EVENT_PATH, "utf8")
);
payloadObj.base_ref = `refs/heads/${githubEvent.pull_request.base.ref}`;
payloadObj.base_sha = githubEvent.pull_request.base.sha;
@@ -180541,9 +180583,9 @@ async function uploadPostProcessedFiles(logger2, checkoutPath, uploadTarget, pos
};
}
function dumpSarifFile(sarifPayload, outputDir, logger2, uploadTarget) {
if (!fs23.existsSync(outputDir)) {
fs23.mkdirSync(outputDir, { recursive: true });
} else if (!fs23.lstatSync(outputDir).isDirectory()) {
if (!fs24.existsSync(outputDir)) {
fs24.mkdirSync(outputDir, { recursive: true });
} else if (!fs24.lstatSync(outputDir).isDirectory()) {
throw new ConfigurationError(
`The path that processed SARIF files should be written to exists, but is not a directory: ${outputDir}`
);
@@ -180553,7 +180595,7 @@ function dumpSarifFile(sarifPayload, outputDir, logger2, uploadTarget) {
`upload${uploadTarget.sarifExtension}`
);
logger2.info(`Writing processed SARIF file to ${outputFile}`);
fs23.writeFileSync(outputFile, sarifPayload);
fs24.writeFileSync(outputFile, sarifPayload);
}
var STATUS_CHECK_INITIAL_BACKOFF_MILLISECONDS = 5 * 1e3;
var STATUS_CHECK_BACKOFF_MULTIPLIER = 2;
@@ -180800,7 +180842,7 @@ function doesGoExtractionOutputExist(config) {
"trap",
"go" /* go */
);
return fs24.existsSync(trapDirectory) && fs24.readdirSync(trapDirectory).some(
return fs25.existsSync(trapDirectory) && fs25.readdirSync(trapDirectory).some(
(fileName) => [
".trap",
".trap.gz",
@@ -181103,18 +181145,18 @@ async function runWrapper() {
}
// src/analyze-action-post.ts
var fs28 = __toESM(require("fs"));
var fs29 = __toESM(require("fs"));
var core16 = __toESM(require_core());
// src/debug-artifacts.ts
var fs27 = __toESM(require("fs"));
var fs28 = __toESM(require("fs"));
var path23 = __toESM(require("path"));
var artifact = __toESM(require_artifact2());
var artifactLegacy = __toESM(require_artifact_client2());
var core15 = __toESM(require_core());
// node_modules/archiver/lib/core.js
var import_fs = require("fs");
var import_fs2 = require("fs");
// node_modules/is-stream/index.js
function isStream(stream2, { checkOpen = true } = {}) {
@@ -181122,7 +181164,7 @@ function isStream(stream2, { checkOpen = true } = {}) {
}
// node_modules/readdir-glob/dist/index.mjs
var fs25 = __toESM(require("fs"), 1);
var fs26 = __toESM(require("fs"), 1);
var import_events = require("events");
// node_modules/readdir-glob/node_modules/balanced-match/dist/esm/index.js
@@ -182999,7 +183041,7 @@ minimatch.unescape = unescape2;
var import_path6 = require("path");
function readdir2(dir, strict) {
return new Promise((resolve$1, reject) => {
fs25.readdir(dir, { withFileTypes: true }, (err, files) => {
fs26.readdir(dir, { withFileTypes: true }, (err, files) => {
if (err) switch (err.code) {
case "ENOTDIR":
if (strict) reject(err);
@@ -183022,7 +183064,7 @@ function readdir2(dir, strict) {
}
function getStat(file, followSymlinks) {
return new Promise((resolve$1) => {
const statFunc = followSymlinks ? fs25.stat : fs25.lstat;
const statFunc = followSymlinks ? fs26.stat : fs26.lstat;
statFunc(file, (err, stats) => {
if (err) switch (err.code) {
case "ENOENT":
@@ -183192,7 +183234,7 @@ var import_async = __toESM(require_async(), 1);
var import_path7 = require("path");
// node_modules/archiver/lib/error.js
var import_util37 = __toESM(require("util"), 1);
var import_util38 = __toESM(require("util"), 1);
var ERROR_CODES = {
ABORTED: "archive was aborted",
DIRECTORYDIRPATHREQUIRED: "diretory dirpath argument must be a non-empty string value",
@@ -183217,7 +183259,7 @@ function ArchiverError(code, data) {
this.code = code;
this.data = data;
}
import_util37.default.inherits(ArchiverError, Error);
import_util38.default.inherits(ArchiverError, Error);
// node_modules/archiver/lib/core.js
var import_readable_stream2 = __toESM(require_ours(), 1);
@@ -183330,7 +183372,7 @@ var Archiver = class extends import_readable_stream2.Transform {
data.sourcePath = filepath;
task.data = data;
this._entriesCount++;
if (data.stats && data.stats instanceof import_fs.Stats) {
if (data.stats && data.stats instanceof import_fs2.Stats) {
task = this._updateQueueTaskWithStats(task, data.stats);
if (task) {
if (data.stats.size) {
@@ -183578,7 +183620,7 @@ var Archiver = class extends import_readable_stream2.Transform {
callback();
return;
}
(0, import_fs.lstat)(
(0, import_fs2.lstat)(
task.filepath,
function(err, stats) {
if (this._state.aborted) {
@@ -183640,7 +183682,7 @@ var Archiver = class extends import_readable_stream2.Transform {
task.data.type = "file";
task.data.sourceType = "stream";
task.source = new import_lazystream.Readable(function() {
return (0, import_fs.createReadStream)(task.filepath);
return (0, import_fs2.createReadStream)(task.filepath);
});
} else if (stats.isDirectory() && this._supportsDirectory) {
task.data.name = trailingSlashIt(task.data.name);
@@ -183649,7 +183691,7 @@ var Archiver = class extends import_readable_stream2.Transform {
task.data.sourceType = "buffer";
task.source = Buffer.concat([]);
} else if (stats.isSymbolicLink() && this._supportsSymlink) {
const linkPath = (0, import_fs.readlinkSync)(task.filepath);
const linkPath = (0, import_fs2.readlinkSync)(task.filepath);
const dirName = (0, import_path7.dirname)(task.filepath);
task.data.type = "symlink";
task.data.linkname = (0, import_path7.relative)(
@@ -185492,7 +185534,7 @@ var ZipArchive = class extends Archiver {
};
// src/artifact-scanner.ts
var fs26 = __toESM(require("fs"));
var fs27 = __toESM(require("fs"));
var os7 = __toESM(require("os"));
var path22 = __toESM(require("path"));
var exec = __toESM(require_exec());
@@ -185539,7 +185581,7 @@ function isAuthToken(value, patterns = GITHUB_TOKEN_PATTERNS) {
function scanFileForTokens(filePath, relativePath2, logger2) {
const findings = [];
try {
const content = fs26.readFileSync(filePath, "utf8");
const content = fs27.readFileSync(filePath, "utf8");
for (const { type, pattern } of GITHUB_TOKEN_PATTERNS) {
const matches = content.match(pattern);
if (matches) {
@@ -185572,7 +185614,7 @@ async function scanArchiveFile(archivePath, relativeArchivePath, extractDir, log
findings: []
};
try {
const tempExtractDir = fs26.mkdtempSync(
const tempExtractDir = fs27.mkdtempSync(
path22.join(extractDir, `extract-${depth}-`)
);
const fileName = path22.basename(archivePath).toLowerCase();
@@ -185606,7 +185648,7 @@ async function scanArchiveFile(archivePath, relativeArchivePath, extractDir, log
path22.basename(archivePath, ".gz")
);
await exec.exec("gunzip", ["-c", archivePath], {
outStream: fs26.createWriteStream(outputFile),
outStream: fs27.createWriteStream(outputFile),
silent: true
});
} else if (fileName.endsWith(".zip")) {
@@ -185627,7 +185669,7 @@ async function scanArchiveFile(archivePath, relativeArchivePath, extractDir, log
);
result.scannedFiles += scanResult.scannedFiles;
result.findings.push(...scanResult.findings);
fs26.rmSync(tempExtractDir, { recursive: true, force: true });
fs27.rmSync(tempExtractDir, { recursive: true, force: true });
} catch (e) {
logger2.debug(
`Could not extract or scan archive file ${archivePath}: ${getErrorMessage(e)}`
@@ -185662,7 +185704,7 @@ async function scanDirectory(dirPath, baseRelativePath, logger2, depth = 0) {
scannedFiles: 0,
findings: []
};
const entries = fs26.readdirSync(dirPath, { withFileTypes: true });
const entries = fs27.readdirSync(dirPath, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path22.join(dirPath, entry.name);
const relativePath2 = path22.join(baseRelativePath, entry.name);
@@ -185697,10 +185739,10 @@ async function scanArtifactsForTokens(filesToScan, logger2) {
scannedFiles: 0,
findings: []
};
const tempScanDir = fs26.mkdtempSync(path22.join(os7.tmpdir(), "artifact-scan-"));
const tempScanDir = fs27.mkdtempSync(path22.join(os7.tmpdir(), "artifact-scan-"));
try {
for (const filePath of filesToScan) {
const stats = fs26.statSync(filePath);
const stats = fs27.statSync(filePath);
const fileName = path22.basename(filePath);
if (stats.isDirectory()) {
const dirResult = await scanDirectory(filePath, fileName, logger2);
@@ -185738,7 +185780,7 @@ async function scanArtifactsForTokens(filesToScan, logger2) {
}
} finally {
try {
fs26.rmSync(tempScanDir, { recursive: true, force: true });
fs27.rmSync(tempScanDir, { recursive: true, force: true });
} catch (e) {
logger2.debug(
`Could not clean up temporary scan directory: ${getErrorMessage(e)}`
@@ -185760,10 +185802,10 @@ async function uploadCombinedSarifArtifacts(logger2, gitHubVariant) {
);
const baseTempDir = path23.resolve(tempDir, "combined-sarif");
const toUpload = [];
if (fs27.existsSync(baseTempDir)) {
const outputDirs = fs27.readdirSync(baseTempDir);
if (fs28.existsSync(baseTempDir)) {
const outputDirs = fs28.readdirSync(baseTempDir);
for (const outputDir of outputDirs) {
const sarifFiles = fs27.readdirSync(path23.resolve(baseTempDir, outputDir)).filter((f) => path23.extname(f) === ".sarif");
const sarifFiles = fs28.readdirSync(path23.resolve(baseTempDir, outputDir)).filter((f) => path23.extname(f) === ".sarif");
for (const sarifFile of sarifFiles) {
toUpload.push(path23.resolve(baseTempDir, outputDir, sarifFile));
}
@@ -185790,17 +185832,17 @@ async function uploadCombinedSarifArtifacts(logger2, gitHubVariant) {
function tryPrepareSarifDebugArtifact(config, language, logger2) {
try {
const analyzeActionOutputDir = process.env["CODEQL_ACTION_SARIF_RESULTS_OUTPUT_DIR" /* SARIF_RESULTS_OUTPUT_DIR */];
if (analyzeActionOutputDir !== void 0 && fs27.existsSync(analyzeActionOutputDir) && fs27.lstatSync(analyzeActionOutputDir).isDirectory()) {
if (analyzeActionOutputDir !== void 0 && fs28.existsSync(analyzeActionOutputDir) && fs28.lstatSync(analyzeActionOutputDir).isDirectory()) {
const sarifFile = path23.resolve(
analyzeActionOutputDir,
`${language}.sarif`
);
if (fs27.existsSync(sarifFile)) {
if (fs28.existsSync(sarifFile)) {
const sarifInDbLocation = path23.resolve(
config.dbLocation,
`${language}.sarif`
);
fs27.copyFileSync(sarifFile, sarifInDbLocation);
fs28.copyFileSync(sarifFile, sarifInDbLocation);
return sarifInDbLocation;
}
}
@@ -185968,10 +186010,10 @@ async function createPartialDatabaseBundle(config, language) {
core15.info(
`${config.debugDatabaseName}-${language} is not finalized. Uploading partial database bundle at ${databaseBundlePath}...`
);
if (fs27.existsSync(databaseBundlePath)) {
await fs27.promises.rm(databaseBundlePath, { force: true });
if (fs28.existsSync(databaseBundlePath)) {
await fs28.promises.rm(databaseBundlePath, { force: true });
}
const output = fs27.createWriteStream(databaseBundlePath);
const output = fs28.createWriteStream(databaseBundlePath);
const zip = new ZipArchive();
zip.on("error", (err) => {
throw err;
@@ -186021,9 +186063,9 @@ async function runWrapper2() {
getCsharpTempDependencyDir()
];
for (const tempDependencyDir of tempDependencyDirs) {
if (fs28.existsSync(tempDependencyDir)) {
if (fs29.existsSync(tempDependencyDir)) {
try {
fs28.rmSync(tempDependencyDir, { recursive: true });
fs29.rmSync(tempDependencyDir, { recursive: true });
} catch (error3) {
logger2.info(
`Failed to remove temporary dependencies directory: ${getErrorMessage(error3)}`
@@ -186138,7 +186180,7 @@ var fs31 = __toESM(require("fs"));
var path25 = __toESM(require("path"));
var core19 = __toESM(require_core());
var io7 = __toESM(require_io());
var semver12 = __toESM(require_semver2());
var semver11 = __toESM(require_semver2());
// src/config/inputs.ts
async function getToolsInput(action, repositoryProperties) {
@@ -186175,51 +186217,8 @@ async function getToolsInput(action, repositoryProperties) {
}
// src/languages/swift.ts
var fs29 = __toESM(require("fs"));
var semver11 = __toESM(require_semver2());
var XCODE_SELECT_LINK_PATH = "/private/var/db/xcode_select_link";
var XCODE_APP_FILENAME_PATTERN = new RegExp(
/(?<filename>Xcode_(?<majorMinor>\d+.\d+).app)/
);
var SWIFT_TRACED_UNSUPPORTED_MACOS = 27;
var SWIFT_TRACED_UNSUPPORTED_XCODE = 27;
function xcodeVersion(logger2) {
try {
const stats = fs29.statSync(XCODE_SELECT_LINK_PATH);
if (!stats.isSymbolicLink()) {
logger2.warning(
`${XCODE_SELECT_LINK_PATH} exists, but is not a symbolic link.`
);
return void 0;
}
const xcodePath = fs29.readlinkSync(XCODE_SELECT_LINK_PATH);
if (xcodePath === "") {
logger2.warning(
`Resolving ${XCODE_SELECT_LINK_PATH} unexpectedly returned nothing.`
);
return void 0;
}
const matchResult = xcodePath.match(XCODE_APP_FILENAME_PATTERN);
if (matchResult?.groups === void 0) {
logger2.warning(
`Xcode path '${xcodePath}' does not contain expected pattern.`
);
return void 0;
}
const majorMinor = matchResult.groups["majorMinor"];
const version = semver11.coerce(majorMinor);
if (version === null) {
logger2.warning(`Couldn't parse '${majorMinor}' as a semantic version.`);
return void 0;
}
return version;
} catch (err) {
logger2.warning(
`Unable to determine Xcode version: ${getErrorMessage(err)}`
);
return void 0;
}
}
function handleUnsupportedVersion(logger2, config, skipUnsupportedTracedAnalysis, product, version) {
const baseMessage = [
`Traced Swift analysis is not supported on ${product} ${SWIFT_TRACED_UNSUPPORTED_MACOS} or above.`,
@@ -186769,7 +186768,7 @@ async function run3(actionState) {
) {
const publicPreview = "2.22.1";
const actualVer = (await codeql.getVersion()).version;
if (semver12.lt(actualVer, publicPreview)) {
if (semver11.lt(actualVer, publicPreview)) {
actionState.env.export("CODEQL_ENABLE_EXPERIMENTAL_FEATURES" /* EXPERIMENTAL_FEATURES */, "true");
logger2.info("Experimental Rust analysis enabled");
}

View File

@@ -7,6 +7,7 @@ import { getCodeQLForTesting } from "../codeql";
import * as diagnostics from "../diagnostics";
import { ActionsEnvVars } from "../environment";
import { Feature } from "../feature-flags";
import { XCODE_SELECT_LINK_PATH } from "../platform";
import {
checkExpectedLogMessages,
checkUnexpectedLogMessages,
@@ -21,136 +22,12 @@ import {
import { ToolsFeature } from "../tools-features";
import { withTmpDir } from "../util";
import {
isSwiftCompatible,
XCODE_SELECT_LINK_PATH,
xcodeVersion,
} from "./swift";
import { isSwiftCompatible } from "./swift";
import { BuiltInLanguage } from ".";
setupTests(test);
test.serial("xcodeVersion returns undefined if symlink doesn't exist", (t) => {
const logger = new RecordingLogger();
const statSync = sinon.stub(fs, "statSync").throws(new Error("ENOENT"));
t.is(xcodeVersion(logger), undefined);
t.is(statSync.callCount, 1);
t.deepEqual(statSync.args[0], [XCODE_SELECT_LINK_PATH]);
checkExpectedLogMessages(t, logger.messages, [
"Unable to determine Xcode version: ENOENT",
]);
});
test.serial("xcodeVersion returns undefined if file is not a symlink", (t) => {
const logger = new RecordingLogger();
const statSync = sinon
.stub(fs, "statSync")
.returns({ isSymbolicLink: () => false } as fs.Stats);
t.is(xcodeVersion(logger), undefined);
t.is(statSync.callCount, 1);
t.deepEqual(statSync.args[0], [XCODE_SELECT_LINK_PATH]);
checkExpectedLogMessages(t, logger.messages, [
"exists, but is not a symbolic link",
]);
});
test.serial(
"xcodeVersion returns undefined if resolving the symlink returns nothing",
(t) => {
const logger = new RecordingLogger();
const statSync = sinon
.stub(fs, "statSync")
.returns({ isSymbolicLink: () => true } as fs.Stats);
const readlinkSync = sinon.stub(fs, "readlinkSync").returns("");
t.is(xcodeVersion(logger), undefined);
t.is(statSync.callCount, 1);
t.deepEqual(statSync.args[0], [XCODE_SELECT_LINK_PATH]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
checkExpectedLogMessages(t, logger.messages, [
"unexpectedly returned nothing",
]);
},
);
test.serial(
"xcodeVersion returns undefined if resolved path doesn't include pattern",
(t) => {
const logger = new RecordingLogger();
const statSync = sinon
.stub(fs, "statSync")
.returns({ isSymbolicLink: () => true } as fs.Stats);
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.returns("/Applications/Xcode.app/Contents/Developer");
t.is(xcodeVersion(logger), undefined);
t.is(statSync.callCount, 1);
t.deepEqual(statSync.args[0], [XCODE_SELECT_LINK_PATH]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
checkExpectedLogMessages(t, logger.messages, [
"does not contain expected pattern",
]);
},
);
test.serial("xcodeVersion returns undefined if match can't be parsed", (t) => {
const logger = new RecordingLogger();
const statSync = sinon
.stub(fs, "statSync")
.returns({ isSymbolicLink: () => true } as fs.Stats);
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.returns("/Applications/Xcode_00.0.app/Contents/Developer");
t.is(xcodeVersion(logger), undefined);
t.is(statSync.callCount, 1);
t.deepEqual(statSync.args[0], [XCODE_SELECT_LINK_PATH]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
checkExpectedLogMessages(t, logger.messages, [
"Couldn't parse '00.0' as a semantic version.",
]);
});
test.serial("xcodeVersion returns version from resolved path", (t) => {
const logger = new RecordingLogger();
const statSync = sinon
.stub(fs, "statSync")
.returns({ isSymbolicLink: () => true } as fs.Stats);
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.returns("/Applications/Xcode_16.4.app/Contents/Developer");
const result = xcodeVersion(logger);
if (t.truthy(result)) {
t.is(result.major, 16);
t.is(result.minor, 4);
}
t.is(statSync.callCount, 1);
t.deepEqual(statSync.args[0], [XCODE_SELECT_LINK_PATH]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
});
test("isSwiftCompatible doesn't throw for non-Swift languages", async (t) => {
for (const language of Object.values(BuiltInLanguage)) {
if (language === BuiltInLanguage.swift) {

View File

@@ -1,5 +1,3 @@
import * as fs from "fs";
import * as semver from "semver";
import { ActionState, Logger } from "../action-common";
@@ -7,82 +5,18 @@ import { CodeQL } from "../codeql";
import { Config } from "../config-utils";
import { addDiagnostic, makeDiagnostic } from "../diagnostics";
import { Feature } from "../feature-flags";
import { macOSVersion } from "../platform";
import { macOSVersion, xcodeVersion } from "../platform";
import { ToolsFeature } from "../tools-features";
import { ConfigurationError, getErrorMessage } from "../util";
import { ConfigurationError } from "../util";
import { BuiltInLanguage } from ".";
/** The static path we check for a symbolic link to the (dynamic) Xcode location. */
export const XCODE_SELECT_LINK_PATH = "/private/var/db/xcode_select_link";
/** The pattern we expect to find in the Xcode path. */
export const XCODE_APP_FILENAME_PATTERN = new RegExp(
/(?<filename>Xcode_(?<majorMinor>\d+.\d+).app)/,
);
/** macOS 27 and above do not support traced extraction for Swift. */
export const SWIFT_TRACED_UNSUPPORTED_MACOS = 27;
/** Xcode 27 and above do not support traced extraction for Swift. */
export const SWIFT_TRACED_UNSUPPORTED_XCODE = 27;
/**
* Tries to determine the version of Xcode that is installed.
*
* @param logger The logger to use.
* @returns The Xcode version or `undefined` if it couldn't be determined.
*/
export function xcodeVersion(logger: Logger): semver.SemVer | undefined {
try {
// Stat the expected symbolic link to check that it exists and is a symbolic link.
// The `readlinkSync` call below returns an empty string in either case and so
// this check allows us to distinguish between the two cases.
const stats = fs.statSync(XCODE_SELECT_LINK_PATH);
if (!stats.isSymbolicLink()) {
logger.warning(
`${XCODE_SELECT_LINK_PATH} exists, but is not a symbolic link.`,
);
return undefined;
}
// Read what the symbolic link points to.
const xcodePath = fs.readlinkSync(XCODE_SELECT_LINK_PATH);
if (xcodePath === "") {
logger.warning(
`Resolving ${XCODE_SELECT_LINK_PATH} unexpectedly returned nothing.`,
);
return undefined;
}
// Try to extract the version from the path.
const matchResult = xcodePath.match(XCODE_APP_FILENAME_PATTERN);
if (matchResult?.groups === undefined) {
logger.warning(
`Xcode path '${xcodePath}' does not contain expected pattern.`,
);
return undefined;
}
const majorMinor = matchResult.groups["majorMinor"];
const version = semver.coerce(majorMinor);
if (version === null) {
logger.warning(`Couldn't parse '${majorMinor}' as a semantic version.`);
return undefined;
}
return version;
} catch (err) {
logger.warning(
`Unable to determine Xcode version: ${getErrorMessage(err)}`,
);
return undefined;
}
}
/**
* Creates a diagnostic indicating that `version` of `product` is unsupported for traced Swift analysis.
* Depending on `skipUnsupportedTracedAnalysis`, this function then either throws a {@link ConfigurationError}

View File

@@ -1,7 +1,23 @@
import test from "ava";
import fs from "fs";
import { BundlePlatform, getBundlePlatform, macOSVersion } from "./platform";
import { initAllState } from "./testing-utils";
import test from "ava";
import * as sinon from "sinon";
import {
BundlePlatform,
getBundlePlatform,
macOSVersion,
XCODE_SELECT_LINK_PATH,
xcodeVersion,
} from "./platform";
import {
checkExpectedLogMessages,
initAllState,
RecordingLogger,
setupTests,
} from "./testing-utils";
setupTests(test);
for (const [platform, arch, expected] of [
["linux", "x64", BundlePlatform.Linux64],
@@ -54,3 +70,123 @@ test("macOSVersion returns semver if parsing succeeds", (t) => {
t.is(version["patch"], 1);
}
});
test.serial("xcodeVersion returns undefined if symlink doesn't exist", (t) => {
const logger = new RecordingLogger();
const statSync = sinon.stub(fs, "statSync").throws(new Error("ENOENT"));
t.is(xcodeVersion(logger), undefined);
t.is(statSync.callCount, 1);
t.deepEqual(statSync.args[0], [XCODE_SELECT_LINK_PATH]);
checkExpectedLogMessages(t, logger.messages, [
"Unable to determine Xcode version: ENOENT",
]);
});
test.serial("xcodeVersion returns undefined if file is not a symlink", (t) => {
const logger = new RecordingLogger();
const statSync = sinon
.stub(fs, "statSync")
.returns({ isSymbolicLink: () => false } as fs.Stats);
t.is(xcodeVersion(logger), undefined);
t.is(statSync.callCount, 1);
t.deepEqual(statSync.args[0], [XCODE_SELECT_LINK_PATH]);
checkExpectedLogMessages(t, logger.messages, [
"exists, but is not a symbolic link",
]);
});
test.serial(
"xcodeVersion returns undefined if resolving the symlink returns nothing",
(t) => {
const logger = new RecordingLogger();
const statSync = sinon
.stub(fs, "statSync")
.returns({ isSymbolicLink: () => true } as fs.Stats);
const readlinkSync = sinon.stub(fs, "readlinkSync").returns("");
t.is(xcodeVersion(logger), undefined);
t.is(statSync.callCount, 1);
t.deepEqual(statSync.args[0], [XCODE_SELECT_LINK_PATH]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
checkExpectedLogMessages(t, logger.messages, [
"unexpectedly returned nothing",
]);
},
);
test.serial(
"xcodeVersion returns undefined if resolved path doesn't include pattern",
(t) => {
const logger = new RecordingLogger();
const statSync = sinon
.stub(fs, "statSync")
.returns({ isSymbolicLink: () => true } as fs.Stats);
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.returns("/Applications/Xcode.app/Contents/Developer");
t.is(xcodeVersion(logger), undefined);
t.is(statSync.callCount, 1);
t.deepEqual(statSync.args[0], [XCODE_SELECT_LINK_PATH]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
checkExpectedLogMessages(t, logger.messages, [
"does not contain expected pattern",
]);
},
);
test.serial("xcodeVersion returns undefined if match can't be parsed", (t) => {
const logger = new RecordingLogger();
const statSync = sinon
.stub(fs, "statSync")
.returns({ isSymbolicLink: () => true } as fs.Stats);
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.returns("/Applications/Xcode_00.0.app/Contents/Developer");
t.is(xcodeVersion(logger), undefined);
t.is(statSync.callCount, 1);
t.deepEqual(statSync.args[0], [XCODE_SELECT_LINK_PATH]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
checkExpectedLogMessages(t, logger.messages, [
"Couldn't parse '00.0' as a semantic version.",
]);
});
test.serial("xcodeVersion returns version from resolved path", (t) => {
const logger = new RecordingLogger();
const statSync = sinon
.stub(fs, "statSync")
.returns({ isSymbolicLink: () => true } as fs.Stats);
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.returns("/Applications/Xcode_16.4.app/Contents/Developer");
const result = xcodeVersion(logger);
if (t.truthy(result)) {
t.is(result.major, 16);
t.is(result.minor, 4);
}
t.is(statSync.callCount, 1);
t.deepEqual(statSync.args[0], [XCODE_SELECT_LINK_PATH]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
});

View File

@@ -1,6 +1,9 @@
import fs from "fs";
import * as semver from "semver";
import type { ActionState } from "./action-common";
import type { ActionState, Logger } from "./action-common";
import { getErrorMessage } from "./util";
/** Platform identifiers used in CodeQL bundle asset names. */
export enum BundlePlatform {
@@ -53,3 +56,67 @@ export function macOSVersion(
return version;
}
/** The static path we check for a symbolic link to the (dynamic) Xcode location. */
export const XCODE_SELECT_LINK_PATH = "/private/var/db/xcode_select_link";
/** The pattern we expect to find in the Xcode path. */
export const XCODE_APP_FILENAME_PATTERN = new RegExp(
/(?<filename>Xcode_(?<majorMinor>\d+.\d+).app)/,
);
/**
* Tries to determine the version of Xcode that is installed.
*
* @param logger The logger to use.
* @returns The Xcode version or `undefined` if it couldn't be determined.
*/
export function xcodeVersion(logger: Logger): semver.SemVer | undefined {
try {
// Stat the expected symbolic link to check that it exists and is a symbolic link.
// The `readlinkSync` call below returns an empty string in either case and so
// this check allows us to distinguish between the two cases.
const stats = fs.statSync(XCODE_SELECT_LINK_PATH);
if (!stats.isSymbolicLink()) {
logger.warning(
`${XCODE_SELECT_LINK_PATH} exists, but is not a symbolic link.`,
);
return undefined;
}
// Read what the symbolic link points to.
const xcodePath = fs.readlinkSync(XCODE_SELECT_LINK_PATH);
if (xcodePath === "") {
logger.warning(
`Resolving ${XCODE_SELECT_LINK_PATH} unexpectedly returned nothing.`,
);
return undefined;
}
// Try to extract the version from the path.
const matchResult = xcodePath.match(XCODE_APP_FILENAME_PATTERN);
if (matchResult?.groups === undefined) {
logger.warning(
`Xcode path '${xcodePath}' does not contain expected pattern.`,
);
return undefined;
}
const majorMinor = matchResult.groups["majorMinor"];
const version = semver.coerce(majorMinor);
if (version === null) {
logger.warning(`Couldn't parse '${majorMinor}' as a semantic version.`);
return undefined;
}
return version;
} catch (err) {
logger.warning(
`Unable to determine Xcode version: ${getErrorMessage(err)}`,
);
return undefined;
}
}