Skip to content

Drop CocoaPods and Carthage support - #2278

Closed
maratal wants to merge 12 commits into
integration/v2from
dist/drop-cocoapods
Closed

maratal wants to merge 12 commits into
integration/v2from
dist/drop-cocoapods

Conversation

@maratal

@maratal maratal commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

Against integration/v2 directly, not stacked on the split PRs — this is a distribution decision rather than part of the package restructure, and touches a mostly disjoint set of files.

Why

2.x ships no pod. PDR-091b2 names only a Swift Package Manager product for this SDK, and a pod would have to be a second published artifact with its own trunk ownership, publish ordering and podspec to keep in step with Package.swift.

Existing pod consumers are not stranded: the Ably pod's last release stays on the 1.x line, which is maintenance-only with security and critical fixes for its support window. To go beyond that they move to Swift Package Manager.

Two consequences worth stating, because neither is obvious:

  • A pod consumer cannot declare the device side, since the declaration lives in AblyPubSubDevice, which is SPM-only. Their traffic keeps being classified by Ably's default rules for as long as they stay on 1.x. That is a real cost of this decision, not a detail.
  • ably-flutter must move to Flutter's Swift Package Manager support. Its iOS plugin depends on pod 'Ably', '1.2.53' and has no Package.swift, and a podspec's s.dependency 'Ably' can only resolve against a published pod — so the pod path cannot reach 2.x at all. Its users face a breaking major regardless (renamed repo, new ably_pubsub_device package, new factory), so the build-system change lands inside a migration they are already making. Worth confirming with that owner, since PDR-091b2 marks ably-flutter as a prerequisite to schedule early.

What

  • Ably.podspec deleted, along with the pod_lint Makefile target.
  • Examples/Tests deleted — an example app whose only purpose was proving pod install worked, plus its step in examples.yaml and its Podfile.lock entry in .gitignore. The SPM, Carthage and push examples are untouched.
  • check-pod.yaml → check-carthage.yaml. Only two of its steps concerned pods (printing the CocoaPods version, and pod lib lint); everything else builds Ably.framework.zip, which Carthage consumers install and which the release process attaches to the GitHub release. So the workflow stays and loses the lint. Its job is still named check, so no check name changes.
  • Docs corrected where the change falsified them: the README's install list and CocoaPods section (replaced by a short notice), CONTRIBUTING.md's distribution table, the four reasons LiveObjects is SPM-only — three of which cited the podspec — the release process, CLAUDE.md's distribution sentence, and the parenthetical in Docs/plugins.md that named CocoaPods as a non-SPM build.

Second commit: Carthage goes too

With the pod gone, Swift Package Manager is the only channel for 2.x. The Carthage Ably.xcframework's last release stays on the 1.x line alongside the pod.

