Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ jobs:
ENABLE_WASM_SDK_BUILD: "false"
ENABLE_EMBEDDED_WASM_SDK_BUILD: "false"
ENABLE_ANDROID_SDK_BUILD: "false"
ENABLE_ANDROID_EMULATOR_TESTS: "false"
ENABLE_CXX_INTEROP: "false"
LINUX_SWIFT_VERSIONS: ${{ inputs.linux_swift_versions }}
MACOS_SWIFT_VERSIONS: ${{ inputs.macos_swift_versions }}
Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/package_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ on:
type: boolean
description: "Build with the Swift SDK for Android. Set false to skip it."
default: true
enable_android_emulator_tests:
type: boolean
description: "Run the Android emulator tests after the SDK build. Set false to skip it."
default: true
enable_cxx_interop:
type: boolean
description: "Run the Cxx interoperability check. Set false to skip it."
Expand Down Expand Up @@ -113,10 +109,14 @@ on:
type: string
description: "Android NDK version list (JSON array)."
default: '["r30"]'
android_sdk_triples:
android_sdk_build_triples:
type: string
description: "Android SDK triples (JSON array) that are built only. They share one job. Empty builds none."
default: '["aarch64-unknown-linux-android28"]'
android_emulator_test_triples:
type: string
description: "Android SDK triples (JSON array)."
default: '["aarch64-unknown-linux-android28", "x86_64-unknown-linux-android28"]'
description: "Android SDK triples (JSON array) that are built and then run on an emulator, each in its own job. An emulator's architecture must be one the runner can accelerate, which is the runner's own. A triple is in this list or in android_sdk_build_triples, not both. Empty runs no emulator."
default: '["x86_64-unknown-linux-android28"]'

# ----- Commands & flags -----
linux_command:
Expand Down Expand Up @@ -439,7 +439,6 @@ jobs:
ENABLE_WASM_SDK_BUILD: ${{ inputs.enable_wasm_sdk_build }}
ENABLE_EMBEDDED_WASM_SDK_BUILD: ${{ inputs.enable_embedded_wasm_sdk_build }}
ENABLE_ANDROID_SDK_BUILD: ${{ inputs.enable_android_sdk_build }}
ENABLE_ANDROID_EMULATOR_TESTS: ${{ inputs.enable_android_emulator_tests }}
ENABLE_CXX_INTEROP: ${{ inputs.enable_cxx_interop }}
CXX_INTEROP_SWIFT_VERSIONS: ${{ inputs.cxx_interop_swift_versions }}
LINUX_SWIFT_VERSIONS: ${{ inputs.linux_swift_versions }}
Expand All @@ -460,7 +459,8 @@ jobs:
EMBEDDED_WASM_SDK_VERSIONS: ${{ inputs.embedded_wasm_sdk_versions }}
ANDROID_SDK_VERSIONS: ${{ inputs.android_sdk_versions }}
ANDROID_NDK_VERSIONS: ${{ inputs.android_ndk_versions }}
ANDROID_SDK_TRIPLES: ${{ inputs.android_sdk_triples }}
ANDROID_SDK_BUILD_TRIPLES: ${{ inputs.android_sdk_build_triples }}
ANDROID_EMULATOR_TEST_TRIPLES: ${{ inputs.android_emulator_test_triples }}
LINUX_COMMAND: ${{ inputs.linux_command }}
LINUX_SETUP_COMMAND: ${{ inputs.linux_setup_command }}
MACOS_COMMAND: ${{ inputs.macos_command }}
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ jobs:
enable_wasm_sdk_build: false
enable_embedded_wasm_sdk_build: false
enable_android_sdk_build: false
enable_android_emulator_tests: false
# Two labeled commands, so a run exercises the label suffix.
linux_command: |
Debug-Build: swift build
Expand Down Expand Up @@ -206,7 +205,6 @@ jobs:
enable_wasm_sdk_build: false
enable_embedded_wasm_sdk_build: false
enable_android_sdk_build: false
enable_android_emulator_tests: false
enable_cxx_interop: false

