Introduce adyen to CI pipeline for public API changes detection
Motivation
A couple of weeks ago we realized we broke the public API. For better API stability and change control, the job should fail on any API modifications - whether breaking or non-breaking - to ensure all changes are intentional and properly reviewed.
With changes
Without changes
Description of Changes
Use https://www.adyen.com/knowledge-hub/swift-api-diff to detect API changes (only RevenueCat for now, RevenueCatUI coming next):
- Add baseline swift interface files
- Re-generate those on each PR. Compare them to the baselines
- Added Adyen to RC orb (3.3.0)
When detecting changes, there's a lane to run locally that re-generates the swift interface files to replace the baselines. This makes reviewing public changes easier for everybody
On my mind
- I think that we could only store a hash for each file instead of the whole file; but that's an optimization that we can easily add later.
- Once we move this to other repos, we might consider moving some lanes to the shared plugin to reuse them
📸 Snapshot Test
68 modified, 625 unchanged
| Name | Added | Removed | Modified | Renamed | Unchanged | Errored | Approval |
|---|---|---|---|---|---|---|---|
| RevenueCat com.revenuecat.PaywallsTester.mac-catalyst-scaled-to-match-ipad |
0 | 0 | 68 | 0 | 163 | 0 | ⏳ Needs approval |
| RevenueCat com.revenuecat.PaywallsTester.mac-catalyst-optimized-for-mac |
0 | 0 | 0 | 0 | 231 | 0 | N/A |
| RevenueCat com.revenuecat.PaywallsTester |
0 | 0 | 0 | 0 | 231 | 0 | N/A |
:flying_saucer: Powered by Emerge Tools
👁️🗨️ API DIFF
iOS Simulator
Status: ❌ Changes detected
⚠ We should not end up here - investigate how this happened
👀 2 public changes detected
| ❇️ | 2 Additions |
PaywallComponent
❇️ Added
public enum AnimationType: RevenueCat.PaywallComponentBase, Swift.String {
case easeIn
case easeInOut
case easeOut
case linear
public init(from decoder: any Swift.Decoder) throws
public init?(rawValue: Swift.String)
public typealias RawValue = Swift.String
public var rawValue: Swift.String { get }
}
public struct Animation: RevenueCat.PaywallComponentBase {
public func encode(to encoder: any Swift.Encoder) throws -> Swift.Void
public func hash(into hasher: inout Swift.Hasher) -> Swift.Void
public init(from decoder: any Swift.Decoder) throws
public let msDelay: Swift.Int { get }
public let msDuration: Swift.Int { get }
public let type: RevenueCat.PaywallComponent.AnimationType { get }
public static func ==(
a: RevenueCat.PaywallComponent.Animation,
b: RevenueCat.PaywallComponent.Animation
) -> Swift.Bool
public var hashValue: Swift.Int { get }
}
iOS
Status: ❌ Changes detected
⚠ We should not end up here - investigate how this happened
👀 2 public changes detected
| ❇️ | 2 Additions |
PaywallComponent
❇️ Added
public enum AnimationType: RevenueCat.PaywallComponentBase, Swift.String {
case easeIn
case easeInOut
case easeOut
case linear
public init(from decoder: any Swift.Decoder) throws
public init?(rawValue: Swift.String)
public typealias RawValue = Swift.String
public var rawValue: Swift.String { get }
}
public struct Animation: RevenueCat.PaywallComponentBase {
public func encode(to encoder: any Swift.Encoder) throws -> Swift.Void
public func hash(into hasher: inout Swift.Hasher) -> Swift.Void
public init(from decoder: any Swift.Decoder) throws
public let msDelay: Swift.Int { get }
public let msDuration: Swift.Int { get }
public let type: RevenueCat.PaywallComponent.AnimationType { get }
public static func ==(
a: RevenueCat.PaywallComponent.Animation,
b: RevenueCat.PaywallComponent.Animation
) -> Swift.Bool
public var hashValue: Swift.Int { get }
}
macOS
Status: ❌ Changes detected
⚠ We should not end up here - investigate how this happened
👀 2 public changes detected
| ❇️ | 2 Additions |
PaywallComponent
❇️ Added
public enum AnimationType: RevenueCat.PaywallComponentBase, Swift.String {
case easeIn
case easeInOut
case easeOut
case linear
public init(from decoder: any Swift.Decoder) throws
public init?(rawValue: Swift.String)
public typealias RawValue = Swift.String
public var rawValue: Swift.String { get }
}
public struct Animation: RevenueCat.PaywallComponentBase {
public func encode(to encoder: any Swift.Encoder) throws -> Swift.Void
public func hash(into hasher: inout Swift.Hasher) -> Swift.Void
public init(from decoder: any Swift.Decoder) throws
public let msDelay: Swift.Int { get }
public let msDuration: Swift.Int { get }
public let type: RevenueCat.PaywallComponent.AnimationType { get }
public static func ==(
a: RevenueCat.PaywallComponent.Animation,
b: RevenueCat.PaywallComponent.Animation
) -> Swift.Bool
public var hashValue: Swift.Int { get }
}
watchOS Simulator
Status: ❌ Changes detected
⚠ We should not end up here - investigate how this happened
👀 2 public changes detected
| ❇️ | 2 Additions |
PaywallComponent
❇️ Added
public enum AnimationType: RevenueCat.PaywallComponentBase, Swift.String {
case easeIn
case easeInOut
case easeOut
case linear
public init(from decoder: any Swift.Decoder) throws
public init?(rawValue: Swift.String)
public typealias RawValue = Swift.String
public var rawValue: Swift.String { get }
}
public struct Animation: RevenueCat.PaywallComponentBase {
public func encode(to encoder: any Swift.Encoder) throws -> Swift.Void
public func hash(into hasher: inout Swift.Hasher) -> Swift.Void
public init(from decoder: any Swift.Decoder) throws
public let msDelay: Swift.Int { get }
public let msDuration: Swift.Int { get }
public let type: RevenueCat.PaywallComponent.AnimationType { get }
public static func ==(
a: RevenueCat.PaywallComponent.Animation,
b: RevenueCat.PaywallComponent.Animation
) -> Swift.Bool
public var hashValue: Swift.Int { get }
}
watchOS
Status: ❌ Changes detected
⚠ We should not end up here - investigate how this happened
👀 2 public changes detected
| ❇️ | 2 Additions |
PaywallComponent
❇️ Added
public enum AnimationType: RevenueCat.PaywallComponentBase, Swift.String {
case easeIn
case easeInOut
case easeOut
case linear
public init(from decoder: any Swift.Decoder) throws
public init?(rawValue: Swift.String)
public typealias RawValue = Swift.String
public var rawValue: Swift.String { get }
}
public struct Animation: RevenueCat.PaywallComponentBase {
public func encode(to encoder: any Swift.Encoder) throws -> Swift.Void
public func hash(into hasher: inout Swift.Hasher) -> Swift.Void
public init(from decoder: any Swift.Decoder) throws
public let msDelay: Swift.Int { get }
public let msDuration: Swift.Int { get }
public let type: RevenueCat.PaywallComponent.AnimationType { get }
public static func ==(
a: RevenueCat.PaywallComponent.Animation,
b: RevenueCat.PaywallComponent.Animation
) -> Swift.Bool
public var hashValue: Swift.Int { get }
}
| 2 Warnings | |
|---|---|
| :warning: | Size check is being bypassed due to the presence of the label "danger-bypass-size-limit" |
| :warning: | Size increase: 1181.45 KB |
Generated by :no_entry_sign: Danger