Skip to content

chore: Parallelize builds to cut down CI wall clock time#481

Merged
keelerm84 merged 9 commits intov11from
mk/sdk-1959/faster-builds
Feb 27, 2026
Merged

chore: Parallelize builds to cut down CI wall clock time#481
keelerm84 merged 9 commits intov11from
mk/sdk-1959/faster-builds

Conversation

@keelerm84
Copy link
Member

@keelerm84 keelerm84 commented Feb 26, 2026

Note

Medium Risk
CI is significantly restructured (new parallel jobs/composite actions), which can cause workflow gaps or environment/tooling mismatches. There is also a small runtime change to DiagnosticReporter queue QoS that could affect timing/performance characteristics.

Overview
CI is restructured to run faster via parallel jobs. The monolithic .github/actions/ci composite is removed and replaced with focused composites (lint, build-ios, build-macos, build-tvos, build-watchos, test-swiftpm, contract-tests), with ci.yml updated to run these as separate jobs (including a matrix across Xcode 15.4/16.4 where applicable). iOS/tvOS/watchOS builds now include an xcrun simctl list devices available warm-up step to mitigate intermittent macos-15 simulator runtime issues.

Tooling and tests are adjusted for reliability. Mint is removed (Mintfile deleted) and Xcode build phases/schemes are updated to invoke swiftlint/sourcery directly; lint now also verifies generated code is up to date. Several unit tests are made less flaky by avoiding OHHTTPStubs for error paths, adding explicit shutdown in DiagnosticReporterSpec, and preventing polling/timer races in FlagSynchronizerSpec; DiagnosticReporter queue QoS is changed from .background to .utility.

Written by Cursor Bugbot for commit 67c45fd. This will update automatically on new commits. Configure here.

@keelerm84 keelerm84 requested a review from a team as a code owner February 26, 2026 19:17
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

private var sentInit: Bool
private let stateQueue = DispatchQueue(label: "com.launchdarkly.diagnosticReporter.state", qos: .background)
private let workQueue = DispatchQueue(label: "com.launchdarkly.diagnosticReporter.work", qos: .background)
private let stateQueue = DispatchQueue(label: "com.launchdarkly.diagnosticReporter.state", qos: .utility)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small behavioral change here. This provides slightly more priority to the diagnostic stuff, which trimmed several minutes off the build time as these background queues were being deprioritized.

@keelerm84 keelerm84 merged commit 27d68a6 into v11 Feb 27, 2026
18 checks passed
@keelerm84 keelerm84 deleted the mk/sdk-1959/faster-builds branch February 27, 2026 16:27
kinyoklion pushed a commit to launchdarkly/swift-eventsource that referenced this pull request Mar 9, 2026
**Requirements**

