Skip to content

Commit 25de572

Browse files
committed
Upgrade everything to Swift 5.9 and Sendable correctness, use SwiftHTTPTypes (#10)
* Upgrade everything to Swift 5.9 and Sendable correctness, also use SwiftHTTPTypes. What a zoo. * Remove BackgroundTaskHandler entirely. * Heavily improve CI. Revise README. Improve behavior of the URLSessionTransport vis a vis locking. * Create dependabot.yml * Add code coverage uploads, CodeQL scanning, and dependency graph submission
1 parent 78268ba commit 25de572

25 files changed

+385
-907
lines changed

.github/dependabot.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
version: 2
2+
enable-beta-ecosystems: true
3+
updates:
4+
- package-ecosystem: "github-actions"
5+
directory: "/"
6+
schedule:
7+
interval: "weekly"
8+
allow:
9+
- dependency-type: all
10+
groups:
11+
dependencies:
12+
patterns:
13+
- "*"
14+
- package-ecosystem: "swift"
15+
directory: "/"
16+
schedule:
17+
interval: "weekly"
18+
allow:
19+
- dependency-type: all
20+
groups:
21+
all-dependencies:
22+
patterns:
23+
- "*"

.github/workflows/test.yml

Lines changed: 115 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,134 @@
1-
name: test
1+
name: Tests
2+
concurrency:
3+
group: ${{ github.workflow }}-${{ github.ref }}
4+
cancel-in-progress: true
25
on:
3-
push:
4-
branches:
5-
- main
6-
pull_request:
6+
pull_request: { types: [opened, reopened, synchronize, ready_for_review] }
7+
push: { branches: [ main ] }
8+
env:
9+
LOG_LEVEL: info
710

811
jobs:
912
appleos:
13+
if: ${{ !(github.event.pull_request.draft || false) }}
1014
strategy:
1115
fail-fast: false
1216
matrix:
1317
xcode:
1418
- latest
15-
- latest-stable
16-
destination:
17-
- 'platform=macOS,arch=x86_64'
18-
#- 'platform=macOS,arch=arm64'
19-
- 'platform=iOS Simulator,OS=latest,name=iPhone 11 Pro'
20-
- 'platform=tvOS Simulator,OS=latest,name=Apple TV 4K'
21-
- 'platform=watchOS Simulator,OS=latest,name=Apple Watch Series 6 - 44mm'
22-
runs-on: macos-11.0
19+
#- latest-stable
20+
platform:
21+
- 'macOS'
22+
- 'iOS Simulator'
23+
- 'tvOS Simulator'
24+
- 'watchOS Simulator'
25+
include:
26+
- platform: 'macOS'
27+
destination: 'arch=x86_64'
28+
- platform: 'iOS Simulator'
29+
destination: 'OS=latest,name=iPhone 15 Pro'
30+
- platform: 'tvOS Simulator'
31+
destination: 'OS=latest,name=Apple TV 4K (3rd generation)'
32+
- platform: 'watchOS Simulator'
33+
destination: 'OS=latest,name=Apple Watch Series 9 (45mm)'
34+
name: ${{ matrix.platform }} Tests
35+
runs-on: macos-13
2336
steps:
24-
- name: Select latest available Xcode
25-
uses: maxim-lobanov/setup-xcode@v1
26-
with:
27-
xcode-version: ${{ matrix.xcode }}
28-
- name: Checkout
29-
uses: actions/checkout@v2
30-
- name: Run tests for ${{ matrix.destination }}
31-
run: xcodebuild test -scheme StructuredAPIClient-Package -enableThreadSanitizer YES -destination '${{ matrix.destination }}'
37+
- name: Select latest available Xcode
38+
uses: maxim-lobanov/setup-xcode@v1
39+
with:
40+
xcode-version: ${{ matrix.xcode }}
41+
- name: Install xcbeautify
42+
run: brew install xcbeautify
43+
- name: Checkout code
44+
uses: actions/checkout@v4
45+
- name: Run tests
46+
env:
47+
DESTINATION: ${{ format('platform={0},{1}', matrix.platform, matrix.destination) }}
48+
run: |
49+
set -o pipefail && \
50+
xcodebuild test -scheme StructuredAPIClient-Package \
51+
-enableThreadSanitizer YES \
52+
-enableCodeCoverage YES \
53+
-disablePackageRepositoryCache \
54+
-resultBundlePath "${GITHUB_WORKSPACE}/results.resultBundle" \
55+
-destination "${DESTINATION}" |
56+
xcbeautify --is-ci --quiet --renderer github-actions
57+
- name: Upload coverage data
58+
uses: codecov/codecov-action@v3
59+
with:
60+
token: ${{ secrets.CODECOV_TOKEN }}
61+
swift: true
62+
verbose: true
63+
xcode: true
64+
xcode_archive_path: ${{ github.workspace }}/results.resultBundle
3265

3366
linux:
34-
runs-on: ubuntu-latest
67+
if: ${{ !(github.event.pull_request.draft || false) }}
3568
strategy:
3669
fail-fast: false
3770
matrix:
38-
ver:
39-
- swift:5.3
40-
- swift:5.4
41-
- swift:5.5
42-
- swiftlang/swift:nightly-main
43-
os:
44-
- bionic
45-
- focal
46-
- amazonlinux2
71+
swift-image:
72+
- swift:5.9-jammy
73+
- swiftlang/swift:nightly-5.10-jammy
74+
- swiftlang/swift:nightly-main-jammy
75+
name: Linux ${{ matrix.swift-image }} Tests
76+
runs-on: ubuntu-latest
77+
container: ${{ matrix.swift-image }}
78+
steps:
79+
- name: Checkout code
80+
uses: actions/checkout@v4
81+
- name: Install xcbeautify
82+
run: |
83+
DEBIAN_FRONTEND=noninteractive apt-get update
84+
DEBIAN_FRONTEND=noninteractive apt-get install -y curl
85+
curl -fsSLO 'https://github.com/tuist/xcbeautify/releases/download/1.0.1/xcbeautify-1.0.1-x86_64-unknown-linux-gnu.tar.xz'
86+
tar -x -J -f xcbeautify-1.0.1-x86_64-unknown-linux-gnu.tar.xz
87+
- name: Run tests
88+
shell: bash
89+
run: |
90+
set -o pipefail && \
91+
swift test --sanitize=thread --enable-code-coverage |
92+
./xcbeautify --is-ci --quiet --renderer github-actions
93+
- name: Upload coverage data
94+
uses: vapor/[email protected]
95+
with:
96+
cc_token: ${{ secrets.CODECOV_TOKEN }}
97+
cc_verbose: true
98+
99+
codeql:
100+
if: ${{ !(github.event.pull_request.draft || false) }}
101+
name: CodeQL Analysis
102+
runs-on: ubuntu-latest
47103
container:
48-
image: ${{ matrix.ver }}-${{ matrix.os }}
104+
image: swift:5.9-jammy
105+
permissions: { actions: write, contents: read, security-events: write }
49106
steps:
50-
- name: Checkout
51-
uses: actions/checkout@v2
52-
- name: Run tests for ${{ matrix.runner }}
53-
run: swift test --enable-test-discovery --sanitize=thread
107+
- name: Checkout code
108+
uses: actions/checkout@v4
109+
- name: Mark repo safe
110+
run: |
111+
git config --global --add safe.directory "${GITHUB_WORKSPACE}"
112+
- name: Initialize CodeQL
113+
uses: github/codeql-action/init@v2
114+
with: { languages: swift }
115+
- name: Perform build
116+
run: swift build
117+
- name: Run CodeQL analyze
118+
uses: github/codeql-action/analyze@v2
54119

55-
windows:
56-
runs-on: windows-latest
120+
dependency-graph:
121+
if: ${{ github.event_name == 'push' }}
122+
runs-on: ubuntu-latest
123+
container: swift:jammy
124+
permissions:
125+
contents: write
57126
steps:
58-
- name: Install Swift toolchain
59-
uses: compnerd/gha-setup-swift@main
60-
with:
61-
branch: swift-5.5-release
62-
tag: 5.5-RELEASE
63-
- name: Checkout
64-
uses: actions/checkout@v2
65-
- name: Run tests
66-
run: swift test
127+
- name: Check out code
128+
uses: actions/checkout@v4
129+
- name: Set up dependencies
130+
run: |
131+
git config --global --add safe.directory "${GITHUB_WORKSPACE}"
132+
apt-get update && apt-get install -y curl
133+
- name: Submit dependency graph
134+
uses: vapor-community/[email protected]

Package.swift

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version:5.3
1+
// swift-tools-version:5.9
22
//===----------------------------------------------------------------------===//
33
//
44
// This source file is part of the StructuredAPIClient open source project
@@ -14,6 +14,14 @@
1414

1515
import PackageDescription
1616

17+
let swiftSettings: [SwiftSetting] = [
18+
.enableUpcomingFeature("ForwardTrailingClosures"),
19+
.enableUpcomingFeature("ExistentialAny"),
20+
.enableUpcomingFeature("ConciseMagicFile"),
21+
.enableUpcomingFeature("DisableOutwardActorInference"),
22+
.enableExperimentalFeature("StrictConcurrency=complete"),
23+
]
24+
1725
let package = Package(
1826
name: "StructuredAPIClient",
1927
products: [
@@ -22,20 +30,32 @@ let package = Package(
2230
],
2331
dependencies: [
2432
// Swift logging API
25-
.package(url: "https://github.com/apple/swift-log.git", .upToNextMajor(from: "1.4.0")),
33+
.package(url: "https://github.com/apple/swift-log.git", from: "1.5.0"),
34+
.package(url: "https://github.com/apple/swift-http-types.git", from: "1.0.0"),
2635
],
2736
targets: [
2837
.target(
2938
name: "StructuredAPIClient",
30-
dependencies: [.product(name: "Logging", package: "swift-log")]),
39+
dependencies: [
40+
.product(name: "Logging", package: "swift-log"),
41+
.product(name: "HTTPTypes", package: "swift-http-types"),
42+
],
43+
swiftSettings: swiftSettings
44+
),
3145
.target(
3246
name: "StructuredAPIClientTestSupport",
33-
dependencies: [.target(name: "StructuredAPIClient")]),
47+
dependencies: [
48+
.target(name: "StructuredAPIClient"),
49+
],
50+
swiftSettings: swiftSettings
51+
),
3452
.testTarget(
3553
name: "StructuredAPIClientTests",
3654
dependencies: [
3755
.target(name: "StructuredAPIClient"),
3856
.target(name: "StructuredAPIClientTestSupport"),
39-
]),
57+
],
58+
swiftSettings: swiftSettings
59+
),
4060
]
4161
)

