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 9271dd21d5
commit a9623043dc
5 changed files with 99 additions and 30 deletions

7
lib/entry-points.js generated
View File

@@ -193851,10 +193851,13 @@ async function getToolsInput(action, repositoryProperties) {
}
// src/languages/swift.ts
function checkSwiftCompatibility(action, config) {
async function checkSwiftCompatibility(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(
@@ -194388,7 +194391,7 @@ async function run3(actionState) {
enableFileCoverageInformation: fileCoverageResult.enabled,
logger: logger2
});
checkSwiftCompatibility(actionState, config);
await checkSwiftCompatibility(actionState, config, codeql);
if (repositoryPropertiesResult.isFailure()) {
addNoLanguageDiagnostic(
config,

View File

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

View File

@@ -11,27 +11,56 @@ import {
makeVersionInfo,
RecordingLogger,
} from "../testing-utils";
import { ToolsFeature } from "../tools-features";
import { ConfigurationError, withTmpDir } from "../util";
import { checkSwiftCompatibility } from "./swift";
import { BuiltInLanguage } from ".";
test("checkSwiftCompatibility doesn't throw for non-Swift languages", (t) => {
test("checkSwiftCompatibility 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(
checkSwiftCompatibility(
initAllState(),
createTestConfig({ languages: [language] }),
codeql,
),
);
}
});
test("checkSwiftCompatibility 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(
checkSwiftCompatibility(
initAllState({ platform: "darwin", env, logger }),
createTestConfig({ languages: [BuiltInLanguage.swift] }),
codeql,
),
);
t.is(supportsFeature.callCount, 1);
t.deepEqual(supportsFeature.args[0], [
ToolsFeature.SwiftSupportsAllPlatforms,
]);
}));
test("checkSwiftCompatibility doesn't throw for Swift on darwin", async (t) =>
withTmpDir(async (tmpDir) => {
const logger = new RecordingLogger();
@@ -41,42 +70,68 @@ test("checkSwiftCompatibility doesn't throw for Swift on darwin", async (t) =>
const codeql = await getCodeQLForTesting("codeql-for-testing", logger, env);
sinon.stub(codeql, "getVersion").resolves(makeVersionInfo("2.27.0"));
t.notThrows(() =>
await t.notThrowsAsync(
checkSwiftCompatibility(
initAllState({ platform: "darwin", env, logger }),
createTestConfig({
tempDir: tmpDir,
languages: [BuiltInLanguage.swift],
}),
codeql,
),
);
}));
const nonDarwinPlatforms: NodeJS.Platform[] = ["linux", "win32"];
for (const nonDarwinPlatform of nonDarwinPlatforms) {
test(`checkSwiftCompatibility throws for Swift on ${nonDarwinPlatform}`, (t) => {
t.throws(
() => {
test(`checkSwiftCompatibility 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(
checkSwiftCompatibility(
initAllState({ platform: nonDarwinPlatform }),
initAllState({ platform: nonDarwinPlatform, env, logger }),
createTestConfig({ languages: [BuiltInLanguage.swift] }),
);
},
{
instanceOf: ConfigurationError,
message: /^Swift analysis is only supported on macOS runner images/,
},
);
});
codeql,
),
{
instanceOf: ConfigurationError,
message: /^Swift analysis is only supported on macOS runner images/,
},
);
}));
}
test("checkSwiftCompatibility warns if version string is not a semver", (t) => {
const logger = new RecordingLogger();
checkSwiftCompatibility(
initAllState({ logger, platform: "darwin", osRelease: "unexpected" }),
createTestConfig({ languages: [BuiltInLanguage.swift] }),
);
checkExpectedLogMessages(t, logger.messages, [
"Unable to determine version of macOS, got: unexpected",
]);
});
test("checkSwiftCompatibility 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 checkSwiftCompatibility(
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 ".";
@@ -13,15 +15,23 @@ import { BuiltInLanguage } from ".";
*
* @throws {ConfigurationError} If Swift analysis is not possible on the current runner.
*/
export function checkSwiftCompatibility(
export async function checkSwiftCompatibility(
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 { joinMessageStrings, Loggable, LoggableError, 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,
@@ -913,7 +914,7 @@ export function mockLanguagesInRepo(languages: string[]) {
*/
export const makeVersionInfo = (
version: string,
features?: { [name: string]: boolean },
features?: { [key in ToolsFeature]?: boolean },
overlayVersion?: number,
): VersionInfo => ({
version,