- [ ] I have added test coverage for new or changed functionality
- [ ] I have followed the repository's [pull request submission
guidelines](../blob/main/CONTRIBUTING.md#submitting-pull-requests)
- [ ] I have validated my changes against all supported platform
versions

**Related issues**

Ports the relevant CI changes from
[launchdarkly/ios-client-sdk#481](launchdarkly/ios-client-sdk#481)
to swift-eventsource to reduce CI build times. Also incorporates the
contract test fix from branch
`devin/1772832423-fix-contract-test-version`.

The contract tests previously failed due to GitHub API rate limiting in
the `sse-contract-tests` downloader script. The root cause fix is in
[launchdarkly/sse-contract-tests#34](launchdarkly/sse-contract-tests#34).

**Describe the solution you've provided**

The monolithic `.github/actions/ci` composite action ran all builds,
tests, linting, and contract tests sequentially in a single job. This PR
breaks it into focused composite actions that run as **separate parallel
jobs** in `ci.yml`:

| New action | What it does |
|---|---|
| `lint` | `brew install swiftlint`, `pod lib lint --quick`, `swiftlint
lint` |
| `build-ios` | Build for iOS device + test on iOS Simulator |
| `build-macos` | Build & test on macOS + ARM64 build |
| `build-tvos` | Build for tvOS device + test on tvOS Simulator |
| `build-watchos` | Build for watchOS device + simulator |
| `test-swiftpm` | `swift test` via SwiftPM |
| `contract-tests` | Build service, start in background, run via
`launchdarkly/gh-actions/actions/contract-tests@main` |
| `build-docs` | (already existed, now its own job with `setup-xcode`) |

Other changes:
- **Mint removed** — `Mintfile` deleted; swiftlint installed directly
via `brew install swiftlint`
- **Simulator warmup** added for iOS/tvOS/watchOS (`xcrun simctl list
devices available`) to mitigate intermittent macos-15 runner issues
([actions/runner-images#12948](actions/runner-images#12948))
- **Pod lint** changed from `pod spec lint` to `pod lib lint
--allow-warnings --quick` (skips full build since dedicated jobs already
compile all platforms)
- **`setup-xcode`** moved to workflow level (each job sets up Xcode
explicitly)
- **Contract tests fixed** — uses the shared
`launchdarkly/gh-actions/actions/contract-tests@main` action
(intentionally `@main` — this is our own organization's action).
Configured with `branch: main` (since `sse-contract-tests` uses `main`,
not `v2`, as its default branch) and `enable_persistence_tests: false`
(SSE contract tests don't support that flag). Two known-flaky tests are
skipped via `extra_params`.
- **Release/publish workflows** (`release-please.yml`,
`manual-publish.yml`, `manual-publish-docs.yml`) updated to call
individual composite actions sequentially (these must remain sequential
since they gate the publish step)

**Checklist for human reviewer**


1. **SwiftLint version is no longer pinned** — Mintfile pinned
`realm/SwiftLint@0.56.2`; now `brew install swiftlint` pulls whatever
Homebrew provides. Verify this won't cause unexpected lint failures.
2. **Pod lint command changed** — switched from `pod spec lint` to `pod
lib lint` with `--allow-warnings --quick`. Confirm `lib lint` is
appropriate here (validates local podspec vs. published spec).
3. **Runner usage** — each parallel job spins up its own macOS runner (8
macOS jobs instead of 1). Wall clock time decreases but total
runner-minutes may increase.
4. **Contract test action uses `@main`** — uses
`launchdarkly/gh-actions/actions/contract-tests@main` (mutable ref)
rather than a pinned SHA. This is intentional per repo owner direction —
the action is from LaunchDarkly's own organization.

**Describe alternatives you've considered**

- Could have kept Mint with version pinning — chose to match
ios-client-sdk pattern which removed Mint.
- Could have created a matrix for multiple Xcode versions — kept single
version (16.4) to match current setup.

**Additional context**

- This is CI-only infrastructure; no application logic changed.
- Changes cannot be validated locally — require GitHub Actions run to
verify.
- Link to Devin Session:
https://app.devin.ai/sessions/2da8679d630649d4be8984e8cab6c980
- Requested by: rlamb@launchdarkly.com (via @kinyoklion)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> CI-only changes, but they restructure job orchestration, switch
lint/tool installation sources, and move contract testing to an external
action ref (`@main`), any of which can cause unexpected pipeline
failures or behavior changes.
> 
> **Overview**
> Refactors GitHub Actions CI from a single composite
(`.github/actions/ci`) into multiple focused composite actions (lint,
per-platform Xcode builds/tests, SwiftPM tests, and contract tests) and
updates `ci.yml` to run them as separate **parallel** jobs on `macos-15`
(with Xcode 16.4 setup per job) to reduce wall-clock time.
> 
> CI reliability and tooling are adjusted: adds simulator “warm-up”
(`xcrun simctl list devices available`) for iOS/tvOS/watchOS, switches
pod linting to `pod lib lint --allow-warnings --quick`, removes
Mint/`Mintfile` in favor of `brew install swiftlint`, and updates
contract tests to run via
`launchdarkly/gh-actions/actions/contract-tests@main` with specific
config and skipped cases.
> 
> Release/publish workflows (`manual-publish*`, `release-please`) are
updated to invoke the new actions sequentially (preserving gating before
publish).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b2e2d4b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants