diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 10daaff8b..19e35496c 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM registry.gitlab.com/finestructure/spi-base:1.3.0 +FROM registry.gitlab.com/finestructure/spi-base:2.0.0 # Install SPM build dependencies RUN apt-get update && apt-get install -y curl git make unzip \ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e00ed800c..0cf71de06 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: name: Test runs-on: ubuntu-latest container: - image: registry.gitlab.com/finestructure/spi-base:1.3.0 + image: registry.gitlab.com/finestructure/spi-base:2.0.0 options: --privileged steps: - name: GH Runner bug workaround @@ -160,7 +160,7 @@ jobs: name: Release build runs-on: ubuntu-latest container: - image: registry.gitlab.com/finestructure/spi-base:1.3.0 + image: registry.gitlab.com/finestructure/spi-base:2.0.0 options: --privileged steps: - name: GH Runner bug workaround diff --git a/.github/workflows/query-performance.yml b/.github/workflows/query-performance.yml index 034cba8cb..abf7558a1 100644 --- a/.github/workflows/query-performance.yml +++ b/.github/workflows/query-performance.yml @@ -28,7 +28,7 @@ jobs: runs-on: ubuntu-latest continue-on-error: true container: - image: registry.gitlab.com/finestructure/spi-base:1.3.0 + image: registry.gitlab.com/finestructure/spi-base:2.0.0 steps: - name: Checkout code uses: actions/checkout@v4 diff --git a/Dockerfile b/Dockerfile index 5d445b3c9..d5a63b5c9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,7 +18,7 @@ # ================================ # Build image # ================================ -FROM registry.gitlab.com/finestructure/spi-base:1.3.0 as build +FROM registry.gitlab.com/finestructure/spi-base:2.0.0 as build # Set up a build area WORKDIR /build @@ -62,7 +62,7 @@ RUN [ -d /build/Resources ] && { mv /build/Resources ./Resources && chmod -R a-w # ================================ # Run image # ================================ -FROM registry.gitlab.com/finestructure/spi-base:1.3.0 +FROM registry.gitlab.com/finestructure/spi-base:2.0.0 # NB sas 2022-09-23: We're not using a dedicated `vapor` user to run the executable, because it # makes managing the data in the checkouts volume difficult. See diff --git a/LOCAL_DEVELOPMENT_SETUP.md b/LOCAL_DEVELOPMENT_SETUP.md index 8ec8dde73..64145f79e 100644 --- a/LOCAL_DEVELOPMENT_SETUP.md +++ b/LOCAL_DEVELOPMENT_SETUP.md @@ -238,7 +238,7 @@ The trickiest part of this is to ensure the test or app container can connect to So, in order to run the tests in a Linux container run: ``` -docker run --rm -v "$PWD":/host -w /host --add-host=host.docker.internal:host-gateway registry.gitlab.com/finestructure/spi-base:1.3.0 swift test +docker run --rm -v "$PWD":/host -w /host --add-host=host.docker.internal:host-gateway registry.gitlab.com/finestructure/spi-base:2.0.0 swift test ``` Make sure you use the most recent `spi-base` image. You can find the latest image name in the `test-docker` target, which also provides a convenient way to run all all tests in a docker container. diff --git a/Makefile b/Makefile index 52db1a2f7..8879df645 100644 --- a/Makefile +++ b/Makefile @@ -89,7 +89,7 @@ test-docker: @# run tests inside a docker container docker run --rm -v "$(PWD)":/host -w /host \ --add-host=host.docker.internal:host-gateway \ - registry.gitlab.com/finestructure/spi-base:1.3.0 \ + registry.gitlab.com/finestructure/spi-base:2.0.0 \ make test test-e2e: db-reset reconcile ingest analyze diff --git a/Package.resolved b/Package.resolved index ef2162a0b..a7c519412 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "2bcecf7e0a5d6f26686ba99934b5b5024efba0c1e11aff15ee2ca4f1b628fb90", + "originHash" : "450a4f4aa3ad86420402e491c931da027398eff2f4597b5011b210fd21412182", "pins" : [ { "identity" : "async-http-client", @@ -249,8 +249,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/SwiftPackageIndex/SPIManifest.git", "state" : { - "revision" : "aace30e17abaa35713022ecc1cf426292b57f980", - "version" : "1.9.0" + "revision" : "2fad3a95a3740d2eb0dc963bc03737ae35ea2bd8", + "version" : "1.10.0" } }, { diff --git a/Package.swift b/Package.swift index 80f7bdd2f..d0d8fef9c 100644 --- a/Package.swift +++ b/Package.swift @@ -32,7 +32,7 @@ let package = Package( .package(url: "https://github.com/SwiftPackageIndex/Plot.git", branch: "main"), .package(url: "https://github.com/SwiftPackageIndex/CanonicalPackageURL.git", from: "1.0.0"), .package(url: "https://github.com/SwiftPackageIndex/DependencyResolution.git", from: "1.1.2"), - .package(url: "https://github.com/SwiftPackageIndex/SPIManifest.git", from: "1.9.0"), + .package(url: "https://github.com/SwiftPackageIndex/SPIManifest.git", from: "1.10.0"), .package(url: "https://github.com/SwiftPackageIndex/SemanticVersion.git", from: "0.3.0"), .package(url: "https://github.com/SwiftPackageIndex/ShellOut.git", from: "3.3.0"), .package(url: "https://github.com/finestructure/swift-package-manager.git", branch: "release/6.1"), diff --git a/Sources/App/Commands/TriggerBuilds.swift b/Sources/App/Commands/TriggerBuilds.swift index e1488e181..580764867 100644 --- a/Sources/App/Commands/TriggerBuilds.swift +++ b/Sources/App/Commands/TriggerBuilds.swift @@ -389,8 +389,7 @@ struct BuildPair { case .iOS, .linux, .macosSpm, .macosXcodebuild, .tvOS, .watchOS: return BuildPair(platform, swiftVersion) case .visionOS: - // visionOS is only available for Swift versions 5.9+ - return swiftVersion >= .v5_9 ? BuildPair(platform, swiftVersion) : nil + return BuildPair(platform, swiftVersion) case .wasm: // Android is supported from Swift version 6.1+ return swiftVersion >= .v6_1 ? BuildPair(platform, swiftVersion) : nil diff --git a/Sources/App/Core/SwiftVersion+Build.swift b/Sources/App/Core/SwiftVersion+Build.swift index d30c5ed14..594d212dc 100644 --- a/Sources/App/Core/SwiftVersion+Build.swift +++ b/Sources/App/Core/SwiftVersion+Build.swift @@ -18,27 +18,27 @@ extension SwiftVersion { // https://github.com/SwiftPackageIndex/SwiftPackageIndex-Server/issues/1267#issuecomment-975379966 // Patch versions are irrelevant here but the underlying type requires one, so use 0 // in general. - static let v5_9: Self = .init(5, 9, 0) static let v5_10: Self = .init(5, 10, 0) static let v6_0: Self = .init(6, 0, 0) static let v6_1: Self = .init(6, 1, 0) + static let v6_2: Self = .init(6, 2, 0) /// Currently supported swift versions for building static var allActive: [Self] { - [.v5_9, .v5_10, .v6_0, .v6_1] + [.v5_10, .v6_0, .v6_1, .v6_2] } var xcodeVersion: String? { // NB: this is used for display purposes and not critical for compiler selection switch self { - case .v5_9: - return "Xcode 15.2" case .v5_10: return "Xcode 15.4" case .v6_0: return "Xcode 16.2" case .v6_1: return "Xcode 16.3" + case .v6_2: + return "Xcode 26.0" default: return nil } diff --git a/Sources/App/Views/PackageController/SwiftVersion+BuildResultPresentable.swift b/Sources/App/Views/PackageController/SwiftVersion+BuildResultPresentable.swift index 23c1d99ca..2ca911134 100644 --- a/Sources/App/Views/PackageController/SwiftVersion+BuildResultPresentable.swift +++ b/Sources/App/Views/PackageController/SwiftVersion+BuildResultPresentable.swift @@ -17,7 +17,7 @@ extension SwiftVersion: BuildResultPresentable { var longDisplayName: String { "Swift \(displayName)" } var note: String? { switch self { - // case .v6_0: return "beta" + case .v6_2: return "beta" default: return nil } } diff --git a/Tests/AppTests/AlertingTests.swift b/Tests/AppTests/AlertingTests.swift index 88fc8400d..df78f56cf 100644 --- a/Tests/AppTests/AlertingTests.swift +++ b/Tests/AppTests/AlertingTests.swift @@ -34,8 +34,8 @@ extension AllTests.AlertingTests { Alerting.BuildInfo.mock(swiftVersion: $0) } #expect(all.validateSwiftVersionsPresent() == .ok) - #expect(all.filter { $0.swiftVersion != .v1 }.validateSwiftVersionsPresent() == .failed(reasons: ["Missing Swift version: 5.9"])) - #expect(all.filter { $0.swiftVersion != .v1 && $0.swiftVersion != .v2 }.validateSwiftVersionsPresent() == .failed(reasons: ["Missing Swift version: 5.9", "Missing Swift version: 5.10"])) + #expect(all.filter { $0.swiftVersion != .v1 }.validateSwiftVersionsPresent() == .failed(reasons: ["Missing Swift version: 5.10"])) + #expect(all.filter { $0.swiftVersion != .v1 && $0.swiftVersion != .v2 }.validateSwiftVersionsPresent() == .failed(reasons: ["Missing Swift version: 5.10", "Missing Swift version: 6.0"])) } @Test func validatePlatformsSuccessful() throws { @@ -57,13 +57,13 @@ extension AllTests.AlertingTests { Alerting.BuildInfo.mock(swiftVersion: $0, status: .ok) } #expect(all.validateSwiftVersionsSuccessful() == .ok) - #expect(all.filter { $0.swiftVersion != .v1 }.validateSwiftVersionsSuccessful() == .failed(reasons: ["Swift version without successful builds: 5.9"])) + #expect(all.filter { $0.swiftVersion != .v1 }.validateSwiftVersionsSuccessful() == .failed(reasons: ["Swift version without successful builds: 5.10"])) #expect( Array(all.filter { $0.swiftVersion != .v1 }) .appending(.mock(swiftVersion: .v1, status: .failed)) - .validateSwiftVersionsSuccessful() == .failed(reasons: ["Swift version without successful builds: 5.9"]) + .validateSwiftVersionsSuccessful() == .failed(reasons: ["Swift version without successful builds: 5.10"]) ) - #expect(all.filter { $0.swiftVersion != .v1 && $0.swiftVersion != .v2 }.validateSwiftVersionsSuccessful() == .failed(reasons: ["Swift version without successful builds: 5.9", "Swift version without successful builds: 5.10"])) + #expect(all.filter { $0.swiftVersion != .v1 && $0.swiftVersion != .v2 }.validateSwiftVersionsSuccessful() == .failed(reasons: ["Swift version without successful builds: 5.10", "Swift version without successful builds: 6.0"])) } @Test func validateRunnerIdsPresent() throws { diff --git a/Tests/AppTests/ApiTests.swift b/Tests/AppTests/ApiTests.swift index 632b11a6c..43b58065b 100644 --- a/Tests/AppTests/ApiTests.swift +++ b/Tests/AppTests/ApiTests.swift @@ -818,7 +818,7 @@ extension AllTests.ApiTests { let badge = try res.content.decode(Badge.self) #expect(badge.schemaVersion == 1) #expect(badge.label == "Swift") - #expect(badge.message == "5.10 | 5.9") + #expect(badge.message == "6.0 | 5.10") #expect(badge.isError == false) #expect(badge.color == "blue") #expect(badge.cacheSeconds == 6*3600) diff --git a/Tests/AppTests/BadgeTests.swift b/Tests/AppTests/BadgeTests.swift index 4a9de501a..6efe743ac 100644 --- a/Tests/AppTests/BadgeTests.swift +++ b/Tests/AppTests/BadgeTests.swift @@ -20,7 +20,7 @@ import Testing extension AllTests.BadgeTests { @Test func badgeMessage_swiftVersions() throws { - #expect(Badge.badgeMessage(swiftVersions: [.v1, .v2, .v3, .v4]) == "6.1 | 6.0 | 5.10 | 5.9") + #expect(Badge.badgeMessage(swiftVersions: [.v1, .v2, .v3, .v4]) == "6.2 | 6.1 | 6.0 | 5.10") #expect(Badge.badgeMessage(swiftVersions: []) == nil) } diff --git a/Tests/AppTests/BuildIndexModelTests.swift b/Tests/AppTests/BuildIndexModelTests.swift index 52ca7a566..7047b25ee 100644 --- a/Tests/AppTests/BuildIndexModelTests.swift +++ b/Tests/AppTests/BuildIndexModelTests.swift @@ -96,7 +96,7 @@ extension AllTests.BuildIndexModelTests { let matrix = model.buildMatrix // validate - #expect(matrix.values.keys.count == 30) + #expect(matrix.values.keys.count == 32) #expect( matrix.values[.init(swiftVersion: .v3, platform: .iOS)]?.map(\.column.label) == ["1.2.3", "2.0.0-b1", "main"] ) @@ -141,7 +141,7 @@ extension AllTests.BuildIndexModelTests { let matrix = model.buildMatrix // validate - #expect(matrix.values.keys.count == 30) + #expect(matrix.values.keys.count == 32) #expect( matrix.values[.init(swiftVersion: .v3, platform: .iOS)]?.map(\.column.label) == ["1.2.3", "main"] ) diff --git a/Tests/AppTests/BuildTriggerTests.swift b/Tests/AppTests/BuildTriggerTests.swift index ba12a1ef0..06af3f1a8 100644 --- a/Tests/AppTests/BuildTriggerTests.swift +++ b/Tests/AppTests/BuildTriggerTests.swift @@ -266,10 +266,10 @@ extension AllTests.BuildTriggerTests { "\(v) could not be converted to a SPIManifest Swift version") } // Check the values specifically (which we can't easily do in the loop above) - #expect(BuildPair(.iOS, .v5_9).manifestSwiftVersion == .v5_9) #expect(BuildPair(.iOS, .v5_10).manifestSwiftVersion == .v5_10) #expect(BuildPair(.iOS, .v6_0).manifestSwiftVersion == .v6_0) #expect(BuildPair(.iOS, .v6_1).manifestSwiftVersion == .v6_1) + #expect(BuildPair(.iOS, .v6_2).manifestSwiftVersion == .v6_2) } @Test func SPIManifest_docPairs() throws { @@ -289,9 +289,9 @@ extension AllTests.BuildTriggerTests { configs: - documentation_targets: [t0] platform: ios - swift_version: 5.9 + swift_version: 5.10 """) - #expect(manifest.docPairs == [.init(.iOS, .v5_9)]) + #expect(manifest.docPairs == [.init(.iOS, .v5_10)]) } do { let manifest = try SPIManifest.Manifest(yml: """ @@ -301,12 +301,12 @@ extension AllTests.BuildTriggerTests { configs: - documentation_targets: [t0] platform: ios - swift_version: 5.9 + swift_version: 5.10 - documentation_targets: [t0] platform: macos-spm - swift_version: 5.10 + swift_version: 6.0 """) - #expect(manifest.docPairs == [.init(.iOS, .v5_9), .init(.macosSpm, .v5_10)]) + #expect(manifest.docPairs == [.init(.iOS, .v5_10), .init(.macosSpm, .v6_0)]) } } @@ -389,7 +389,7 @@ extension AllTests.BuildTriggerTests { #expect(queries.count == 1) #expect(queries.value.map { $0.variables["VERSION_ID"] } == [versionId.uuidString]) #expect(queries.value.map { $0.variables["BUILD_PLATFORM"] } == ["ios"]) - #expect(queries.value.map { $0.variables["SWIFT_VERSION"] } == ["5.9"]) + #expect(queries.value.map { $0.variables["SWIFT_VERSION"] } == ["5.10"]) // ensure the Build stubs is created to prevent re-selection let v = try await Version.find(versionId, on: app.db) @@ -436,16 +436,16 @@ extension AllTests.BuildTriggerTests { // validate // ensure Gitlab requests go out - #expect(queries.count == 30) - #expect(queries.value.map { $0.variables["VERSION_ID"] } == Array(repeating: versionId.uuidString, count: 30)) + #expect(queries.count == 32) + #expect(queries.value.map { $0.variables["VERSION_ID"] } == Array(repeating: versionId.uuidString, count: 32)) let buildPlatforms = queries.value.compactMap { $0.variables["BUILD_PLATFORM"] } #expect(Dictionary(grouping: buildPlatforms, by: { $0 }) - .mapValues(\.count) == ["android": 1, + .mapValues(\.count) == ["android": 2, "ios": 4, "macos-spm": 4, "macos-xcodebuild": 4, "linux": 4, - "wasm": 1, + "wasm": 2, "watchos": 4, "visionos": 4, "tvos": 4]) @@ -453,13 +453,13 @@ extension AllTests.BuildTriggerTests { #expect(Dictionary(grouping: swiftVersions, by: { $0 }) .mapValues(\.count) == [SwiftVersion.v1.description(droppingZeroes: .patch): 7, SwiftVersion.v2.description(droppingZeroes: .patch): 7, - SwiftVersion.v3.description(droppingZeroes: .patch): 7, + SwiftVersion.v3.description(droppingZeroes: .patch): 9, SwiftVersion.v4.description(droppingZeroes: .patch): 9]) // ensure the Build stubs are created to prevent re-selection let v = try await Version.find(versionId, on: app.db) try await v?.$builds.load(on: app.db) - #expect(v?.builds.count == 30) + #expect(v?.builds.count == 32) // ensure re-selection is empty let candidates = try await fetchBuildCandidates(app.db) @@ -597,11 +597,11 @@ extension AllTests.BuildTriggerTests { try await triggerBuilds(on: app.db, mode: .packageId(pkgId, force: false)) // validate - #expect(triggerCount.value == 30) + #expect(triggerCount.value == 32) // ensure builds are now in progress let v = try await Version.find(versionId, on: app.db) try await v?.$builds.load(on: app.db) - #expect(v?.builds.count == 30) + #expect(v?.builds.count == 32) } } @@ -622,11 +622,11 @@ extension AllTests.BuildTriggerTests { try await triggerBuilds(on: app.db, mode: .packageId(pkgId, force: true)) // validate - #expect(triggerCount.value == 30) + #expect(triggerCount.value == 32) // ensure builds are now in progress let v = try await Version.find(versionId, on: app.db) try await v?.$builds.load(on: app.db) - #expect(v?.builds.count == 30) + #expect(v?.builds.count == 32) } } } @@ -671,7 +671,7 @@ extension AllTests.BuildTriggerTests { try await triggerBuilds(on: app.db, mode: .limit(4)) // validate - only the first batch must be allowed to trigger - #expect(triggerCount.value == 30) + #expect(triggerCount.value == 32) } } } @@ -883,7 +883,7 @@ extension AllTests.BuildTriggerTests { try await triggerBuilds(on: app.db, mode: .packageId(pkgId, force: false)) // validate - #expect(triggerCount.value == 30) + #expect(triggerCount.value == 32) } } } @@ -945,7 +945,7 @@ extension AllTests.BuildTriggerTests { try await triggerBuilds(on: app.db, mode: .packageId(pkgId, force: false)) // validate - #expect(triggerCount.value == 30) + #expect(triggerCount.value == 32) } } } @@ -986,7 +986,7 @@ extension AllTests.BuildTriggerTests { try await triggerBuilds(on: app.db, mode: .packageId(.id0, force: false)) // validate - #expect(triggerCount.value == 30) + #expect(triggerCount.value == 32) } } } @@ -1230,7 +1230,7 @@ extension AllTests.BuildTriggerTests { @Test func BuildPair_all() throws { // Sanity checks for critical counts used in canadidate selection - #expect(BuildPair.all.count == 30) + #expect(BuildPair.all.count == 32) #expect(BuildPair.all == [ .init(.iOS, .v1), .init(.iOS, .v2), @@ -1260,10 +1260,12 @@ extension AllTests.BuildTriggerTests { .init(.linux, .v2), .init(.linux, .v3), .init(.linux, .v4), + .init(.wasm, .v3), .init(.wasm, .v4), + .init(.android, .v3), .init(.android, .v4), ]) - #expect(BuildPair.allExceptLatestSwiftVersion.count == 21) + #expect(BuildPair.allExceptLatestSwiftVersion.count == 23) } @Test func BuildPair_Equatable() throws { @@ -1308,7 +1310,7 @@ extension AllTests.BuildTriggerTests { let res = try await findMissingBuilds(app.db, packageId: pkgId) #expect(res.count == 1) let triggerInfo = try #require(res.first) - #expect(triggerInfo.buildPairs.count == 29) + #expect(triggerInfo.buildPairs.count == 31) #expect(!triggerInfo.buildPairs.contains(.init(.iOS, .v1))) } } diff --git a/Tests/AppTests/Helpers/SwiftVersion+ext.swift b/Tests/AppTests/Helpers/SwiftVersion+ext.swift index 7ecbb9ba2..ec5ca6fb4 100644 --- a/Tests/AppTests/Helpers/SwiftVersion+ext.swift +++ b/Tests/AppTests/Helpers/SwiftVersion+ext.swift @@ -71,10 +71,10 @@ extension SwiftVersion { /// ``` /// /// And then all that remains is to adjust the mapping below whenever we change the range of Swift versions. - static var v1: Self { .v5_9 } - static var v2: Self { .v5_10 } - static var v3: Self { .v6_0 } - static var v4: Self { .v6_1 } + static var v1: Self { .v5_10 } + static var v2: Self { .v6_0 } + static var v3: Self { .v6_1 } + static var v4: Self { .v6_2 } func incrementingPatchVersion(by value: Int = 1) -> Self { .init(major, minor, patch + value) diff --git a/Tests/AppTests/PackageCollectionTests.swift b/Tests/AppTests/PackageCollectionTests.swift index fb1483694..3f263e664 100644 --- a/Tests/AppTests/PackageCollectionTests.swift +++ b/Tests/AppTests/PackageCollectionTests.swift @@ -265,8 +265,8 @@ extension AllTests.PackageCollectionTests { #expect(res.version == "1.2.3") #expect(res.summary == "Bar") #expect(res.verifiedCompatibility == [ - .init(platform: .init(name: "ios"), swiftVersion: .init("5.9")), - .init(platform: .init(name: "macos"), swiftVersion: .init("5.10")), + .init(platform: .init(name: "ios"), swiftVersion: .init("5.10")), + .init(platform: .init(name: "macos"), swiftVersion: .init("6.0")), ]) #expect(res.license == .init(name: "MIT", url: URL(string: "https://foo/mit")!)) #expect(res.createdAt == Date(timeIntervalSince1970: 0)) diff --git a/Tests/AppTests/__Snapshots__/WebpageSnapshotTests/BuildIndex_document.1.html b/Tests/AppTests/__Snapshots__/WebpageSnapshotTests/BuildIndex_document.1.html index 86b09722b..f8e80d1ca 100644 --- a/Tests/AppTests/__Snapshots__/WebpageSnapshotTests/BuildIndex_document.1.html +++ b/Tests/AppTests/__Snapshots__/WebpageSnapshotTests/BuildIndex_document.1.html @@ -104,7 +104,7 @@
71b4d8
), with
- Swift 5.10 for
+ Swift 6.0 for
iOS using
- Xcode 15.4 on
+ Xcode 16.2 on
1 Jan 1970 00:00:00 UTC.