Raise minimum supported Swift version from 5.4 to 5.5 (#2267)

Motivation:

SwiftNIO periodically drops support for older Swift versions. Now that
5.7 has been released, 5.4 will be dropped.

Modifications:

- Remove 5.4 specific Package.swift and docker-compose
- Update the 5.7 docker-compose to use the released 5.7 and move from
  focal (2004) to jammy (2204)
- Remove unused swiftformat from Dockerfile
- Update tools version in syscall wrapper tests to 5.5
- Update docs

Results:

Minimum Swift version is 5.5
This commit is contained in:
George Barnett 2022-09-29 11:47:44 +01:00 committed by GitHub
parent 39e61f636f
commit fcca969463
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 47 additions and 202 deletions

View File

@ -72,7 +72,7 @@ For this reason, whenever you add new tests **you have to run a script** that ge
### Make sure your patch works for all supported versions of swift
The CI will do this for you. You can use the docker-compose files included if you wish to check locally. Currently all versions of swift >= 5.4 are supported. For example usage of docker compose see the main [README](./README.md#an-alternative-using-docker-compose)
The CI will do this for you. You can use the docker-compose files included if you wish to check locally. Currently all versions of swift >= 5.5 are supported. For example usage of docker compose see the main [README](./README.md#an-alternative-using-docker-compose)
### Make sure your code is performant

View File

@ -17,7 +17,7 @@ set -eu
function make_package() {
cat > "$tmpdir/syscallwrapper/Package.swift" <<"EOF"
// swift-tools-version:5.4
// swift-tools-version:5.5
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription

View File

@ -1,150 +0,0 @@
// swift-tools-version:5.4
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2017-2021 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import PackageDescription
let swiftAtomics: PackageDescription.Target.Dependency = .product(name: "Atomics", package: "swift-atomics")
let swiftCollections: PackageDescription.Target.Dependency = .product(name: "DequeModule", package: "swift-collections")
var targets: [PackageDescription.Target] = [
.target(name: "NIOCore",
dependencies: ["NIOConcurrencyHelpers", "CNIOLinux", "CNIOWindows", swiftCollections, swiftAtomics]),
.target(name: "_NIODataStructures"),
.target(name: "NIOEmbedded",
dependencies: ["NIOCore",
"NIOConcurrencyHelpers",
"_NIODataStructures",
swiftAtomics]),
.target(name: "NIOPosix",
dependencies: ["CNIOLinux",
"CNIODarwin",
"CNIOWindows",
"NIOConcurrencyHelpers",
"NIOCore",
"_NIODataStructures",
swiftAtomics]),
.target(name: "NIO",
dependencies: ["NIOCore",
"NIOEmbedded",
"NIOPosix"]),
.target(name: "_NIOConcurrency",
dependencies: ["NIO", "NIOCore"]),
.target(name: "_NIOBeta",
dependencies: ["NIOCore"]),
.target(name: "NIOFoundationCompat", dependencies: ["NIO", "NIOCore"]),
.target(name: "CNIOAtomics", dependencies: []),
.target(name: "CNIOSHA1", dependencies: []),
.target(name: "CNIOLinux", dependencies: []),
.target(name: "CNIODarwin", dependencies: [], cSettings: [.define("__APPLE_USE_RFC_3542")]),
.target(name: "CNIOWindows", dependencies: []),
.target(name: "NIOConcurrencyHelpers",
dependencies: ["CNIOAtomics"]),
.target(name: "NIOHTTP1",
dependencies: ["NIO", "NIOCore", "NIOConcurrencyHelpers", "CNIOLLHTTP"]),
.executableTarget(name: "NIOEchoServer",
dependencies: ["NIOPosix", "NIOCore", "NIOConcurrencyHelpers"],
exclude: ["README.md"]),
.executableTarget(name: "NIOEchoClient",
dependencies: ["NIOPosix", "NIOCore", "NIOConcurrencyHelpers"],
exclude: ["README.md"]),
.executableTarget(name: "NIOHTTP1Server",
dependencies: ["NIOPosix", "NIOCore", "NIOHTTP1", "NIOConcurrencyHelpers"],
exclude: ["README.md"]),
.executableTarget(name: "NIOHTTP1Client",
dependencies: ["NIOPosix", "NIOCore", "NIOHTTP1", "NIOConcurrencyHelpers"],
exclude: ["README.md"]),
.target(
name: "CNIOLLHTTP",
cSettings: [.define("LLHTTP_STRICT_MODE")]
),
.target(name: "NIOTLS", dependencies: ["NIO", "NIOCore"]),
.executableTarget(name: "NIOChatServer",
dependencies: ["NIOPosix", "NIOCore", "NIOConcurrencyHelpers"],
exclude: ["README.md"]),
.executableTarget(name: "NIOChatClient",
dependencies: ["NIOPosix", "NIOCore", "NIOConcurrencyHelpers"],
exclude: ["README.md"]),
.target(name: "NIOWebSocket",
dependencies: ["NIO", "NIOCore", "NIOHTTP1", "CNIOSHA1"]),
.executableTarget(name: "NIOWebSocketServer",
dependencies: ["NIOPosix", "NIOCore", "NIOHTTP1", "NIOWebSocket"],
exclude: ["README.md"]),
.executableTarget(name: "NIOWebSocketClient",
dependencies: ["NIOPosix", "NIOCore", "NIOHTTP1", "NIOWebSocket"],
exclude: ["README.md"]),
.executableTarget(name: "NIOPerformanceTester",
dependencies: ["NIOPosix", "NIOCore", "NIOEmbedded", "NIOHTTP1", "NIOFoundationCompat", "NIOWebSocket"]),
.executableTarget(name: "NIOMulticastChat",
dependencies: ["NIOPosix", "NIOCore"]),
.executableTarget(name: "NIOUDPEchoServer",
dependencies: ["NIOPosix", "NIOCore"],
exclude: ["README.md"]),
.executableTarget(name: "NIOUDPEchoClient",
dependencies: ["NIOPosix", "NIOCore"],
exclude: ["README.md"]),
.target(name: "NIOTestUtils",
dependencies: ["NIOPosix", "NIOCore", "NIOEmbedded", "NIOHTTP1", swiftAtomics]),
.executableTarget(name: "NIOCrashTester",
dependencies: ["NIOPosix", "NIOCore", "NIOEmbedded", "NIOHTTP1", "NIOWebSocket", "NIOFoundationCompat"]),
.executableTarget(name: "NIOAsyncAwaitDemo",
dependencies: ["NIOPosix", "NIOCore", "NIOHTTP1"]),
.testTarget(name: "NIOCoreTests",
dependencies: ["NIOCore", "NIOEmbedded", "NIOFoundationCompat"]),
.testTarget(name: "NIOBetaTests",
dependencies: ["_NIOBeta"]),
.testTarget(name: "NIOEmbeddedTests",
dependencies: ["NIOConcurrencyHelpers", "NIOCore", "NIOEmbedded"]),
.testTarget(name: "NIOPosixTests",
dependencies: ["NIOPosix", "NIOCore", "NIOFoundationCompat", "NIOTestUtils", "NIOConcurrencyHelpers", "NIOEmbedded"]),
.testTarget(name: "NIOConcurrencyHelpersTests",
dependencies: ["NIOConcurrencyHelpers", "NIOCore"]),
.testTarget(name: "NIODataStructuresTests",
dependencies: ["_NIODataStructures"]),
.testTarget(name: "NIOHTTP1Tests",
dependencies: ["NIOCore", "NIOEmbedded", "NIOPosix", "NIOHTTP1", "NIOFoundationCompat", "NIOTestUtils"]),
.testTarget(name: "NIOTLSTests",
dependencies: ["NIOCore", "NIOEmbedded", "NIOTLS", "NIOFoundationCompat"]),
.testTarget(name: "NIOWebSocketTests",
dependencies: ["NIOCore", "NIOEmbedded", "NIOWebSocket"]),
.testTarget(name: "NIOTestUtilsTests",
dependencies: ["NIOTestUtils", "NIOCore", "NIOEmbedded", "NIOPosix"]),
.testTarget(name: "NIOFoundationCompatTests",
dependencies: ["NIOCore", "NIOFoundationCompat"]),
.testTarget(name: "NIOTests",
dependencies: ["NIO"]),
]
let package = Package(
name: "swift-nio",
products: [
.library(name: "NIOCore", targets: ["NIOCore"]),
.library(name: "NIO", targets: ["NIO"]),
.library(name: "NIOEmbedded", targets: ["NIOEmbedded"]),
.library(name: "NIOPosix", targets: ["NIOPosix"]),
.library(name: "_NIOConcurrency", targets: ["_NIOConcurrency"]),
.library(name: "_NIOBeta", targets: ["_NIOBeta"]),
.library(name: "NIOTLS", targets: ["NIOTLS"]),
.library(name: "NIOHTTP1", targets: ["NIOHTTP1"]),
.library(name: "NIOConcurrencyHelpers", targets: ["NIOConcurrencyHelpers"]),
.library(name: "NIOFoundationCompat", targets: ["NIOFoundationCompat"]),
.library(name: "NIOWebSocket", targets: ["NIOWebSocket"]),
.library(name: "NIOTestUtils", targets: ["NIOTestUtils"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-atomics.git", from: "1.0.2"),
.package(url: "https://github.com/apple/swift-collections.git", from: "1.0.2"),
],
targets: targets
)

View File

@ -11,7 +11,7 @@ It's like [Netty](https://netty.io), but written for Swift.
The SwiftNIO project is split across multiple repositories:
Repository | NIO 2 (Swift 5.4+)
Repository | NIO 2 (Swift 5.5+)
--- | ---
[https://github.com/apple/swift-nio][repo-nio] <br> SwiftNIO core | `from: "2.0.0"`
[https://github.com/apple/swift-nio-ssl][repo-nio-ssl] <br> TLS (SSL) support | `from: "2.0.0"`
@ -67,9 +67,17 @@ Redis | ✅ | ❌ | [mordil/swift-redi-stack](https://gitlab.com/Mordil/swift-re
### Supported Versions
### SwiftNIO 2
This is the current version of SwiftNIO and will be supported for the foreseeable future.
The latest released SwiftNIO 2 version supports Swift 5.4+. NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+.
The most recent versions of SwiftNIO support Swift 5.5 and newer. The minimum Swift version supported by SwiftNIO releases are detailed below:
SwiftNIO | Minimum Swift Version
--------------------|----------------------
`2.0.0 ..< 2.30.0` | 5.0
`2.30.0 ..< 2.40.0` | 5.2
`2.40.0 ..< 2.43.0` | 5.4
`2.43.0 ...` | 5.5
### SwiftNIO 1
SwiftNIO 1 is considered end of life - it is strongly recommended that you move to a newer version. The Core NIO team does not actively work on this version. No new features will be added to this version but PRs which fix bugs or security vulnerabilities will be accepted until the end of May 2022.
@ -243,7 +251,7 @@ dependencies: [
and then adding the appropriate SwiftNIO module(s) to your target dependencies.
The syntax for adding target dependencies differs slightly between Swift
versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and
versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and
`NIOHTTP1` modules, specify the following dependencies:
#### Swift 5.4 and newer (`swift-tools-version:5.4`)
@ -305,9 +313,9 @@ First make sure you have [Docker](https://www.docker.com/community-edition) inst
Will create a base image, compile SwiftNIO, and run a sample `NIOHTTP1Server` on
`localhost:8888`. Test it by `curl http://localhost:8888`
- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2004.54.yaml run test`
- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2204.57.yaml run test`
Will create a base image using Ubuntu 20.04 and swift 5.4, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory.
Will create a base image using Ubuntu 22.04 and Swift 5.7, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory.
## Developing SwiftNIO
@ -329,7 +337,7 @@ have a few prerequisites installed on your system.
### Linux
- Swift 5.2, 5.3, or 5.4 from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version.
- Swift 5.5 or newer from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version.
- netcat (for integration tests only)
- lsof (for integration tests only)
- shasum (for integration tests only)

View File

@ -4,19 +4,21 @@ This document specifies the security process for the SwiftNIO project.
## Versions
The SwiftNIO core team will address security vulnerabilities in all SwiftNIO 2.x
versions. Since support for some Swift versions was dropped during the lifetime of
The SwiftNIO core team will address security vulnerabilities in all SwiftNIO 2.x
versions. Since support for some Swift versions was dropped during the lifetime of
SwiftNIO 2, patch releases will be created for the last supported SwiftNIO versions
that supported older Swift versions.
If a hypothetical security vulnerability was introduced in 2.10.0, then SwiftNIO core
that supported older Swift versions.
If a hypothetical security vulnerability was introduced in 2.10.0, then SwiftNIO core
team would create the following patch releases:
* NIO 2.29. + plus next patch release to address the issue for projects that support
Swift 5.0 and 5.1
* NIO 2.39. + plus next patch release to address the issue for projects that support
* NIO 2.39. + plus next patch release to address the issue for projects that support
Swift 5.2 and 5.3
* mainline + plus next patch release to address the issue for projects that support
* NIO 2.42. + plus next patch release to address the issue for projects that support
Swift 5.4 and later
* mainline + plus next patch release to address the issue for projects that support
Swift 5.5 and later
SwiftNIO 1.x is considered end of life and will not receive any security patches.

View File

@ -40,14 +40,14 @@ internal struct Base64 {
// nearest multiple of four.
let base64StringLength = ((bytes.count + 2) / 3) * 4
let alphabet = Base64.encodeBase64
return String(customUnsafeUninitializedCapacity: base64StringLength) { backingStorage in
var input = bytes.makeIterator()
var offset = 0
while let firstByte = input.next() {
let secondByte = input.next()
let thirdByte = input.next()
backingStorage[offset] = Base64.encode(alphabet: alphabet, firstByte: firstByte)
backingStorage[offset + 1] = Base64.encode(alphabet: alphabet, firstByte: firstByte, secondByte: secondByte)
backingStorage[offset + 2] = Base64.encode(alphabet: alphabet, secondByte: secondByte, thirdByte: thirdByte)
@ -57,9 +57,9 @@ internal struct Base64 {
return offset
}
}
// MARK: Internal
// The base64 unicode table.
@usableFromInline
static let encodeBase64: [UInt8] = [
@ -80,7 +80,7 @@ internal struct Base64 {
UInt8(ascii: "4"), UInt8(ascii: "5"), UInt8(ascii: "6"), UInt8(ascii: "7"),
UInt8(ascii: "8"), UInt8(ascii: "9"), UInt8(ascii: "+"), UInt8(ascii: "/"),
]
static let encodePaddingCharacter: UInt8 = UInt8(ascii: "=")
@usableFromInline
@ -150,7 +150,7 @@ extension String {
// enhancement on Apple platforms.
#if (compiler(>=5.3) && !(os(macOS) || os(iOS) || os(tvOS) || os(watchOS))) || compiler(>=5.4)
extension String {
@inlinable
init(customUnsafeUninitializedCapacity capacity: Int,
initializingUTF8With initializer: (_ buffer: UnsafeMutableBufferPointer<UInt8>) throws -> Int) rethrows {

View File

@ -37,14 +37,11 @@ import XCTest
@testable import NIOTests
@testable import NIOWebSocketTests
// This protocol is necessary so we can call the 'run' method (on an existential of this protocol)
// without the compiler noticing that we're calling a deprecated function.
// This hack exists so we can deprecate individual tests which test deprecated functionality without
// getting a compiler warning...
protocol LinuxMainRunner { func run() }
class LinuxMainRunnerImpl: LinuxMainRunner {
@available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings")
@main
class LinuxMainRunner {
@available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings")
func run() {
static func main() {
XCTMain([
testCase(AcceptBackoffHandlerTest.allTests),
testCase(AdaptiveRecvByteBufferAllocatorTest.allTests),
@ -146,7 +143,6 @@ class LinuxMainRunnerImpl: LinuxMainRunner {
])
}
}
(LinuxMainRunnerImpl() as LinuxMainRunner).run()
#endif
#else
#error("on Swift 5.5 and newer, --enable-test-discovery is required")

View File

@ -1,4 +1,4 @@
ARG swift_version=5.4
ARG swift_version=5.7
ARG ubuntu_version=bionic
ARG base_image=swift:$swift_version-$ubuntu_version
FROM $base_image
@ -22,10 +22,3 @@ RUN apt-get update && apt-get install -y ruby ruby-dev libsqlite3-dev build-esse
# tools
RUN mkdir -p $HOME/.tools
RUN echo 'export PATH="$HOME/.tools:$PATH"' >> $HOME/.profile
# swiftformat (until part of the toolchain)
ARG swiftformat_version=0.40.12
RUN git clone --branch $swiftformat_version --depth 1 https://github.com/nicklockwood/SwiftFormat $HOME/.tools/swift-format
RUN cd $HOME/.tools/swift-format && swift build -c release
RUN ln -s $HOME/.tools/swift-format/.build/release/swiftformat $HOME/.tools/swiftformat

View File

@ -3,20 +3,20 @@ version: "3"
services:
runtime-setup:
image: swift-nio:20.04-5.7
image: swift-nio:22.04-5.7
build:
args:
ubuntu_version: "jammy"
swift_version: "5.7"
unit-tests:
image: swift-nio:20.04-5.7
image: swift-nio:22.04-5.7
integration-tests:
image: swift-nio:20.04-5.7
image: swift-nio:22.04-5.7
test:
image: swift-nio:20.04-5.7
image: swift-nio:22.04-5.7
environment:
- MAX_ALLOCS_ALLOWED_1000_addHandlers=47050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=40050
@ -64,13 +64,13 @@ services:
# - SANITIZER_ARG=--sanitize=thread # TSan broken still
performance-test:
image: swift-nio:20.04-5.7
image: swift-nio:22.04-5.7
shell:
image: swift-nio:20.04-5.7
image: swift-nio:22.04-5.7
echo:
image: swift-nio:20.04-5.7
image: swift-nio:22.04-5.7
http:
image: swift-nio:20.04-5.7
image: swift-nio:22.04-5.7

View File

@ -148,14 +148,11 @@ def createLinuxMain(testsDirectory, allTestSubDirectories, files)
file.write ' @testable import ' + testSubDirectory + "\n"
end
file.write "\n"
file.write "// This protocol is necessary so we can call the 'run' method (on an existential of this protocol)\n"
file.write "// without the compiler noticing that we're calling a deprecated function.\n"
file.write "// This hack exists so we can deprecate individual tests which test deprecated functionality without\n"
file.write "// getting a compiler warning...\n"
file.write "protocol LinuxMainRunner { func run() }\n"
file.write "class LinuxMainRunnerImpl: LinuxMainRunner {\n"
file.write '@available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings")' + "\n"
file.write "@main\n"
file.write "class LinuxMainRunner {\n"
file.write ' @available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings")' + "\n"
file.write " func run() {\n"
file.write " static func main() {\n"
file.write " XCTMain([\n"
testCases = []
@ -171,7 +168,6 @@ def createLinuxMain(testsDirectory, allTestSubDirectories, files)
file.write " ])\n"
file.write " }\n"
file.write "}\n"
file.write "(LinuxMainRunnerImpl() as LinuxMainRunner).run()\n"
file.write "#endif\n"
file.write "#else\n"
file.write "#error(\"on Swift 5.5 and newer, --enable-test-discovery is required\")\n"