Skip to content

[FSSDK-13238] ci: build all platforms on Xcode 16 and 27, check API breaks, harden workflows - #660

Merged
muzahidul-opti merged 7 commits into
masterfrom
muzahid/ci-hardening
Oct 7, 2026
Merged

muzahidul-opti merged 7 commits into
masterfrom
muzahid/ci-hardening

Conversation

@muzahidul-opti

@muzahidul-opti muzahidul-opti commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #659. Adds compile-only gates (deterministic, no flaky tests) and cleans up CI, modeled on Alamofire / firebase-ios-sdk.

 swift.yml
+  concurrency: cancel superseded runs of the same PR (push/manual runs never queued or dropped)
   lint_markdown_files    uses ./.github/workflows/...   (was @master)
   integration_tests      uses ./.github/workflows/...   (was @master)
-  package_validation     swift build + SourceClear       (redundant, see below)
+  build (Xcode_27.0 | Xcode_16.0)
+    swift build                                     # macOS 12
+    swift build --triple arm64-apple-ios15.0        # iOS 15
+    swift build --triple arm64-apple-tvos15.0       # tvOS 15
+    swift build --triple arm64_32-apple-watchos9.0  # watchOS 9 (never built in CI before)
+  api_breaking_changes (PRs only)
+    swift package diagnose-api-breaking-changes origin/$BASE_REF
   unittests              + timeout 90m, xcbeautify annotations
  • package_validation removed:
    • its swift build is the first step of build (Xcode_27.0)
    • swift package resolve is a no-op, since there are no dependencies
    • SourceClear still scans master on every push and weekly via source_clear_cron.yml
  • Actions:
    • actions/checkout v3 → v7 and actions/upload-artifact v4 → v7 (both off the deprecated Node 20)
    • referenced by major tag
    • persist-credentials: false on every checkout, including the CI_USER_TOKEN PAT checkout of ci-helper-tools (Arnica artipacked finding; its scripts only call the API with curl and the env token)
  • Timeouts on macOS jobs:
    • unit tests 90m (3 retry attempts can take 60–70m)
    • builds 30m, API check 20m, SourceClear cron 30m
  • Leftovers:
    • drop the unused buildoutput tee in run_unit_tests.sh
    • lint_markdown Ruby 2.6 (EOL) → 3.3, dropping bundler-cache (there's no Gemfile)

Test plan

PR CI on this branch (run, before the cleanup commit):

  • api_breaking_changes: pass (first real run, no breaks vs master)
  • build (Xcode_16.0) on macos-15: macOS, iphoneos, appletvos, watchos all Build complete!
  • build (Xcode_27.0), integration tests, lint, iPhone 17 + tvOS unit tests: pass
  • Earlier manual run: all 4 unit test jobs pass within the 90m timeout, and xcbeautify output is present on xcode-27

Local, Xcode 27.0, API check:

  • Before (v5.4.2 → HEAD): No breaking changes detected in Optimizely
  • After removing public from getEnabledFeatures: 💔 API breakage: func OptimizelyClient.getEnabledFeatures(userId:attributes:) has been removed, exit 1 (change reverted)

Lint and cleanup commit:

  • actionlint clean (ignoring the custom xcode-27 runner label and pre-existing SC2086 infos)
  • The cleanup commit's Ruby 3.3 lint and upload-artifact@v7 are verified by this PR's CI run

Merge Danger

Door: two-way. Workflow-only changes that revert cleanly.

Blast Radius:

  • api_breaking_changes fails on intentional breaks, so keep it a non-required check.
  • SourceClear no longer runs on each PR, only on master (push + weekly). Revisit if the SDK gains third-party dependencies or security requires pre-merge SCA.
  • Major-version bumps of actions stay manual (prompted by GitHub deprecation warnings).
  • Settings, after merge:
    • required check names must be unittests (27.0, …); the current (27, …) entries never report
    • add build (Xcode_16.0), build (Xcode_27.0), jira_ticket_reference_check

Issues

  • FSSDK-13238

🤖 Generated with Claude Code

Comment thread .github/workflows/integration_tests.yml Outdated
Comment thread .github/workflows/unit_tests.yml Outdated
@datadog-optimizely-experimentation

This comment has been minimized.

@muzahidul-opti
muzahidul-opti force-pushed the muzahid/ci-hardening branch 3 times, most recently from ca8bf28 to 2d0ccd9 Compare October 6, 2026 17:51
Base automatically changed from muzahid/spm-release-workflow to master October 7, 2026 00:59
muzahidul-opti and others added 6 commits October 7, 2026 07:01
…workflows

- Compile the package for iOS, tvOS, watchOS and macOS on the newest
  (27.0) and oldest supported (16.0) Xcode; watchOS was never built in CI
- Fail PRs that break public API vs. the base branch
  (swift package diagnose-api-breaking-changes)
- Cancel superseded PR runs; add timeouts to macOS jobs
- Upgrade actions/checkout v3 -> v7, pin all actions to commit SHAs,
  stop persisting checkout credentials, add Dependabot for actions
- Call reusable workflows from the same commit instead of @master
- Pipe unit test output through xcbeautify for inline PR annotations

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tools

The trigger scripts only call the GitHub API with curl using the token
from the environment, so no git credentials are needed on disk.
Addresses Arnica's artipacked finding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Major tags pick up patch and minor fixes without bot PRs. The ticket
checker stays SHA-pinned since it only has a master branch and hasn't
changed since 2022.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It's Optimizely-owned, so pinning adds little and would hide future fixes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A shared group with cancel-in-progress=false still lets a newer pending
master run replace an older pending one; give non-PR runs a unique group.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A job that needs all 3 retry attempts runs 60-70 minutes; 60 cancelled
a legitimate run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coveralls

coveralls commented Oct 7, 2026 •

Copy link
Copy Markdown

Coverage Status

No base build to compare — muzahid/ci-hardening into master

- package_validation: its swift build is covered by build (Xcode_27.0)
  and SourceClear still scans master via source_clear_cron.yml
- upload-artifact v4 -> v7 (v4 runs on deprecated Node 20; name/path
  inputs unchanged)
- run_unit_tests.sh: drop the unused buildoutput tee
- lint_markdown: Ruby 2.6 (EOL) -> 3.3; drop bundler-cache (no Gemfile)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread .github/workflows/unit_tests.yml
@muzahidul-opti
muzahidul-opti merged commit c9b263f into master Oct 7, 2026
10 of 13 checks passed
@muzahidul-opti
muzahidul-opti deleted the muzahid/ci-hardening branch October 7, 2026 01:49
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