Chore: Add API breakage gate, platform CI matrix and changelog (Phase 0) - #440
Merged
Merged
Conversation
Runs swift package diagnose-api-breaking-changes against the newest semver tag on every pull request and push to main, publishes the report in the job summary, and fails on any break that is not listed in .github/api-breakage-allowlist.txt. A manual run can pass a different baseline. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…latform Package.swift declares Swift 5.10 and macOS, iOS, tvOS, watchOS and visionOS, but CI only ran one unpinned Linux toolchain. Linux now builds and tests in swift:5.10, 6.0 and 6.3 containers; macOS and the iOS Simulator run the tests; tvOS, watchOS and visionOS are built with xcodebuild. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
testModerationsIterable used Regex and String.replacing(_:with:), which require iOS 16 while the package declares iOS 13, so the test bundle could not be built for iOS. Foundation's replacingOccurrences(of:with:options:) does the same job on every platform. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
CHANGELOG.md follows Keep a Changelog and is seeded from the 0.4.9, 0.5.0 and 0.5.1 release notes, including the public API changes 0.5.1 shipped. CONTRIBUTING.md gains an API stability section: additive-only public API, how the breakage gate works, how to accept an unavoidable break, and how regenerated Components.Schemas types are treated. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…lator by UDID Package.resolved pins swift-openapi-runtime 1.12.0, whose manifest needs Swift tools 6.1, so the 5.10 and 6.0 lanes failed before compiling anything. A consumer of this library never uses our Package.resolved, so those lanes now delete it and resolve fresh, which is what such a consumer gets. The iOS Simulator lane picked a device name that only exists in an older runtime; it now takes an iPhone from the newest installed iOS runtime and addresses it by UDID. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
swift-corelibs-foundation gained data(for:delegate:) in Swift 6.0, so on Linux toolchains before that URLSession did not satisfy URLSessionProtocol and the package failed to compile, contradicting the declared Swift 5.10 minimum. A Linux-only, pre-Swift-6 extension now bridges dataTask(with:completionHandler:) to async/await, including cancellation. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… shim The call was ambiguous between Foundation's method and the URLSessionProtocol overload that returns URLSessionDataTaskProtocol. Coerce to URLSessionDataTask, as URLSessionProtocol.swift already does. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Swift Testing ships with Swift 6 toolchains. The package declares Swift 5.10, and swift test on that toolchain failed with 'no such module Testing'. The eight Swift Testing files are now wrapped in #if canImport(Testing); the XCTest suite still runs on every toolchain. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adding methods to OpenAIProtocol, OpenAIAsync or OpenAICombine is reported as a break by the API gate because external conformers stop compiling. New endpoint groups follow the Responses API pattern instead: one namespace property on OpenAIProtocol and the methods on the endpoint protocol in all three flavours. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
swift package diagnose-api-breaking-changes matches allowlist entries literally and matches none of them when the file contains a comment or blank line. The file now starts empty and the format is documented in CONTRIBUTING.md and in the workflow summary. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
nezhyborets
approved these changes
Sep 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Phase 0 of the maintenance plan: a safety net that makes "no breaking changes" and "builds on every declared platform" checkable in CI, plus the paperwork that goes with it.
API Breakageworkflow (.github/workflows/api-breakage.yml): runsswift package diagnose-api-breaking-changesagainst the latest semver tag on every pull request and push tomain, writes the report to the job summary, and fails on every break not listed in.github/api-breakage-allowlist.txt. Manual runs can pass a different baseline.Swift Buildworkflow now covers whatPackage.swiftdeclares: Linux inswift:5.10,swift:6.0andswift:6.3containers (build + test), macOS and iOS Simulator (test), tvOS, watchOS and visionOS (build) onmacos-latest.CHANGELOG.mdin Keep a Changelog format, seeded from the 0.4.9, 0.5.0 and 0.5.1 release notes, with the 0.5.1 API changes spelled out.CONTRIBUTING.md: an API stability section describing the additive-only policy, how the gate works, how to accept an unavoidable break, and how regeneratedComponents.Schemastypes are treated.testModerationsIterableusedRegex, which needs iOS 16.ModelResponseEventsStreamInterpreter(optional interpolated into a debug log line).URLSessionAPIs in Swift 6, soURLSessiondid not satisfy ourURLSessionProtocolthere and the package did not compile on the toolchain it declares as its minimum. A Linux-only, pre-Swift-6 extension bridgesdataTask(with:completionHandler:)to async/await, with cancellation.Why
swift package diagnose-api-breaking-changes 0.5.0reports 77 public API breaks shipped in 0.5.1: 71 inside the generatedComponents.Schemas(for example transcription timestamps changed fromFloattoDouble,ImageGenTool.SizePayloadlost its cases,responseIdwas removed from the response audio events) and 6 in hand-written types (twoChatCompletionMessageParaminitializers andChatResult.Choice.Message.Annotationremoved). Nothing in CI could have caught them, and CI only ever ran one unpinned Linux toolchain even though the package declares Swift 5.10 and five Apple platforms.Affected Areas
CI configuration and documentation, one debug-only log line, one test using
replacingOccurrences(of:with:options:)instead ofRegex, and one new internal Linux-only file (URLSession+AsyncCompatibility.swift) that compiles only withcompiler(<6.0). No public API changes; the new gate confirms this against 0.5.1.More Info
Components.Schemasstays public. The policy in CONTRIBUTING.md asks for shims on regeneration instead of silently accepting breaks; moving generated types out of the public surface is a 1.0 topic.swift-openapi-runtime1.10.0 requires Swift 6.0 and 1.11.0+ requires Swift 6.1. OurPackage.resolvedpins 1.12.0, which a Swift 5.10 or 6.0 toolchain refuses outright, so the Linux 5.10 and 6.0 lanes delete the pin and resolve the way a consumer of this library does (they get 1.9.0 and 1.10.0). Consumers never use ourPackage.resolved, so this is the realistic check.🤖 Generated with Claude Code