Remove xcodeVersion and inline fallback logic in checkRunnerSupportsTracedAnalysis

This commit is contained in:
Michael B. Gale
2026-10-30 15:51:13 +00:00
parent 1fb93080c2
commit 8f2596eca1
5 changed files with 68 additions and 44 deletions

View File

@@ -1,5 +1,6 @@
import fs from "fs";
import * as io from "@actions/io";
import test from "ava";
import * as sinon from "sinon";
@@ -426,6 +427,61 @@ test.serial(
}),
);
test.serial(
"checkRunnerSupportsTracedAnalysis uses Xcode SDK version as fallback",
async (t) =>
withTmpDir(async (tmpDir) => {
const logger = new RecordingLogger();
const env = getTestEnv();
env.set(ActionsEnvVars.RUNNER_TEMP, tmpDir);
const features = createFeatures([Feature.CheckUnsupportedTracedAnalysis]);
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.throws(new Error("Not found"));
const which = sinon.stub(io, "which").throws(new Error("Tool not found"));
const codeql = await getCodeQLWithTracedStub(
"codeql-for-testing",
logger,
env,
);
sinon.stub(codeql, "getVersion").resolves(makeVersionInfo("2.27.0"));
const addDiagnostic = sinon.stub(diagnostics, "addDiagnostic");
const config = createTestConfig({
tempDir: tmpDir,
languages: [BuiltInLanguage.swift],
});
await checkRunnerSupportsTracedAnalysis(
initAllState({
logger,
platform: "darwin",
osRelease: "26.0.0",
env,
features,
}),
config,
codeql,
);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
t.is(which.callCount, 1);
t.deepEqual(which.args[0], ["xcrun", true]);
checkExpectedLogMessages(t, logger.messages, [
"Unable to determine Xcode version: Tool not found",
]);
checkUnexpectedLogMessages(t, logger.messages, [
"Traced analysis is not supported on Xcode 27",
]);
t.is(addDiagnostic.callCount, 0);
}),
);
// `addDiagnostic` changes global state and we must stub it, so this test must be serial.
test.serial(
"checkRunnerSupportsTracedAnalysis logs and adds diagnostic if Xcode version is unsupported",

View File

@@ -7,7 +7,11 @@ import type { ActionConfig } from "../config/action-config";
import { addDiagnostic, makeDiagnostic } from "../diagnostics";
import { DocUrl } from "../doc-url";
import { Feature } from "../feature-flags";
import { darwinVersion, xcodeVersion } from "../platform";
import {
darwinVersion,
xcodeVersionFromLink,
xcodeVersionFromSdk,
} from "../platform";
import { ConfigurationError } from "../util";
import { checkSwiftCompatibility } from "./swift";
@@ -196,8 +200,12 @@ export async function checkRunnerSupportsTracedAnalysis(
}
// Determining whether the Xcode version is supported only makes sense on macOS, so we only do it
// after determining that we are running on macOS.
const xcodeVer = await xcodeVersion(action.logger);
// after determining that we are running on macOS. We first try to obtain the version of Xcode itself
// starting with the cheapest approach. If that doesn't work, we obtain the version from the SDK instead.
// Since either Xcode or the SDK at version 27 or above is incompatible, the major version of either is fine.
const xcodeVer =
xcodeVersionFromLink(action.logger) ??
(await xcodeVersionFromSdk(action.logger));
if (
xcodeVer !== undefined &&

View File

@@ -12,7 +12,6 @@ import {
darwinVersion,
XCODE_SELECT_LINK_PATH,
xcodeVersionFromLink,
xcodeVersion,
xcodeVersionFromSdk,
} from "./platform";
import {
@@ -295,27 +294,3 @@ test.serial(
});
},
);
test.serial("xcodeVersion falls back to xcodeVersionFromSdk", async (t) => {
const logger = new RecordingLogger();
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.throws(new Error("ENOENT: no such file or directory"));
const which = sinon.stub(io, "which").throws(new Error("No such tool"));
await t.notThrowsAsync(async () => {
const result = await xcodeVersion(logger);
t.is(result, undefined);
t.is(readlinkSync.callCount, 1);
t.is(which.callCount, 1);
t.deepEqual(which.args[0], ["xcrun", true]);
checkExpectedLogMessages(t, logger.messages, [
"Unable to determine Xcode version: ENOENT: no such file or directory",
"Unable to determine Xcode version: No such tool",
]);
});
});

View File

@@ -170,15 +170,3 @@ export async function xcodeVersionFromSdk(
return undefined;
}
}
/**
* 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 async function xcodeVersion(
logger: Logger,
): Promise<semver.SemVer | undefined> {
return xcodeVersionFromLink(logger) ?? (await xcodeVersionFromSdk(logger));
}