Skip to content

Commit

Permalink
Upgrade everything to Swift 5.9 and Sendable correctness, use SwiftHT…
Browse files Browse the repository at this point in the history
…TPTypes (#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
  • Loading branch information
gwynne committed Dec 1, 2023
1 parent 78268ba commit 25de572
Show file tree
Hide file tree
Showing 25 changed files with 385 additions and 907 deletions.
23 changes: 23 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
version: 2
enable-beta-ecosystems: true
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
allow:
- dependency-type: all
groups:
dependencies:
patterns:
- "*"
- package-ecosystem: "swift"
directory: "/"
schedule:
interval: "weekly"
allow:
- dependency-type: all
groups:
all-dependencies:
patterns:
- "*"
162 changes: 115 additions & 47 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,66 +1,134 @@
name: test
name: Tests
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
push:
branches:
- main
pull_request:
pull_request: { types: [opened, reopened, synchronize, ready_for_review] }
push: { branches: [ main ] }
env:
LOG_LEVEL: info

jobs:
appleos:
if: ${{ !(github.event.pull_request.draft || false) }}
strategy:
fail-fast: false
matrix:
xcode:
- latest
- latest-stable
destination:
- 'platform=macOS,arch=x86_64'
#- 'platform=macOS,arch=arm64'
- 'platform=iOS Simulator,OS=latest,name=iPhone 11 Pro'
- 'platform=tvOS Simulator,OS=latest,name=Apple TV 4K'
- 'platform=watchOS Simulator,OS=latest,name=Apple Watch Series 6 - 44mm'
runs-on: macos-11.0
#- latest-stable
platform:
- 'macOS'
- 'iOS Simulator'
- 'tvOS Simulator'
- 'watchOS Simulator'
include:
- platform: 'macOS'
destination: 'arch=x86_64'
- platform: 'iOS Simulator'
destination: 'OS=latest,name=iPhone 15 Pro'
- platform: 'tvOS Simulator'
destination: 'OS=latest,name=Apple TV 4K (3rd generation)'
- platform: 'watchOS Simulator'
destination: 'OS=latest,name=Apple Watch Series 9 (45mm)'
name: ${{ matrix.platform }} Tests
runs-on: macos-13
steps:
- name: Select latest available Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ${{ matrix.xcode }}
- name: Checkout
uses: actions/checkout@v2
- name: Run tests for ${{ matrix.destination }}
run: xcodebuild test -scheme StructuredAPIClient-Package -enableThreadSanitizer YES -destination '${{ matrix.destination }}'
- name: Select latest available Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ${{ matrix.xcode }}
- name: Install xcbeautify
run: brew install xcbeautify
- name: Checkout code
uses: actions/checkout@v4
- name: Run tests
env:
DESTINATION: ${{ format('platform={0},{1}', matrix.platform, matrix.destination) }}
run: |
set -o pipefail && \
xcodebuild test -scheme StructuredAPIClient-Package \
-enableThreadSanitizer YES \
-enableCodeCoverage YES \
-disablePackageRepositoryCache \
-resultBundlePath "${GITHUB_WORKSPACE}/results.resultBundle" \
-destination "${DESTINATION}" |
xcbeautify --is-ci --quiet --renderer github-actions
- name: Upload coverage data
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
swift: true
verbose: true
xcode: true
xcode_archive_path: ${{ github.workspace }}/results.resultBundle

linux:
runs-on: ubuntu-latest
if: ${{ !(github.event.pull_request.draft || false) }}
strategy:
fail-fast: false
matrix:
ver:
- swift:5.3
- swift:5.4
- swift:5.5
- swiftlang/swift:nightly-main
os:
- bionic
- focal
- amazonlinux2
swift-image:
- swift:5.9-jammy
- swiftlang/swift:nightly-5.10-jammy
- swiftlang/swift:nightly-main-jammy
name: Linux ${{ matrix.swift-image }} Tests
runs-on: ubuntu-latest
container: ${{ matrix.swift-image }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install xcbeautify
run: |
DEBIAN_FRONTEND=noninteractive apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y curl
curl -fsSLO 'https://github.com/tuist/xcbeautify/releases/download/1.0.1/xcbeautify-1.0.1-x86_64-unknown-linux-gnu.tar.xz'
tar -x -J -f xcbeautify-1.0.1-x86_64-unknown-linux-gnu.tar.xz
- name: Run tests
shell: bash
run: |
set -o pipefail && \
swift test --sanitize=thread --enable-code-coverage |
./xcbeautify --is-ci --quiet --renderer github-actions
- name: Upload coverage data
uses: vapor/[email protected]
with:
cc_token: ${{ secrets.CODECOV_TOKEN }}
cc_verbose: true

codeql:
if: ${{ !(github.event.pull_request.draft || false) }}
name: CodeQL Analysis
runs-on: ubuntu-latest
container:
image: ${{ matrix.ver }}-${{ matrix.os }}
image: swift:5.9-jammy
permissions: { actions: write, contents: read, security-events: write }
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Run tests for ${{ matrix.runner }}
run: swift test --enable-test-discovery --sanitize=thread
- name: Checkout code
uses: actions/checkout@v4
- name: Mark repo safe
run: |
git config --global --add safe.directory "${GITHUB_WORKSPACE}"
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with: { languages: swift }
- name: Perform build
run: swift build
- name: Run CodeQL analyze
uses: github/codeql-action/analyze@v2

windows:
runs-on: windows-latest
dependency-graph:
if: ${{ github.event_name == 'push' }}
runs-on: ubuntu-latest
container: swift:jammy
permissions:
contents: write
steps:
- name: Install Swift toolchain
uses: compnerd/gha-setup-swift@main
with:
branch: swift-5.5-release
tag: 5.5-RELEASE
- name: Checkout
uses: actions/checkout@v2
- name: Run tests
run: swift test
- name: Check out code
uses: actions/checkout@v4
- name: Set up dependencies
run: |
git config --global --add safe.directory "${GITHUB_WORKSPACE}"
apt-get update && apt-get install -y curl
- name: Submit dependency graph
uses: vapor-community/[email protected]
30 changes: 25 additions & 5 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.3
// swift-tools-version:5.9
//===----------------------------------------------------------------------===//
//
// This source file is part of the StructuredAPIClient open source project
Expand All @@ -14,6 +14,14 @@

import PackageDescription

let swiftSettings: [SwiftSetting] = [
.enableUpcomingFeature("ForwardTrailingClosures"),
.enableUpcomingFeature("ExistentialAny"),
.enableUpcomingFeature("ConciseMagicFile"),
.enableUpcomingFeature("DisableOutwardActorInference"),
.enableExperimentalFeature("StrictConcurrency=complete"),
]

let package = Package(
name: "StructuredAPIClient",
products: [
Expand All @@ -22,20 +30,32 @@ let package = Package(
],
dependencies: [
// Swift logging API
.package(url: "https://github.com/apple/swift-log.git", .upToNextMajor(from: "1.4.0")),
.package(url: "https://github.com/apple/swift-log.git", from: "1.5.0"),
.package(url: "https://github.com/apple/swift-http-types.git", from: "1.0.0"),
],
targets: [
.target(
name: "StructuredAPIClient",
dependencies: [.product(name: "Logging", package: "swift-log")]),
dependencies: [
.product(name: "Logging", package: "swift-log"),
.product(name: "HTTPTypes", package: "swift-http-types"),
],
swiftSettings: swiftSettings
),
.target(
name: "StructuredAPIClientTestSupport",
dependencies: [.target(name: "StructuredAPIClient")]),
dependencies: [
.target(name: "StructuredAPIClient"),
],
swiftSettings: swiftSettings
),
.testTarget(
name: "StructuredAPIClientTests",
dependencies: [
.target(name: "StructuredAPIClient"),
.target(name: "StructuredAPIClientTestSupport"),
]),
],
swiftSettings: swiftSettings
),
]
)
32 changes: 22 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
# StructuredAPIClient
# <div align="center">StructuredAPIClient</div>

<p align="center">

<a href="LICENSE">
<img src="https://img.shields.io/badge/license-MIT-brightgreen.svg" alt="MIT License">
<img src="https://img.shields.io/badge/license-MIT-skyblue?style=plastic&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB2aWV3Qm94PSIwIDAgMTI4IDEyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSJza3libHVlIiBkPSJNNzAuNTQsMTEuNWMtLjEtMy44Ny0xMi0zLjg3LTEyLDB2MTBjLTUuMjcuMi0yMC4zNCw3Ljg3LTI0LjQ0LDhoLTE4LjRjLTcuMSwwLTguMywxMy45NSwzLjUsMTIsMCwwLTE0Ljk2LDMzLjItMTYuNywzNy41NC04LjE1LDE4LjQ2LDUzLjkzLDE3LjMsNDUuOC44LTIuNS01LjA3LTE2LjctMzguMzQtMTYuNy0zOC4zNCw1LjcsMCwxOC40LTcuODMsMjcuMTQtOHY3Ni43OGgtMjBjLTMuOSwwLTMuOSwxMiwwLDEyaDUyYzMuOSwwLDMuOS0xMiwwLTEyaC0yMHYtNzYuNzhjOC43LS4xLDIxLjE2LDgsMjcuMzYsOCwwLDAtMTQuNDMsMzIuODYtMTYuNywzOC4zNC03LjEsMTUuOTYsNTMuNTYsMTguMyw0NS44LDAtMi4yLTUuMy0xNi43LTM4LjM0LTE2LjctMzguMzQsMTIuNiwxLjIsMTEuNS0xMiwzLjUtMTIsMCwwLTIyLjgtLjItMTguNCwwLDAsMC0xOS03LjktMjQuNDQtOHptMzIuODYsNDQuNjYsMTAuNCwyNGMtMy45LDEuNzQtMTguNiwxLjItMjAuODQsMHptLTc3LjcsMCwxMC40LDI0Yy04LDMuMy0xNSwyLjktMjAuODQsMCwzLjcyLTcuODcsNi41Ny0xNi4yNSwxMC40NC0yNHoiLz48L3N2Zz4%3D" alt="MIT License">
</a>
<a href="https://swift.org">
<img src="https://img.shields.io/badge/swift-5.3-brightgreen.svg" alt="Swift 5.3">

<a href="https://github.com/stairtree/StructuredAPIClient/actions/workflows/test.yml">
<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">
</a>
<a href="https://github.com/stairtree/StructuredAPIClient/actions">
<img src="https://github.com/stairtree/StructuredAPIClient/workflows/test/badge.svg" alt="CI">

<a href="https://codecov.io/gh/stairtree/StructuredAPIClient">
<img src="https://img.shields.io/codecov/c/gh/stairtree/StructuredAPIClient?style=plastic&logo=codecov&label=codecov&token=MD69L97AOO">
</a>

<a href="https://swift.org">
<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">
</a>

</p>

A testable and composable network client.

### Supported Platforms
For more information, browse the API documentation (_coming soon_).

## Supported Platforms

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

* Ubuntu 16.04+
* Ubuntu 18.04+
* AmazonLinux2
* macOS 10.12+
* iOS 12+
Expand All @@ -28,10 +40,10 @@ To integrate the package:

```swift
dependencies: [
.package(url: "https://github.com/stairtree/StructuredAPIClient.git", from: "1.1.1")
.package(url: "https://github.com/stairtree/StructuredAPIClient.git", from: "2.0.0")
]
```

---

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.
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.
Loading

0 comments on commit 25de572

Please sign in to comment.