README.md

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,34 @@
1-
# StructuredAPIClient
1+
# <div align="center">StructuredAPIClient</div>
2+
3+
<p align="center">
24

35
<a href="LICENSE">
4-
<img src="https://img.shields.io/badge/license-MIT-brightgreen.svg" alt="MIT License">
6+
<img src="https://img.shields.io/badge/license-MIT-skyblue?style=plastic&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB2aWV3Qm94PSIwIDAgMTI4IDEyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSJza3libHVlIiBkPSJNNzAuNTQsMTEuNWMtLjEtMy44Ny0xMi0zLjg3LTEyLDB2MTBjLTUuMjcuMi0yMC4zNCw3Ljg3LTI0LjQ0LDhoLTE4LjRjLTcuMSwwLTguMywxMy45NSwzLjUsMTIsMCwwLTE0Ljk2LDMzLjItMTYuNywzNy41NC04LjE1LDE4LjQ2LDUzLjkzLDE3LjMsNDUuOC44LTIuNS01LjA3LTE2LjctMzguMzQtMTYuNy0zOC4zNCw1LjcsMCwxOC40LTcuODMsMjcuMTQtOHY3Ni43OGgtMjBjLTMuOSwwLTMuOSwxMiwwLDEyaDUyYzMuOSwwLDMuOS0xMiwwLTEyaC0yMHYtNzYuNzhjOC43LS4xLDIxLjE2LDgsMjcuMzYsOCwwLDAtMTQuNDMsMzIuODYtMTYuNywzOC4zNC03LjEsMTUuOTYsNTMuNTYsMTguMyw0NS44LDAtMi4yLTUuMy0xNi43LTM4LjM0LTE2LjctMzguMzQsMTIuNiwxLjIsMTEuNS0xMiwzLjUtMTIsMCwwLTIyLjgtLjItMTguNCwwLDAsMC0xOS03LjktMjQuNDQtOHptMzIuODYsNDQuNjYsMTAuNCwyNGMtMy45LDEuNzQtMTguNiwxLjItMjAuODQsMHptLTc3LjcsMCwxMC40LDI0Yy04LDMuMy0xNSwyLjktMjAuODQsMCwzLjcyLTcuODcsNi41Ny0xNi4yNSwxMC40NC0yNHoiLz48L3N2Zz4%3D" alt="MIT License">
57
</a>
6-
<a href="https://swift.org">
7-
<img src="https://img.shields.io/badge/swift-5.3-brightgreen.svg" alt="Swift 5.3">
8+
9+
<a href="https://github.com/stairtree/StructuredAPIClient/actions/workflows/test.yml">
10+
<img src="https://img.shields.io/github/actions/workflow/status/stairtree/StructuredAPIClient/test.yml?event=push&style=plastic&logo=github&label=tests&logoColor=%23ccc" alt="CI">
811
</a>
9-
<a href="https://github.com/stairtree/StructuredAPIClient/actions">
10-
<img src="https://github.com/stairtree/StructuredAPIClient/workflows/test/badge.svg" alt="CI">
12+
13+
<a href="https://codecov.io/gh/stairtree/StructuredAPIClient">
14+
<img src="https://img.shields.io/codecov/c/gh/stairtree/StructuredAPIClient?style=plastic&logo=codecov&label=codecov&token=MD69L97AOO">
1115
</a>
1216

