Skip to content

Cache Swift packages across CI runs - #998

Merged
lawrencecchen merged 2 commits into
mainfrom
feat-spm-cache
Mar 6, 2026
Merged

lawrencecchen merged 2 commits into
mainfrom
feat-spm-cache

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Mar 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

All CI workflows were re-fetching SPM dependencies (Sparkle, sentry-cocoa, swift-markdown-ui, posthog-ios, NetworkImage) from GitHub on every run. This adds actions/cache keyed on Package.resolved to persist the cloned source packages directory across runs.

  • nightly.yml / release.yml: Replaced the no-op SwiftPM cache step with actions/cache + -clonedSourcePackagesDirPath .spm-cache on the xcodebuild command
  • ci.yml / ci-macos-compat.yml / test-e2e.yml: Added actions/cache before the existing resolve step, stopped deleting the cache directory each run

Test plan

  • CI passes on this PR (the workflow-guard-tests job validates the SPM retry pattern is still present)
  • Trigger a second run on the same branch to confirm cache hit (no fetching in resolve step)

Summary by cubic

Caches SwiftPM dependencies across CI runs to avoid re-fetching packages and speed up builds. Uses actions/cache keyed by Package.resolved, with xcodebuild pointing to the cached source packages directory; cache keys are scoped by runner/OS where needed.

  • Refactors
    • ci.yml, ci-macos-compat.yml, test-e2e.yml: add actions/cache for .ci-source-packages, stop deleting it before resolve, and include runner/OS in the cache key (matrix.os or inputs.runner).
    • nightly.yml, release.yml: replace the SwiftPM cache step with actions/cache for .spm-cache and pass -clonedSourcePackagesDirPath to xcodebuild.

Written for commit d767274. Summary will update on new commits.

Summary by CodeRabbit

  • Chores
    • Implemented Swift package caching across CI workflows to speed up builds and reduce redundant dependency resolution.
    • Preserves previously resolved package artifacts between runs to improve cache hits and overall pipeline performance.
    • Adjusted package cleanup/initialization sequencing to rely on cached artifacts during resolution.

Add actions/cache for the SPM cloned source packages directory so
subsequent runs skip fetching Sparkle, sentry-cocoa, swift-markdown-ui,
posthog-ios, and NetworkImage from GitHub each time.

- nightly/release: replace the no-op SwiftPM cache step with
  actions/cache + -clonedSourcePackagesDirPath on xcodebuild
- ci/ci-macos-compat/test-e2e: add actions/cache before the existing
  resolve step, stop deleting the cache dir each run
@vercel

vercel Bot commented Mar 6, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Mar 6, 2026 6:16am

@coderabbitai

coderabbitai Bot commented Mar 6, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4df73339-2986-41c0-898b-dc9a3d905cb6

📥 Commits

Reviewing files that changed from the base of the PR and between d8db3ee and d767274.

📒 Files selected for processing (1)
  • .github/workflows/test-e2e.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/test-e2e.yml

📝 Walkthrough

Walkthrough

Adds GitHub Actions caching for Swift packages across CI workflows, reusing .ci-source-packages / .spm-cache via keys derived from Package.resolved and removing pre-emptive rm -rf cleanup steps so cached packages persist between runs.

Changes

Cohort / File(s) Summary
Standard CI / macOS compatibility
.github/workflows/ci-macos-compat.yml, .github/workflows/ci.yml, .github/workflows/test-e2e.yml
Add actions/cache step for Swift packages using .ci-source-packages and a key based on Package.resolved; remove prior rm -rf "$SOURCE_PACKAGES_DIR" cleanup before resolution.
Nightly / Release builds
.github/workflows/nightly.yml, .github/workflows/release.yml
Introduce actions/cache for .spm-cache keyed on Package.resolved; pass -clonedSourcePackagesDirPath .spm-cache to xcodebuild; replace manual env-based cache setup.

Sequence Diagram(s)

sequenceDiagram
    participant Actions as GitHub Actions workflow
    participant Cache as actions/cache
    participant SwiftPM as Swift Package Manager (resolve)
    participant Xcode as xcodebuild

    Actions->>Cache: restore cache (key: Package.resolved hash)
    Cache-->>Actions: cache hit/miss
    Actions->>SwiftPM: Resolve Swift packages (use cached dir if present)
    SwiftPM-->>Actions: resolved packages in .ci-source-packages / .spm-cache
    Actions->>Xcode: build with -clonedSourcePackagesDirPath .spm-cache
    Xcode-->>Actions: build artifacts
    Actions->>Cache: save updated cache (if changes)
    Cache-->>Actions: persisted cache
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I cached the carrots (packages) neat,
In .spm-cache and .ci-source-packages sweet,
No more clearing the burrow at dawn,
Builds hop faster — a developer yawn! 🥕✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Cache Swift packages across CI runs' directly and concisely summarizes the main objective of the changeset: adding caching for Swift packages in CI workflows.
Description check ✅ Passed The PR description covers the summary and testing sections with clear details about what changed and why, though the Testing section lacks evidence of manual verification and the checklist is incomplete.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-spm-cache

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

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 5 files

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
.github/workflows/test-e2e.yml (1)

