Skip Swift checks if tools feature is enabled

This commit is contained in:
Michael B. Gale
2026-10-09 15:25:46 +01:00
parent 6989a48f28
commit 094875d25b
5 changed files with 116 additions and 31 deletions

7
lib/entry-points.js generated
View File

@@ -186170,10 +186170,13 @@ async function getToolsInput(action, repositoryProperties) {
}
// src/languages/swift.ts
function isSwiftCompatible(action, config) {
async function isSwiftCompatible(action, config, codeql) {
if (!config.languages.includes("swift" /* swift */)) {
return;
}
if (await codeql.supportsFeature("swiftSupportsAllPlatforms" /* SwiftSupportsAllPlatforms */)) {
return;
}
const version = macOSVersion(action);
if (version === void 0) {
throw new ConfigurationError(
@@ -186707,7 +186710,7 @@ async function run3(actionState) {
enableFileCoverageInformation: fileCoverageResult.enabled,
logger: logger2
});
isSwiftCompatible(actionState, config);
await isSwiftCompatible(actionState, config, codeql);
if (repositoryPropertiesResult.isFailure()) {
addNoLanguageDiagnostic(
config,

View File

@@ -419,7 +419,7 @@ async function run(
logger,
});
isSwiftCompatible(actionState, config);
await isSwiftCompatible(actionState, config, codeql);
if (repositoryPropertiesResult.isFailure()) {
addNoLanguageDiagnostic(

View File

@@ -1,59 +1,130 @@
import test from "ava";
import * as sinon from "sinon";
import { getCodeQLForTesting } from "../codeql";
import { ActionsEnvVars } from "../environment";
import {
checkExpectedLogMessages,
createTestConfig,
getTestEnv,
initAllState,
makeVersionInfo,
RecordingLogger,
} from "../testing-utils";
import { ToolsFeature } from "../tools-features";
import { withTmpDir } from "../util";
import { isSwiftCompatible } from "./swift";
import { BuiltInLanguage } from ".";
test("isSwiftCompatible doesn't throw for non-Swift languages", (t) => {
test("isSwiftCompatible doesn't throw for non-Swift languages", async (t) => {
for (const language of Object.values(BuiltInLanguage)) {
if (language === BuiltInLanguage.swift) {
continue;
}
t.notThrows(() =>
const codeql = await getCodeQLForTesting();
await t.notThrowsAsync(
isSwiftCompatible(
initAllState(),
createTestConfig({ languages: [language] }),
codeql,
),
);
}
});
test("isSwiftCompatible doesn't throw for Swift on darwin", (t) => {
t.notThrows(() => {
isSwiftCompatible(
initAllState({ platform: "darwin" }),
createTestConfig({ languages: [BuiltInLanguage.swift] }),
test("isSwiftCompatible doesn't throw for Swift if CLI supports swiftSupportsAllPlatforms", async (t) =>
withTmpDir(async (tmpDir) => {
const logger = new RecordingLogger();
const env = getTestEnv();
env.set(ActionsEnvVars.RUNNER_TEMP, tmpDir);
const codeql = await getCodeQLForTesting("codeql-for-testing", logger, env);
const supportsFeature = sinon
.stub(codeql, "supportsFeature")
.withArgs(ToolsFeature.SwiftSupportsAllPlatforms)
.resolves(true);
await t.notThrowsAsync(
isSwiftCompatible(
initAllState({ platform: "darwin", env, logger }),
createTestConfig({ languages: [BuiltInLanguage.swift] }),
codeql,
),
);
});
});
t.is(supportsFeature.callCount, 1);
t.deepEqual(supportsFeature.args[0], [
ToolsFeature.SwiftSupportsAllPlatforms,
]);
}));
test("isSwiftCompatible doesn't throw for Swift on darwin", async (t) =>
withTmpDir(async (tmpDir) => {
const logger = new RecordingLogger();
const env = getTestEnv();
env.set(ActionsEnvVars.RUNNER_TEMP, tmpDir);
const codeql = await getCodeQLForTesting("codeql-for-testing", logger, env);
sinon.stub(codeql, "getVersion").resolves(makeVersionInfo("2.27.0"));
await t.notThrowsAsync(
isSwiftCompatible(
initAllState({ platform: "darwin", env, logger }),
createTestConfig({ languages: [BuiltInLanguage.swift] }),
codeql,
),
);
}));
const nonDarwinPlatforms: NodeJS.Platform[] = ["linux", "win32"];
for (const nonDarwinPlatform of nonDarwinPlatforms) {
test(`isSwiftCompatible throws for Swift on ${nonDarwinPlatform}`, (t) => {
t.throws(() => {
isSwiftCompatible(
initAllState({ platform: nonDarwinPlatform }),
createTestConfig({ languages: [BuiltInLanguage.swift] }),
test(`isSwiftCompatible throws for Swift on ${nonDarwinPlatform}`, async (t) =>
withTmpDir(async (tmpDir) => {
const logger = new RecordingLogger();
const env = getTestEnv();
env.set(ActionsEnvVars.RUNNER_TEMP, tmpDir);
const codeql = await getCodeQLForTesting(
"codeql-for-testing",
logger,
env,
);
});
});
sinon.stub(codeql, "getVersion").resolves(makeVersionInfo("2.27.0"));
await t.throwsAsync(
isSwiftCompatible(
initAllState({ platform: nonDarwinPlatform, env, logger }),
createTestConfig({ languages: [BuiltInLanguage.swift] }),
codeql,
),
);
}));
}
test("isSwiftCompatible warns if version string is not a semver", (t) => {
const logger = new RecordingLogger();
isSwiftCompatible(
initAllState({ logger, platform: "darwin", osRelease: "unexpected" }),
createTestConfig({ languages: [BuiltInLanguage.swift] }),
);
checkExpectedLogMessages(t, logger.messages, [
"Unable to determine version of macOS, got: unexpected",
]);
});
test("isSwiftCompatible warns if version string is not a semver", async (t) =>
withTmpDir(async (tmpDir) => {
const logger = new RecordingLogger();
const env = getTestEnv();
env.set(ActionsEnvVars.RUNNER_TEMP, tmpDir);
const codeql = await getCodeQLForTesting("codeql-for-testing", logger, env);
sinon.stub(codeql, "getVersion").resolves(makeVersionInfo("2.27.0"));
await isSwiftCompatible(
initAllState({
logger,
platform: "darwin",
osRelease: "unexpected",
env,
}),
createTestConfig({ languages: [BuiltInLanguage.swift] }),
codeql,
);
checkExpectedLogMessages(t, logger.messages, [
"Unable to determine version of macOS, got: unexpected",
]);
}));

View File

@@ -1,6 +1,8 @@
import { ActionState } from "../action-common";
import { CodeQL } from "../codeql";
import { Config } from "../config-utils";
import { macOSVersion } from "../platform";
import { ToolsFeature } from "../tools-features";
import { ConfigurationError } from "../util";
import { BuiltInLanguage } from ".";
@@ -14,15 +16,23 @@ import { BuiltInLanguage } from ".";
* @throws {ConfigurationError} If Swift analysis is not possible on the current runner.
* @returns True if we can run a Swift analysis.
*/
export function isSwiftCompatible(
export async function isSwiftCompatible(
action: ActionState<["Base", "Logger"]>,
config: Config,
codeql: CodeQL,
) {
// The checks are not relevant if we are not trying to analyse Swift.
if (!config.languages.includes(BuiltInLanguage.swift)) {
return;
}
// Skip the checks if the `swiftSupportsAllPlatforms` feature is supported by the CLI.
// This is a forward-looking measure that allows a future CLI update to disable these
// platform checks in the Action when they shouldn't be enforced anymore.
if (await codeql.supportsFeature(ToolsFeature.SwiftSupportsAllPlatforms)) {
return;
}
// Try to get the macOS version.
const version = macOSVersion(action);

View File

@@ -35,6 +35,7 @@ import { Logger } from "./logging";
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
import { getBundlePlatform } from "./platform";
import { ActionName } from "./status-report";
import { ToolsFeature } from "./tools-features";
import {
DEFAULT_DEBUG_ARTIFACT_NAME,
DEFAULT_DEBUG_DATABASE_NAME,
@@ -912,7 +913,7 @@ export function mockLanguagesInRepo(languages: string[]) {
*/
export const makeVersionInfo = (
version: string,
features?: { [name: string]: boolean },
features?: { [key in ToolsFeature]?: boolean },
overlayVersion?: number,
): VersionInfo => ({
version,