17+
<a href="https://swift.org">
18+
<img src="https://img.shields.io/badge/swift-5.9%2b-white?style=plastic&logoColor=%23f07158&labelColor=gray&color=%23f07158&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI%2BPHBhdGggZD0iTTYsMjRjLTMsMC02LTMtNi02di0xMmMwLTMsMy02LDYtNmgxMmMzLDAsNiwzLDYsNnYxMmMwLDMtMyw2LTYsNnoiIGZpbGw9IiNmMDcxNTgiLz48cGF0aCBkPSJNMTMuNiwzLjRjNC4yLDIuNCw2LjMsNy41LDUuMywxMS41LDEuOSwyLjgsMS42LDUuMiwxLjQsNC43LTEuMi0yLjMtMy4zLTEuNC00LjQtLjctMy45LDEuOC0xMC4yLjItMTMuNS01LDMsMi4yLDcuMiwzLjEsMTAuMywxLjItNC42LTMuNi04LjUtOS4yLTguNS05LjMsMi4zLDIuMSw2LDQuOCw3LjMsNS43LTIuOC0zLjEtNS4zLTYuNy01LjItNi43LDIuNywyLjcsNS43LDUuMiw4LjksNy4yLjQtLjgsMS40LTQuNS0xLjYtOC43eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg%3D%3D" alt="Swift 5.9">
19+
</a>
20+
21+
</p>
22+
1323
A testable and composable network client.
1424