Removed: Cartfile and Cartfile.resolved, check-carthage.yaml (which the first commit had kept for exactly this artifact), the two Scripts/*carthage* helpers, every carthage_* Makefile target, and Examples/AblyCarthage with its step in examples.yaml. make update now only updates submodules.

Three things worth calling out:

  • docs.yml no longer resolves Carthage dependencies before generating docs. It never needed them: jazzy.sh and generate-markdown-api-reference.py parse headers out of Source/, and no public header imports msgpack or AblyDeltaCodec, so the step was vestigial.
  • The Carthage/ entry stays in .gitignore, narrowed to the whole directory. Removing it exposed a leftover local checkout to both git status and editorconfig-checker — the linter failed on third-party trailing whitespace under Carthage/Checkouts/Nimble/… until it was restored.
  • Ably.xcodeproj is kept but is now dormant. It took its dependencies from Carthage/Build, so it has no way to resolve them, and nothing in CI builds its schemes. It stays because Ably.xcworkspace references it and it hosts the soak-test app; CONTRIBUTING.md now says so rather than leaving the next person to discover it. Removing it properly is a separate change.

CONTRIBUTING.md's Distribution section is rewritten rather than patched: with one channel its premise — that a release tag delivers different products to different channels — no longer holds, and three of the four reasons it gave for AblyLiveObjects being SPM-only cited the podspec or the Xcode project.

Verification

swift build clean, make parses, editorconfig clean, and a grep for Ably.podspec, Examples/Tests, check-pod and pod_lint across the tree returns nothing outside CHANGELOG.md and .github/issue_template.md — both left alone deliberately, since they describe released 1.x versions and the people filing issues about them.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Sep 10, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions
github-actions Bot temporarily deployed to staging/pull/2278/features September 10, 2026 12:26 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2278/AblyLiveObjects September 10, 2026 12:28 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2278/jazzydoc September 10, 2026 12:31 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2278/markdown-api-reference September 10, 2026 12:31 Inactive
@maratal maratal changed the title Drop CocoaPods support Drop CocoaPods and Carthage support Sep 10, 2026
@github-actions
github-actions Bot temporarily deployed to staging/pull/2278/features September 10, 2026 13:30 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2278/AblyLiveObjects September 10, 2026 13:32 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2278/jazzydoc September 10, 2026 13:33 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2278/markdown-api-reference September 10, 2026 13:34 Inactive
@maratal
maratal added this pull request to stack #2281 September 10, 2026 15:26
maratal and others added 12 commits September 10, 2026 18:29
First step of the PDR-091b device/server split. The SPM product that
vends the core SDK is renamed Ably -> AblyPubSubCore and documented as an
internal implementation product for Ably's own packages; the manifest
name becomes ably-pubsub-cocoa.

The module stays Ably and the class prefix stays ART: the split changes
the package a consumer depends on, not the symbols inside it, so every
import and #import is untouched.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
PubSubDevice.createClient(options:) returns the same ARTRealtime the
constructor does, plus the agent entry that tells Ably the client runs on
an end user's device. Key and token conveniences mirror the core's
initialisers.

The caller's options and their agents dictionary are never mutated: the
entry goes onto a copy, applied last so it wins a collision on its own
name, and versionless because the SDK entry beside it carries the version.

Tests live in AblyTests, where the proxy transport and HTTP executor are,
and assert the identifier on the wire in both directions — that is what
billing reads.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The identifier follows the package family, so traffic from the new
packages is distinguishable from the 1.x line by a string match rather
than a version range: 1.x keeps sending ably-cocoa for the rest of its
life.

Registers PubSubDeviceTests with set-version.sh, since it now pins the
version in an expected agent string.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
These files are read by anyone using the SDK, and the links resolve only
inside Ably, so they replaced an explanation with a pointer the reader
cannot follow. The reasoning is now written out in place.

Commit messages and PR descriptions still reference the records, where
the audience can open them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The integration helpers wrapped an SDK callback in a continuation and
recorded the issue inside that callback, which runs on the SDK's callback
queue. swift-testing cannot attribute an issue recorded there to the
running test, so instead of failing one test it aborts the process:

  Fatal error: Issue 'Issue recorded: publish(messages) failed: Error
  -1001 - The request timed out.' was recorded at PublishTests.swift:72
  without an associated test.

The whole platform leg then fails with an empty "Failing tests:" list, and
-retry-tests-on-failure cannot absorb it, because there is no attributed
failure to re-run — so a transient sandbox timeout takes out a leg that
retry exists to rescue.

Each helper now carries the outcome across the continuation and records
after the await. Where the message varies by path it crosses as a whole;
otherwise only the error's description does, since ARTErrorInfo is not
Sendable. Nothing about what is asserted changes.

Fixes #2272

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
number_of_retries made xcodebuild re-run failed tests, but scan judged the
lane on every attempt, so a test that failed once and passed on retry
still failed CI. The retry was therefore doing nothing it was configured
for, while the comment beside it claimed otherwise.

Seen on the UTS iOS leg: three suites failed, retried, and passed;
xcodebuild reported

  Test run with 752 tests passed after 578.122 seconds
  Test Succeeded

and scan then reported "Number of failures | 3" and failed the lane.

output_remove_retry_attempts makes scan judge each test on its final
state. A genuine regression still fails, because it fails every attempt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
output_remove_retry_attempts does not strip a failure when the retry
skipped the test rather than passing it, so a flake still failed CI even
with retries configured: xcodebuild reported "Test Succeeded" while scan
reported one failure. 2.237.0 carries the fix for that (#30081).

2.237.0 rather than the current 2.239.0: it is the earliest release with
the fix, and it leaves faraday on 1.10.6, where 2.239.0 moves it to 2.x.

Gemfile is unchanged; the dependency stays unpinned and the lockfile
records the resolved version.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The UTS ran as part of Integration Test, which misnamed it — it is
primarily a unit suite, with the sandbox and proxy tiers a minority — and
meant a UTS failure was indistinguishable from an AblyTests one without
opening a log, and re-running either re-ran both.

It now has uts.yaml, so it appears as "UTS / check (...)" against
"Integration Test / check (...)", and can be dispatched and re-run on its
own. Fastlane lanes take a suite: option that selects targets: sdk skips
the UTS target, uts runs only it, and between them they cover the test
plan exactly once. A lane called without suite: still runs everything, so
local invocations are unchanged.

Job and check names are left alone in both workflows, so any required
status checks configured against them keep reporting.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
UTS_SIDE selects which entry point the suite builds realtime clients
through: unset or 'core' uses the constructor, 'device' uses
PubSubDevice.createClient. Running the same specs both ways is what shows
the factory to be a faithful pass-through rather than a stamp on a client
nothing else exercises.

Both realtime construction points now go through makeRealtimeForSide, so
there is one seam. REST is untouched: the device package exposes no HTTP
door. An unrecognised UTS_SIDE aborts rather than falling back, and
SideSeamTests asserts the routing, since either would otherwise leave the
suite quietly repeating the core run and reporting it as coverage.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2.x ships no pod. The Ably pod's last release stays on the 1.x line, which
is maintenance-only, so existing pod consumers keep a supported SDK for
that window and move to Swift Package Manager to go further.

Ably.podspec, the pod-lint Makefile target and Examples/Tests — an example
app whose only purpose was to prove `pod install` worked — are removed.

check-pod.yaml becomes check-carthage.yaml. Only two of its steps were
about pods; the rest builds Ably.framework.zip, which Carthage consumers
install and which release notes attach, so the workflow stays and loses
the `pod lib lint`.

Carthage is untouched: dropping the pod does not decide its fate.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
With CocoaPods already gone, Swift Package Manager is the only channel for
2.x. The Carthage Ably.xcframework's last release stays on the 1.x line
alongside the pod, so existing consumers keep a supported SDK for that
window.

Removed: Cartfile and Cartfile.resolved, check-carthage.yaml, the two
Scripts/*carthage* helpers, every carthage_* Makefile target, and
Examples/AblyCarthage with its step in examples.yaml. `make update` now
only updates submodules.

docs.yml no longer resolves Carthage dependencies before generating docs.
It never needed them: jazzy and the markdown generator parse headers from
Source/, and no public header imports msgpack or AblyDeltaCodec.

The Carthage entry stays in .gitignore, narrowed to the whole directory: a
checkout from the old tooling may still be lying around locally, and it
should be neither committed nor linted.

Ably.xcodeproj is kept, but it took its dependencies from Carthage/Build
and so no longer has a way to resolve them. Nothing in CI builds its
schemes; CONTRIBUTING now says as much.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maratal

maratal commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Closed in favour of #2282, which is the same two commits rebased onto split/uts-per-side so the whole transition is a single stack. GitHub does not allow a pull request that belongs to a tracked stack to change its base, and closing the pull request above it does not release it, so recreating was the only route. Branch dist/drop-cocoapods is unchanged as a name — it now carries the rebased commits.

This branch was successfully deployed

8 active deployments
staging/pull/2282/AblyLiveObjects — 1599ac37 Deployed Sep 10, 2026 by github-actions[bot]
staging/pull/2278/AblyLiveObjects — 1599ac37 Deployed Sep 10, 2026 by github-actions[bot]
staging/pull/2282/markdown-api-reference — 1599ac37 Deployed Sep 10, 2026 by github-actions[bot]
staging/pull/2282/jazzydoc — 1599ac37 Deployed Sep 10, 2026 by github-actions[bot]
staging/pull/2282/features — 1599ac37 Deployed Sep 10, 2026 by github-actions[bot]
staging/pull/2278/markdown-api-reference — 1599ac37 Deployed Sep 10, 2026 by github-actions[bot]
staging/pull/2278/jazzydoc — 1599ac37 Deployed Sep 10, 2026 by github-actions[bot]
staging/pull/2278/features — 1599ac37 Deployed Sep 10, 2026 by github-actions[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant