diff --git a/Tools/Sources/Commands/CI/CI.swift b/Tools/Sources/Commands/CI/CI.swift index ff5a0b048..2a4ac9bb4 100644 --- a/Tools/Sources/Commands/CI/CI.swift +++ b/Tools/Sources/Commands/CI/CI.swift @@ -6,6 +6,7 @@ import Yams struct CI: ParsableCommand { static let configuration = CommandConfiguration(abstract: "CI workflow commands that can be run both locally and in CI environments.", subcommands: [ + PreviewTests.self, AccessibilityTests.self, UnitTests.self, UITests.self, diff --git a/Tools/Sources/Commands/CI/PreviewTests.swift b/Tools/Sources/Commands/CI/PreviewTests.swift new file mode 100644 index 000000000..9d120bb40 --- /dev/null +++ b/Tools/Sources/Commands/CI/PreviewTests.swift @@ -0,0 +1,42 @@ +import ArgumentParser +import Foundation + +struct PreviewTests: AsyncParsableCommand { + static let configuration = CommandConfiguration(commandName: "preview-tests", + abstract: "Runs the preview test CI workflow.") + + @Option(help: "iOS version for the simulator.") + var osVersion = "26.4" + + private static let scheme = "PreviewTests" + private static let device = "iPhone SE (3rd generation)" + private static let simulatorType = "com.apple.CoreSimulator.SimDeviceType.iPhone-SE-3rd-generation" + private static let testPlanPath = "PreviewTests/SupportingFiles/PreviewTests.xctestplan" + + func run() async throws { + var testsFailed = false + do { + logger.info("\n🧪 Running preview tests…\n") + try await RunTests.parse([ + "--scheme", Self.scheme, + "--device", Self.device, + "--os-version", osVersion, + "--create-simulator-name", Self.device, + "--create-simulator-type", Self.simulatorType + ]).run() + } catch { + logger.error("\nāŒ Preview tests failed.\n") + testsFailed = true + } + + // Collect coverage and test results regardless of test outcome (best-effort). + await CI.collectCoverage(resultBundle: "\(Self.scheme).xcresult", outputName: "preview-cobertura.xml") + await CI.collectTestResults(resultBundle: "\(Self.scheme).xcresult", outputName: "preview-junit.xml") + + if testsFailed { + throw ExitCode.failure + } + + logger.info("\nāœ… Preview tests passed.\n") + } +} diff --git a/Tools/Sources/Commands/CI/UnitTests.swift b/Tools/Sources/Commands/CI/UnitTests.swift index b27d1a606..6a81b2537 100644 --- a/Tools/Sources/Commands/CI/UnitTests.swift +++ b/Tools/Sources/Commands/CI/UnitTests.swift @@ -34,19 +34,10 @@ struct UnitTests: AsyncParsableCommand { } if !skipPreviews { - // Run preview tests on a smaller device do { - logger.info("\n🧪 Running preview tests…\n") - try await RunTests.parse([ - "--scheme", "PreviewTests", - "--device", "iPhone SE (3rd generation)", - "--os-version", osVersion, - "--create-simulator-name", "iPhone SE (3rd generation)", - "--create-simulator-type", "com.apple.CoreSimulator.SimDeviceType.iPhone-SE-3rd-generation" - ]).run() + try await PreviewTests.parse(["--os-version", osVersion]).run() } catch { failures.append("Preview tests failed: \(error)") - logger.error("\nāŒ Preview tests failed.\n") } } @@ -54,13 +45,9 @@ struct UnitTests: AsyncParsableCommand { await CI.zipResults(bundles: ["UnitTests.xcresult", "PreviewTests.xcresult"], outputName: "UnitTests.zip") - // Collect coverage reports + // Collect coverage and JUnit results for unit tests await CI.collectCoverage(resultBundle: "UnitTests.xcresult", outputName: "unit-cobertura.xml") - await CI.collectCoverage(resultBundle: "PreviewTests.xcresult", outputName: "preview-cobertura.xml") - - // Collect JUnit test results await CI.collectTestResults(resultBundle: "UnitTests.xcresult", outputName: "unit-junit.xml") - await CI.collectTestResults(resultBundle: "PreviewTests.xcresult", outputName: "preview-junit.xml") if !failures.isEmpty { logger.error("\nāŒ \(failures.count) test suite(s) failed.\n")