15-
### Supported Platforms
25+
For more information, browse the API documentation (_coming soon_).
26+
27+
## Supported Platforms
1628

1729
StructuredAPIClient is tested on macOS, iOS, tvOS, Linux, and Windows, and is known to support the following operating system versions:
1830

19-
* Ubuntu 16.04+
31+
* Ubuntu 18.04+
2032
* AmazonLinux2
2133
* macOS 10.12+
2234
* iOS 12+
@@ -28,10 +40,10 @@ To integrate the package:
2840

2941
```swift
3042
dependencies: [
31-
.package(url: "https://github.com/stairtree/StructuredAPIClient.git", from: "1.1.1")
43+
.package(url: "https://github.com/stairtree/StructuredAPIClient.git", from: "2.0.0")
3244
]
3345
```
3446

3547
---
3648

37-
Inspired by blog posts by [Rob Napier](https://robnapier.net) and [Soroush Khanlou](http://khanlou.com), as well as the [Testing Tips & Tricks](https://developer.apple.com/videos/play/wwdc2018/417/) WWDC talk.
49+
Inspired by blog posts by [Rob Napier](https://robnapier.net) and [Soroush Khanlou](http://khanlou.com), as well as the [Testing Tips & Tricks](https://developer.apple.com/videos/play/wwdc2018/417/) WWDC talk. Version 2.0 revised for full Concurrency support by @gwynne.

0 commit comments

Comments
 (0)