Skip to content

Commit cce41a9

Browse files
authoredNov 7, 2022
Drop support for Swift 5.4 (#314)
* Use MUCH faster bytes->hex conversion in normalizeSQLConstraint() * Minor CI overhaul (use standard naming, globalize test env, add code coverage and API breakage, add Swift 5.7, etc.) * Drop support for Swift <5.5
1 parent 7d7e6e3 commit cce41a9

File tree

4 files changed

+112
-54
lines changed

4 files changed

+112
-54
lines changed
 

‎.github/workflows/test.yml

+100-47
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,102 @@
11
name: test
22
on:
3-
pull_request:
3+
pull_request: { branches: ['*'] }
44
push: { branches: [ main ] }
5-
defaults:
6-
run:
7-
shell: bash
5+
6+
env:
7+
LOG_LEVEL: debug
8+
SWIFT_DETERMINISTIC_HASHING: 1
9+
MYSQL_HOSTNAME: 'mysql-a'
10+
MYSQL_HOSTNAME_A: 'mysql-a'
11+
MYSQL_HOSTNAME_B: 'mysql-b'
12+
MYSQL_DATABASE: 'test_database'
13+
MYSQL_DATABASE_A: 'test_database'
14+
MYSQL_DATABASE_B: 'test_database'
15+
MYSQL_USERNAME: 'test_username'
16+
MYSQL_USERNAME_A: 'test_username'
17+
MYSQL_USERNAME_B: 'test_username'
18+
MYSQL_PASSWORD: 'test_password'
19+
MYSQL_PASSWORD_A: 'test_password'
20+
MYSQL_PASSWORD_B: 'test_password'
21+
822
jobs:
23+
24+
codecov:
25+
strategy:
26+
# For MySQL we have to run coverage baselines against multiple DB versions thanks to
27+
# the driver's behavior changing notably depending on the server.
28+
matrix: { dbimage: ['mysql:5.7', 'mysql:8.0', 'mariadb:10.7'] }
29+
runs-on: ubuntu-latest
30+
container: swift:5.7-jammy
31+
services:
32+
mysql-a:
33+
image: ${{ matrix.dbimage }}
34+
env:
35+
MYSQL_ALLOW_EMPTY_PASSWORD: "true"
36+
MYSQL_USER: test_username
37+
MYSQL_PASSWORD: test_password
38+
MYSQL_DATABASE: test_database
39+
steps:
40+
- name: Save MySQL version to env
41+
run: |
42+
echo MYSQL_VERSION='${{ matrix.dbimage }}' >> $GITHUB_ENV
43+
- name: Check out package
44+
uses: actions/checkout@v3
45+
- name: Run local tests with coverage
46+
run: swift test --enable-code-coverage
47+
- name: Submit coverage report to Codecov.io
48+
uses: vapor/swift-codecov-action@v0.2
49+
with:
50+
cc_flags: 'unittests'
51+
cc_env_vars: 'SWIFT_VERSION,SWIFT_PLATFORM,RUNNER_OS,RUNNER_ARCH,MYSQL_VERSION'
52+
cc_fail_ci_if_error: true
53+
cc_verbose: true
54+
cc_dry_run: false
55+
56+
# Check for API breakage versus main
57+
api-breakage:
58+
if: github.event_name == 'pull_request'
59+
runs-on: ubuntu-latest
60+
container: swift:5.7-jammy
61+
steps:
62+
- name: Check out package
63+
uses: actions/checkout@v3
64+
with:
65+
fetch-depth: 0
66+
# https://github.com/actions/checkout/issues/766
67+
- name: Mark the workspace as safe
68+
run: git config --global --add safe.directory ${GITHUB_WORKSPACE}
69+
- name: Check for API breaking changes
70+
run: swift package diagnose-api-breaking-changes origin/main
71+
72+
# Test integration with downstream Fluent driver
973
dependents:
74+
if: github.event_name == 'pull_request'
1075
runs-on: ubuntu-latest
1176
services:
1277
mysql-a:
1378
image: ${{ matrix.dbimage }}
1479
env:
1580
MYSQL_ALLOW_EMPTY_PASSWORD: "true"
16-
MYSQL_USER: vapor_username
17-
MYSQL_PASSWORD: vapor_password
18-
MYSQL_DATABASE: vapor_database
81+
MYSQL_USER: test_username
82+
MYSQL_PASSWORD: test_password
83+
MYSQL_DATABASE: test_database
1984
mysql-b:
2085
image: ${{ matrix.dbimage }}
2186
env:
2287
MYSQL_ALLOW_EMPTY_PASSWORD: "true"
23-
MYSQL_USER: vapor_username
24-
MYSQL_PASSWORD: vapor_password
25-
MYSQL_DATABASE: vapor_database
26-
container: swift:5.6-focal
88+
MYSQL_USER: test_username
89+
MYSQL_PASSWORD: test_password
90+
MYSQL_DATABASE: test_database
91+
container: swift:5.7-jammy
2792
strategy:
2893
fail-fast: false
2994
matrix:
95+
# Same minimum all-behavior set as the code coverage runs
3096
dbimage:
3197
- mysql:5.7
3298
- mysql:8.0
33-
- mariadb:10.3
3499
- mariadb:10.7
35-
- percona:8.0
36100
dependent:
37101
- fluent-mysql-driver
38102
steps:
@@ -49,15 +113,13 @@ jobs:
49113
- name: Use local package
50114
run: swift package edit mysql-kit --path ../package
51115
working-directory: dependent
52-
- name: Run tests with Thread Sanitizer
116+
- name: Run tests with Thread Sanitizer
53117
run: swift test --sanitize=thread
54118
working-directory: dependent
55-
env:
56-
MYSQL_HOSTNAME: mysql-a
57-
MYSQL_HOSTNAME_A: mysql-a
58-
MYSQL_HOSTNAME_B: mysql-b
59-
LOG_LEVEL: info
60-
linux:
119+
120+
# Run unit tests (Linux)
121+
linux-unit:
122+
if: github.event_name == 'pull_request'
61123
strategy:
62124
fail-fast: false
63125
matrix:
@@ -68,46 +130,39 @@ jobs:
68130
- mariadb:10.7
69131
- percona:8.0
70132
runner:
71-
- swift:5.5-focal
133+
- swift:5.5-bionic
72134
- swift:5.6-focal
73-
- swiftlang/swift:nightly-main-focal
135+
- swift:5.7-jammy
136+
- swiftlang/swift:nightly-main-jammy
74137
container: ${{ matrix.runner }}
75138
runs-on: ubuntu-latest
76139
services:
77-
mysql:
140+
mysql-a:
78141
image: ${{ matrix.dbimage }}
79142
env:
80143
MYSQL_ALLOW_EMPTY_PASSWORD: "true"
81-
MYSQL_USER: vapor_username
82-
MYSQL_PASSWORD: vapor_password
83-
MYSQL_DATABASE: vapor_database
144+
MYSQL_USER: test_username
145+
MYSQL_PASSWORD: test_password
146+
MYSQL_DATABASE: test_database
84147
steps:
85148
- name: Check out code
86149
uses: actions/checkout@v3
87150
- name: Run tests with Thread Sanitizer
88151
run: swift test --sanitize=thread
89-
env:
90-
MYSQL_HOSTNAME: mysql
91-
LOG_LEVEL: info
92-
macOS:
152+
153+
# Run unit tests (macOS). Don't bother with lots of variations, Linux will cover that.
154+
macos-unit:
155+
if: github.event_name == 'pull_request'
93156
strategy:
94157
fail-fast: false
95158
matrix:
96-
formula:
97-
- mysql
98-
- mysql@5.7
99-
- percona-server
100-
- mariadb
159+
formula:
160+
- mysql@8.0
101161
macos:
102162
- macos-11
103163
- macos-12
104164
xcode:
105-
- latest
106165
- latest-stable
107-
include:
108-
- username: root
109-
- formula: mariadb
110-
username: runner
111166
runs-on: ${{ matrix.macos }}
112167
steps:
113168
- name: Select latest available Xcode
@@ -119,20 +174,18 @@ jobs:
119174
- name: Start MySQL server
120175
run: brew services start ${{ matrix.formula }}
121176
- name: Wait for MySQL server to be ready
122-
run: until echo | mysql -u${{ matrix.username }}; do sleep 1; done
177+
run: until echo | mysql -uroot; do sleep 1; done
123178
timeout-minutes: 5
124179
- name: Set up MySQL databases and privileges
125180
run: |
126-
mysql -u${{ matrix.username }} --batch <<-'SQL'
127-
CREATE USER vapor_username@localhost IDENTIFIED BY 'vapor_password';
128-
CREATE DATABASE vapor_database;
129-
GRANT ALL PRIVILEGES ON vapor_database.* TO vapor_username@localhost;
181+
mysql -uroot --batch <<-'SQL'
182+
CREATE USER test_username@localhost IDENTIFIED BY 'test_password';
183+
CREATE DATABASE test_database;
184+
GRANT ALL PRIVILEGES ON test_database.* TO test_username@localhost;
130185
SQL
131186
- name: Check out code
132187
uses: actions/checkout@v3
133188
- name: Run tests with Thread Sanitizer
134189
run: swift test --sanitize=thread
135190
env:
136191
MYSQL_HOSTNAME: '127.0.0.1'
137-
MYSQL_DATABASE: vapor_database
138-
LOG_LEVEL: info

‎Package.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version:5.2
1+
// swift-tools-version:5.5
22
import PackageDescription
33

44
let package = Package(

‎Sources/MySQLKit/MySQLDialect.swift

+8-3
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,7 @@ public struct MySQLDialect: SQLDialect {
5858

5959
public func normalizeSQLConstraint(identifier: SQLExpression) -> SQLExpression {
6060
if let sqlIdentifier = identifier as? SQLIdentifier {
61-
let hashed = Insecure.SHA1.hash(data: Data(sqlIdentifier.string.utf8))
62-
let digest = hashed.reduce("") { $0 + String(format: "%02x", $1) }
63-
return SQLIdentifier(digest)
61+
return SQLIdentifier(Insecure.SHA1.hash(data: Data(sqlIdentifier.string.utf8)).hexRepresentation)
6462
} else {
6563
return identifier
6664
}
@@ -86,3 +84,10 @@ public struct MySQLDialect: SQLDialect {
8684
SQLRaw("FOR UPDATE")
8785
}
8886
}
87+
88+
fileprivate let hexTable: [UInt8] = [0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66]
89+
extension Sequence where Element == UInt8 {
90+
fileprivate var hexRepresentation: String {
91+
.init(decoding: self.flatMap { [hexTable[Int($0 >> 4)], hexTable[Int($0 & 0x7)]] }, as: Unicode.ASCII.self)
92+
}
93+
}

‎Tests/MySQLKitTests/MySQLKitTests.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ class MySQLKitTests: XCTestCase {
121121
let configuration = MySQLConfiguration(
122122
hostname: env("MYSQL_HOSTNAME") ?? "localhost",
123123
port: env("MYSQL_PORT").flatMap(Int.init) ?? 3306,
124-
username: env("MYSQL_USERNAME") ?? "vapor_username",
125-
password: env("MYSQL_PASSWORD") ?? "vapor_password",
126-
database: env("MYSQL_DATABASE") ?? "vapor_database",
124+
username: env("MYSQL_USERNAME") ?? "test_username",
125+
password: env("MYSQL_PASSWORD") ?? "test_password",
126+
database: env("MYSQL_DATABASE") ?? "test_database",
127127
tlsConfiguration: tls
128128
)
129129
self.pools = .init(

0 commit comments

Comments
 (0)