mirror of
https://github.com/github/codeql-action.git
synced 2026-11-05 04:29:40 +00:00
112 lines
3.3 KiB
TypeScript
112 lines
3.3 KiB
TypeScript
import fs from "fs";
|
|
|
|
import * as semver from "semver";
|
|
|
|
import type { ActionState, Logger } from "./action-common";
|
|
import { getErrorMessage } from "./util";
|
|
|
|
/** Platform identifiers used in CodeQL bundle asset names. */
|
|
export enum BundlePlatform {
|
|
Linux64 = "linux64",
|
|
LinuxArm64 = "linux-arm64",
|
|
Osx64 = "osx64",
|
|
Win64 = "win64",
|
|
}
|
|
|
|
/** Returns the bundle platform, or undefined when an all-platform bundle is required. */
|
|
export function getBundlePlatform(
|
|
platform: NodeJS.Platform = process.platform,
|
|
arch: NodeJS.Architecture = process.arch,
|
|
): BundlePlatform | undefined {
|
|
switch (platform) {
|
|
case "win32":
|
|
return BundlePlatform.Win64;
|
|
case "linux":
|
|
return arch === "arm64"
|
|
? BundlePlatform.LinuxArm64
|
|
: BundlePlatform.Linux64;
|
|
case "darwin":
|
|
return BundlePlatform.Osx64;
|
|
default:
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Tries to determine the version of the Darwin kernel. We use this to approximate the macOS version based
|
|
* on the Darwin kernel version so that we don't have to launch an external process. Note that the Darwin
|
|
* kernel major version does not correspond perfectly to the macOS major version.
|
|
*
|
|
* @returns
|
|
* The version as either a semantic version object, the raw version string
|
|
* if it is not a semantic version, or `undefined` if we are not on macOS.
|
|
*/
|
|
export function darwinVersion(
|
|
action: ActionState<["Base"]>,
|
|
): semver.SemVer | string | undefined {
|
|
// Skip if we are not running on macOS.
|
|
if (action.platform !== "darwin") {
|
|
return undefined;
|
|
}
|
|
|
|
// Try to parse the kernel version string.
|
|
const version = semver.parse(action.osRelease);
|
|
|
|
if (version === null) {
|
|
return action.osRelease;
|
|
}
|
|
|
|
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 {
|
|
// Read what the symbolic link points to. This will throw if `XCODE_SELECT_LINK_PATH` does not
|
|
// exist (`ENOENT`) or is not a symbolic link (`EINVAL`).
|
|
const xcodePath = fs.readlinkSync(XCODE_SELECT_LINK_PATH);
|
|
|
|
if (xcodePath.trim() === "") {
|
|
logger.debug(
|
|
`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.debug(
|
|
`Xcode path '${xcodePath}' does not contain expected pattern.`,
|
|
);
|
|
return undefined;
|
|
}
|
|
|
|
const majorMinor = matchResult.groups["majorMinor"];
|
|
const version = semver.coerce(majorMinor);
|
|
|
|
if (version === null) {
|
|
logger.debug(`Couldn't parse '${majorMinor}' as a semantic version.`);
|
|
return undefined;
|
|
}
|
|
return version;
|
|
} catch (err) {
|
|
logger.debug(`Unable to determine Xcode version: ${getErrorMessage(err)}`);
|
|
return undefined;
|
|
}
|
|
}
|