diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml new file mode 100644 index 0000000..1e39378 --- /dev/null +++ b/.gitea/workflows/test.yml @@ -0,0 +1,28 @@ +name: Tests + +on: + push: + branches: [main] + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + container: + # Pinned rather than tracking latest: a toolchain bump should be a commit, + # not a surprise on an unrelated push. + image: swift:6.2 + steps: + - uses: actions/checkout@v4 + + - name: Toolchain + run: swift --version + + # This only covers IPodSyncKit — the format logic, which is where every + # test lives. The Contacts and EventKit readers are compiled out on Linux + # and can only be exercised on a Mac. + - name: Build + run: swift build --build-tests + + - name: Test + run: swift test diff --git a/Package.swift b/Package.swift index 0c346fb..55a81ac 100644 --- a/Package.swift +++ b/Package.swift @@ -1,18 +1,29 @@ // swift-tools-version: 6.2 import PackageDescription +// The kit and its tests are Foundation-only and build anywhere. The app target +// is SwiftUI driving Contacts and EventKit, none of which exist on Linux, so it +// is added only on macOS — otherwise `swift test` in a Linux container would +// fail trying to build an executable it can never link. +var targets: [Target] = [ + .target(name: "IPodSyncKit"), + .testTarget( + name: "IPodSyncKitTests", + dependencies: ["IPodSyncKit"] + ), +] + +#if os(macOS) +targets.append( + .executableTarget( + name: "iPodSyncApp", + dependencies: ["IPodSyncKit"] + ) +) +#endif + let package = Package( name: "iPodContactsAndCalendarSync", platforms: [.macOS(.v14)], - targets: [ - .target(name: "IPodSyncKit"), - .executableTarget( - name: "iPodSyncApp", - dependencies: ["IPodSyncKit"] - ), - .testTarget( - name: "IPodSyncKitTests", - dependencies: ["IPodSyncKit"] - ), - ] + targets: targets ) diff --git a/README.md b/README.md index 4db7479..7a82ebe 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,18 @@ swift test # run the test suite `Package.swift` opens directly in Xcode if you'd rather work there. +### CI + +`.gitea/workflows/test.yml` runs `swift test` in a `swift:6.2` container on +every push and pull request. + +It covers `IPodSyncKit` only. The Contacts and EventKit readers are compiled +out on Linux via `#if canImport(…)`, and the SwiftUI app target is excluded +from `Package.swift` on non-Apple platforms — neither can exist in a Linux +container. No test coverage is lost by this: every test is about file format, +and none of them touch the readers. What CI cannot tell you is whether reading +from the real Contacts and Calendars databases still works; that needs a Mac. + The bundle is **ad-hoc signed**, which is not the same as signed for distribution. Ad-hoc signing is required — Contacts and Calendars identify an app by its code signature, and an unsigned bundle gets denied or re-prompts diff --git a/Sources/IPodSyncKit/CalendarReader.swift b/Sources/IPodSyncKit/CalendarReader.swift index 2266055..f3001ae 100644 --- a/Sources/IPodSyncKit/CalendarReader.swift +++ b/Sources/IPodSyncKit/CalendarReader.swift @@ -1,3 +1,6 @@ +// EventKit has no Linux equivalent. See the note in ContactsReader.swift. +#if canImport(EventKit) + import EventKit import Foundation @@ -125,3 +128,5 @@ public actor CalendarReader { return "\(String(safe).prefix(64))-\(stamp)@ipod-sync" } } + +#endif diff --git a/Sources/IPodSyncKit/ContactsReader.swift b/Sources/IPodSyncKit/ContactsReader.swift index ecf3826..cef173a 100644 --- a/Sources/IPodSyncKit/ContactsReader.swift +++ b/Sources/IPodSyncKit/ContactsReader.swift @@ -1,3 +1,8 @@ +// Contacts has no Linux equivalent. Guarding the whole file lets the kit +// build in a Linux container so the format logic can be tested there; +// nothing in this file is exercised by the test suite. +#if canImport(Contacts) + import Contacts import Foundation @@ -131,3 +136,5 @@ public actor ContactsReader { } } } + +#endif