154-159: Consider including runner in cache key for consistency.

The runner input allows selecting macos-15 or macos-26, but the cache key doesn't include this. While SwiftPM cloned packages are source code and likely OS-agnostic, ci-macos-compat.yml does include matrix.os in its cache key. For consistency, consider:

♻️ Suggested change
       - name: Cache Swift packages
         uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4
         with:
           path: .ci-source-packages
-          key: spm-${{ hashFiles('GhosttyTabs.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved') }}
-          restore-keys: spm-
+          key: spm-${{ inputs.runner || 'macos-15' }}-${{ hashFiles('GhosttyTabs.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved') }}
+          restore-keys: spm-${{ inputs.runner || 'macos-15' }}-
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/test-e2e.yml around lines 154 - 159, The cache key for
"Cache Swift packages" omits the selected runner/OS, causing inconsistent cache
scopes; update the key generation used in the with.key for that step (the line
starting with key: spm-) to include the workflow runner/OS identifier (e.g.
append -${{ inputs.runner }} or -${{ matrix.os }} to the key) so the cache is
namespaced per runner like ci-macos-compat.yml does.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.github/workflows/test-e2e.yml:
- Around line 154-159: The cache key for "Cache Swift packages" omits the
selected runner/OS, causing inconsistent cache scopes; update the key generation
used in the with.key for that step (the line starting with key: spm-) to include
the workflow runner/OS identifier (e.g. append -${{ inputs.runner }} or -${{
matrix.os }} to the key) so the cache is namespaced per runner like
ci-macos-compat.yml does.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e6a21f34-3382-46b0-a9fe-7e00cbcdf282

📥 Commits

Reviewing files that changed from the base of the PR and between a7cef78 and d8db3ee.

📒 Files selected for processing (5)
  • .github/workflows/ci-macos-compat.yml
  • .github/workflows/ci.yml
  • .github/workflows/nightly.yml
  • .github/workflows/release.yml
  • .github/workflows/test-e2e.yml

@greptile-apps

greptile-apps Bot commented Mar 6, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds actions/cache to persist Swift Package Manager source packages across CI runs, which is a good performance improvement. The implementation correctly:

  • Uses actions/cache with Package.resolved as the cache key base, ensuring cache invalidation when dependencies change
  • Adds cache steps before the resolve/build steps in all five modified workflows
  • Removes the rm -rf that previously cleared the cache directory on each run
  • Includes the OS matrix variable in ci-macos-compat.yml's cache key to prevent cross-OS collisions

The changes follow consistent patterns across workflows and should provide the intended caching benefits.

Confidence Score: 5/5

  • All implementation patterns are consistent and correct. Cache key strategy based on Package.resolved ensures proper invalidation. No safety concerns identified.
  • The PR correctly implements Swift package caching across all five modified workflows. Each workflow uses appropriate cache paths and keys derived from Package.resolved, ensuring cache invalidation when dependencies change. The OS matrix variable is properly included in ci-macos-compat.yml to prevent cross-OS collisions. All cache steps are positioned correctly (before resolve/build), and the removal of previous cache-clearing logic is intentional to preserve the cache. Code review found no correctness issues.
  • No files require special attention

Last reviewed commit: d8db3ee

Consistent with ci-macos-compat.yml which uses matrix.os in the key.
@lawrencecchen
lawrencecchen merged commit c37ace5 into main Mar 6, 2026
12 checks passed
@lawrencecchen
lawrencecchen deleted the feat-spm-cache branch March 6, 2026 07:26
bn-l pushed a commit to bn-l/cmux that referenced this pull request Apr 3, 2026
* Cache Swift packages across CI runs

Add actions/cache for the SPM cloned source packages directory so
subsequent runs skip fetching Sparkle, sentry-cocoa, swift-markdown-ui,
posthog-ios, and NetworkImage from GitHub each time.

- nightly/release: replace the no-op SwiftPM cache step with
  actions/cache + -clonedSourcePackagesDirPath on xcodebuild
- ci/ci-macos-compat/test-e2e: add actions/cache before the existing
  resolve step, stop deleting the cache dir each run

* Include runner in test-e2e cache key

Consistent with ci-macos-compat.yml which uses matrix.os in the key.

This branch was successfully deployed

1 active deployment
Preview — d7672742 Deployed Mar 6, 2026 by vercel[bot]
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.

1 participant