unified_package_test_commands:
Expand All @@ -223,7 +221,6 @@ jobs:
enable_wasm_sdk_build: false
enable_embedded_wasm_sdk_build: false
enable_android_sdk_build: false
enable_android_emulator_tests: false
enable_cxx_interop: false
package_path: tests/TestPackage
linux_swift_versions: '["6.2", "6.3"]'
Expand Down
165 changes: 113 additions & 52 deletions .github/workflows/scripts/matrix/generate-matrix.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ struct Configuration {
@Input("ENABLE_MACOS_SWIFTLY") var swiftlyEnabled = true
@Input("ENABLE_WINDOWS") var windowsEnabled = true
@Input("ENABLE_FREEBSD") var freeBSDEnabled = true
@Input("ENABLE_ANDROID_EMULATOR_TESTS") var androidEmulatorEnabled = true
@Input("ENABLE_CXX_INTEROP") var cxxInteropEnabled = true

/// The release `current` names, such as `6.4`. The workflow supplies it, so that a pinned
Expand Down Expand Up @@ -94,9 +93,11 @@ struct Configuration {
@Input("WINDOWS_JOB_TIMEOUT") var windowsTimeoutMinutes = 0

@Input("ANDROID_NDK_VERSIONS") var androidNDKVersions = ["r30"]
@Input("ANDROID_SDK_TRIPLES") var androidTriples = [
"aarch64-unknown-linux-android28", "x86_64-unknown-linux-android28",
]
/// The triples that are built (not executed).
@Input("ANDROID_SDK_BUILD_TRIPLES") var androidBuildTriples = ["aarch64-unknown-linux-android28"]
/// The triples that are built and then run on an emulator. The emulator's architecture must be
/// one the runner can accelerate, which is the runner's own.
@Input("ANDROID_EMULATOR_TEST_TRIPLES") var androidEmulatorTestTriples = ["x86_64-unknown-linux-android28"]

@Input("CXX_INTEROP_SWIFT_VERSIONS") var cxxInteropVersions: [String] = []

Expand Down Expand Up @@ -124,10 +125,10 @@ struct Configuration {
[self.linuxOverrides, self.macOSOverrides, self.windowsOverrides] + self.sdkBuilds.map(\.overrides)
}

/// The Android SDK build, whose output the emulator tests run.
/// The Android SDK build.
var androidSDKBuild: SDKBuild {
guard let build = self.sdkBuilds.first(where: { $0.kind == .android }) else {
fatal("no Android SDK build is configured, so nothing produces what the emulator runs.")
fatal("no Android SDK build is configured.")
}
return build
}
Expand All @@ -139,15 +140,37 @@ extension Configuration {
/// Fails on a pair of inputs that cannot both be honored. Each would otherwise produce a
/// matrix without the jobs the caller asked for.
func validatePairings(in mode: Matrix.Mode) {
// Toolchains mode emits neither the emulator nor the build it runs, so the pairing only
// has to hold where both could appear.
if mode == .jobs && self.androidEmulatorEnabled && !self.androidSDKBuild.enabled {
fatal(
"""
enable_android_emulator_tests needs enable_android_sdk_build; the emulator runs what that build \
produces.
"""
)
// Toolchains mode emits no Android entries, so the triples only matter where they could appear.
if mode == .jobs && self.androidSDKBuild.enabled {
if self.androidBuildTriples.isEmpty && self.androidEmulatorTestTriples.isEmpty {
fatal(
"""
enable_android_sdk_build is set, but android_sdk_build_triples and android_emulator_test_triples are \
both empty, so there is nothing to build.
"""
)
}

let triples = self.androidBuildTriples + self.androidEmulatorTestTriples
if triples.contains(where: { $0.allSatisfy(\.isWhitespace) }) {
fatal(
"""
android_sdk_build_triples and android_emulator_test_triples must name each triple, but one is blank; \
the SDK build is given it as an empty --android-sdk-triple.
"""
)
}

let repeated = Set(triples.filter { triple in triples.filter { $0 == triple }.count > 1 })
if !repeated.isEmpty {
fatal(
"""
\(repeated.sorted().joined(separator: ", ")) appears more than once across \
android_sdk_build_triples and android_emulator_test_triples; a triple is built once, and either \
only built or built and tested.
"""
)
}
}
// An Apple-platform target rides on a macOS entry, so asking for one without enabling
// macOS produces no jobs at all.
Expand Down Expand Up @@ -483,13 +506,10 @@ extension Generator {

guard build.kind == .android else { return jobs }
jobs.android = SwiftBuildJobs.AndroidBuild(
triples: self.configuration.androidTriples,
ndkVersions: self.configuration.androidNDKVersions,
emulatorEnabled: self.configuration.androidEmulatorEnabled
buildTriples: self.configuration.androidBuildTriples,
emulatorTestTriples: self.configuration.androidEmulatorTestTriples,
ndkVersions: self.configuration.androidNDKVersions
)
// The emulator runs what the build produced, so the build is told to make test binaries
// and takes none of the flags inputs.
jobs.flags = .always(self.configuration.androidEmulatorEnabled ? "--build-tests" : "")
return jobs
}

Expand Down Expand Up @@ -1018,12 +1038,12 @@ struct SwiftBuildJobs: JobGroup {

/// The parts of an Android SDK build that the other SDK builds have no counterpart for.
struct AndroidBuild {
/// The triples the SDK is installed for.
var triples: [String]
/// The triples that are built and nothing more.
var buildTriples: [String]
/// The triples that are built and run on an emulator, each in an entry of its own.
var emulatorTestTriples: [String]
/// The NDK releases the entries fan out over.
var ndkVersions: [String]
/// Whether the executor runs what the build produced on an emulator.
var emulatorEnabled: Bool
}

/// One entry's value from every axis.
Expand Down Expand Up @@ -1059,34 +1079,75 @@ struct SwiftBuildJobs: JobGroup {
}
}

var entries: [MatrixEntry] {
self.combinations.map { combination in
let toolchain = Toolchain(label: combination.versionLabel, releases: self.releases)
var sdk = self.sdk
sdk?.ndkVersion = combination.ndkVersion
sdk?.triples = self.android?.triples
return MatrixEntry(
platform: self.platform,
name: self.settings.name(
"\(self.settings.namePrefix) \(combination.versionLabel)",
combination.ndkVersion.map { "NDK \($0)" },
self.images.count > 1 ? combination.image?.distribution : nil,
self.runners.count > 1 ? combination.runner.name : nil,
for: combination.variant
),
runner: combination.runner.labels,
swiftBuild: MatrixEntry.SwiftBuild(
toolchain,
sdk: sdk,
container: combination.image?.container(toolchain)
),
setupCommand: self.setupCommand,
command: self.command(for: combination),
commandArguments: self.flags.arguments(for: combination.versionLabel),
env: self.environment,
androidEmulator: self.android?.emulatorEnabled
)
/// The triples one entry builds, and whether it runs the emulator on them.
private struct TripleGroup {
var triples: [String]
var runsEmulator: Bool

/// Names what the entry builds, such as `aarch64-android28+armv7-androideabi28`. The API level
/// is part of the name because two triples of one architecture can build in separate entries.
var nameSuffix: String {
self.triples.map { $0.replacing("-unknown-linux", with: "") }.joined(separator: "+")
}

/// The emulator runs what the build produced, so an entry that runs it builds the tests. An
/// Android build takes none of the flags inputs.
var buildArguments: [String] {
self.runsEmulator ? ["--build-tests"] : []
}
}

/// How the Android triples divide across entries, or none for a build with no Android triples.
/// Each emulator triple gets an entry of its own, and the build-only triples share one that has
/// no emulator to run, so no emulator waits on builds it never runs.
private var tripleGroups: [TripleGroup]? {
guard let android = self.android else {
return nil
}
let emulatorGroups = android.emulatorTestTriples.map { TripleGroup(triples: [$0], runsEmulator: true) }
if android.buildTriples.isEmpty {
return emulatorGroups
}
return emulatorGroups + [TripleGroup(triples: android.buildTriples, runsEmulator: false)]
}

var entries: [MatrixEntry] {
self.combinations.flatMap { combination -> [MatrixEntry] in
guard let groups = self.tripleGroups else {
return [self.entry(for: combination, group: nil, named: false)]
}
// Entries are told apart by what they build only when the triples are split across them.
return groups.map { self.entry(for: combination, group: $0, named: groups.count > 1) }
}
}

private func entry(for combination: Combination, group: TripleGroup?, named: Bool) -> MatrixEntry {
let toolchain = Toolchain(label: combination.versionLabel, releases: self.releases)
var sdk = self.sdk
sdk?.ndkVersion = combination.ndkVersion
sdk?.triples = group?.triples
return MatrixEntry(
platform: self.platform,
name: self.settings.name(
"\(self.settings.namePrefix) \(combination.versionLabel)",
combination.ndkVersion.map { "NDK \($0)" },
named ? group?.nameSuffix : nil,
self.images.count > 1 ? combination.image?.distribution : nil,
self.runners.count > 1 ? combination.runner.name : nil,
for: combination.variant
),
runner: combination.runner.labels,
swiftBuild: MatrixEntry.SwiftBuild(
toolchain,
sdk: sdk,
container: combination.image?.container(toolchain)
),
setupCommand: self.setupCommand,
command: self.command(for: combination),
commandArguments: group?.buildArguments ?? self.flags.arguments(for: combination.versionLabel),
env: self.environment,
androidEmulator: group?.runsEmulator
)
}

/// The command one entry runs. A group whose command is the check itself takes no
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/toolchain_matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ jobs:
ENABLE_WASM_SDK_BUILD: "false"
ENABLE_EMBEDDED_WASM_SDK_BUILD: "false"
ENABLE_ANDROID_SDK_BUILD: "false"
ENABLE_ANDROID_EMULATOR_TESTS: "false"
ENABLE_CXX_INTEROP: "false"
LINUX_SWIFT_VERSIONS: ${{ inputs.linux_swift_versions }}
LINUX_HOST_ARCHS: ${{ inputs.linux_host_archs }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ public struct EntryPoint: Sendable, CustomStringConvertible {
"ENABLE_WASM_SDK_BUILD",
"ENABLE_EMBEDDED_WASM_SDK_BUILD",
"ENABLE_ANDROID_SDK_BUILD",
"ENABLE_ANDROID_EMULATOR_TESTS",
"ENABLE_CXX_INTEROP",
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ private let everyGroup = [
"LINUX_STATIC_SDK_VERSIONS": #"["6.3"]"#,
"ANDROID_SDK_VERSIONS": #"["6.3"]"#,
"ANDROID_NDK_VERSIONS": #"["r27d"]"#,
// Empty, so the Android build stays a single entry; with an emulator triple it splits in two.
"ANDROID_EMULATOR_TEST_TRIPLES": "[]",
]

/// The names those groups produce when each runs one command.
Expand Down Expand Up @@ -454,6 +456,7 @@ struct VersionOverrideCommandTests {
// command instead ran what the caller replaced, and still passed.
var environment = [
"ANDROID_NDK_VERSIONS": #"["r27d"]"#,
"ANDROID_EMULATOR_TEST_TRIPLES": "[]",
"LINUX_SWIFT_VERSIONS": #"["6.3"]"#,
]
environment[enableKey] = "true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,12 @@ struct EntryPointDefaultTests {
"Embedded Wasm SDK Swift current",
"Embedded Wasm SDK Swift nightly-release",
"Embedded Wasm SDK Swift nightly-main",
"Android SDK Swift current NDK r30",
"Android SDK Swift nightly-release NDK r30",
"Android SDK Swift nightly-main NDK r30",
"Android SDK Swift current NDK r30 x86_64-android28",
"Android SDK Swift current NDK r30 aarch64-android28",
"Android SDK Swift nightly-release NDK r30 x86_64-android28",
"Android SDK Swift nightly-release NDK r30 aarch64-android28",
"Android SDK Swift nightly-main NDK r30 x86_64-android28",
"Android SDK Swift nightly-main NDK r30 aarch64-android28",
"Cxx interop Swift current-2",
"Cxx interop Swift current-1",
"Cxx interop Swift current",
Expand Down Expand Up @@ -119,9 +122,12 @@ struct EntryPointDefaultTests {
viaWorkflow["ENABLE_ANDROID_SDK_BUILD"] = "true"

let expected = [
"Android SDK Swift current NDK r30",
"Android SDK Swift nightly-release NDK r30",
"Android SDK Swift nightly-main NDK r30",
"Android SDK Swift current NDK r30 x86_64-android28",
"Android SDK Swift current NDK r30 aarch64-android28",
"Android SDK Swift nightly-release NDK r30 x86_64-android28",
"Android SDK Swift nightly-release NDK r30 aarch64-android28",
"Android SDK Swift nightly-main NDK r30 x86_64-android28",
"Android SDK Swift nightly-main NDK r30 aarch64-android28",
]

let workflow = try Generator.run(viaWorkflow, manifests: manifest)
Expand Down
Loading
Loading