Caching dependencies in Github Actions
How to cache Pods, Ruby gem, and Carthage in your iOS project.
Table of Contents
Caching is one of the most requested features in Github Actions. Now the waiting is over. Caching is now natively supported via the cache action[1].
The following are examples of how to cache Ruby Gem, Cocoapods, and Carthage.
Ruby - Gem
- uses: actions/cache@v1
with:
path: vendor/bundle
key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gem-
You can easily support sarunw.com by checking out this sponsor.
Localization Buddy: Easiest way to localize and update App Store metadata.
Swift, Objective-C - Carthage
- uses: actions/cache@v1
with:
path: Carthage
key: ${{ runner.os }}-carthage-${{ hashFiles('**/Cartfile.resolved') }}
Swift, Objective-C - CocoaPods
- uses: actions/cache@v1
with:
path: Pods
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
The cache action required two input parameters and one optional parameter.
path
: Required The file path on the runner to cache or restore.
key
: Required An explicit key for restoring and saving the cache.
restore-keys
: Optional - An ordered list of keys to use for restoring the cache if no cache hit occurred for key
.
Hit or Miss
When key
matches an existing cache, it's called a cache hit, and the action restores the cached files to the path
directory.
When key
doesn't match an existing cache, it's called a cache miss, and a new cache is created if the job completes successfully. You will see something like at the end of your steps (if the job completes successfully).
When a cache miss occurs, the action searches for alternate keys called restore-keys
. If you provide restore-keys, the cache action sequentially searches for any caches that partial match the list of restore-keys. When the action finds a partial match, the most recent cache is restored to the path
directory.
Skipping steps based on cache-hit
If the cache hit, you might want to skip some steps. Typically you would want to skip the step that downloads dependencies or generate the cached output.
Cache hit result is in the output id cache-hit
and accessible through the following command.
steps.<step_id>.outputs.cache-hit
For our Carthage example, it will look like this.
steps:
- name: Checkout
uses: actions/checkout@v1
- uses: actions/cache@v1
id: carthage-cache
with:
path: Carthage
key: ${{ runner.os }}-carthage-${{ hashFiles('**/Cartfile.resolved') }}
- name: Carthage
if: steps.carthage-cache.outputs.cache-hit != 'true'
run: |
carthage bootstrap --no-use-binaries --platform iOS --cache-builds
Techincally, if there is a cache hit for Ruby gem (vendor/bundle) and Cocoapods (Pods), we should be able to skip bundle install --deployment
[2] and pod install
entirely, but in my test, it resulting in GemNotFound
and The sandbox is not in sync with the Podfile.lock
errors.
So if you try to cache gem and pods you still need to run pod install
and bundle install
. You still get speed benefit since you don't need to fetch most gems and pods from the internet.
- name: Bundle Install
run: bundle install --deployment
- name: Cocoapods
run: bundle exec pod install
Limitation
- Cache entries that have not been accessed in over 7 days will be removed.
- Individual files in a cache must not exceed 400 MB. You will receive a 400 - Bad Request if you exceed this limit.
- The total size of all caches in a repository don't exceed 2 GB. If you exceed this limit, GitHub will save your cache but will begin evicting caches until the total size is less than 2 GB.
You can easily support sarunw.com by checking out this sponsor.
Localization Buddy: Easiest way to localize and update App Store metadata.
Related Resources
- How to setup ci for iOS projects with Github Actions. Github Actions for iOS projects
- Github documentation about caching https://help.github.com/en/actions/automating-your-workflow-with-github-actions/caching-dependencies-to-speed-up-workflows
- Cache Action https://github.com/actions/cache
- Example in many popular languages https://github.com/actions/cache/blob/master/examples.md
I can't find the public announcement about this feature, but It definitely came out within this month (November 2019). ↩︎
You need
--deployment
flag here to installs gems to the vendor/bundle directory in the application, which we use as cache path. https://bundler.io/man/bundle-install.1.html#DEPLOYMENT-MODE ↩︎
Read more article about iOS, CI, Workflow, or see all available topic
Enjoy the read?
If you enjoy this article, you can subscribe to the weekly newsletter.
Every Friday, you'll get a quick recap of all articles and tips posted on this site. No strings attached. Unsubscribe anytime.
Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.
If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.
Become a patron Buy me a coffee Tweet ShareDark color cheat sheet
A cheat sheet that tells you what colors to use to support dark mode. This is a guide for those who want to adopt dark mode, but too lazy to figure out which color to use.