An open API service indexing awesome lists of open source software.

https://github.com/kayak/carthage_remote_cache

Centralized cache to serve carthage frameworks. Useful for distributed CI setup with several build machines.
https://github.com/kayak/carthage_remote_cache

apple bcsymbolmap cache cartfile carthage dsym dsym-files framework ios launchagent mac macos ruby ruby-gem serve-carthage-frameworks swift tvos versioning watchos xcode

Last synced: 11 months ago
JSON representation

Centralized cache to serve carthage frameworks. Useful for distributed CI setup with several build machines.

Awesome Lists containing this project

README

          

# CarthageRemoteCache

[![Test Status](https://github.com/kayak/carthage_remote_cache/actions/workflows/ruby.yml/badge.svg)](https://github.com/kayak/carthage_remote_cache/actions/workflows/ruby.yml)
[![Gem Version](https://badge.fury.io/rb/carthage_remote_cache.svg)](https://badge.fury.io/rb/carthage_remote_cache)

Centralized cache to serve Carthage frameworks. Useful for distributed CI setup with several build machines. It's aware of your `xcodebuild` and `swift` versions and builds on top of Carthage's `.xyz.version` file mechanism.

## Installation

The gem is published at [rubygems.org](https://rubygems.org/gems/carthage_remote_cache), installation is as easy as:

$ gem install carthage_remote_cache

_Note: Installing ri documentation for sinatra can be quite slow. Install with_ `--no-rdoc --no-ri` _if you don't want to wait._

## Quickstart

1. Run `carthagerc server` to start the cache on a remote server
2. `cd` to your project's root folder
3. Run `carthagerc init` to create `Cartrcfile` and point the server property to your running server URL
4. Assuming your `Carthage` directory is already built, run `carthagerc upload` to populate remote cache
5. Push your `Cartrcfile` and from a different machine run `cartrcfile download` to fetch frameworks into `Carthage/Build/` folder
6. Build your app without having to wait for `carthage bootstrap`

## Usage

### Init

Before running any other commands, it's required to initialize `carthagerc` in your project directory by running:

$ carthagerc init

Which produces a `Cartrcfile`. Configuration is done via plain `ruby` code, so it is as simple as:

Configuration.setup do |c|
c.server = "http://localhost:9292/"
end

`Cartrcfile` is supposed to be version controlled (e.g. included in git repository), so that it lives along your code and all consumers of the repository have access to same configuration.

### Upload Workflow

Make sure that all your framework binaries have been built with `carthage`, otherwise there is nothing to upload.

$ carthage bootstrap

Start the upload with:

$ carthagerc upload

After couple of seconds you should be able to see confirmation in terminal:

Uploaded 53 archives (97.2 MB), skipped 0.

#### Overwriting Existing Cache

Attempting to run `carthagerc upload` again will not upload any framework binaries, since all of them are already present on the cache server:

Uploaded 0 archives (0.0 MB), skipped 53.

If your cache happens to be tainted by invalid framework binaries, you can overwrite existing cache with

$ carthagerc upload --force

#### Upgrading Xcode or Swift

It is recommended to always perform the upload workflow after upgrading Xcode and Swift versions since `carthagerc` cached frameworks are not only bound to framework versions, but also to your build environment.

### Download Workflow

Once the cache server has been populated with framework binaries, it's time to fetch frameworks from a different machine. Make sure to pull in `Cartrcfile` from the repository before executing:

$ carthagerc download

You should expect to see the following output on a machine with empty `Carthage` folder:

Downloaded and extracted 53 archives (97.2 MB), skipped 0 archives.

Your project should be ready for building.

#### Overwrite Local Carthage Folder

In case you happen to change a file in `Carthage/Build` by accident, it's possible to force download all frameworks again with:

$ carthagerc download --force

#### Download Only Some Platforms

The example above downloaded all frameworks for all platforms (iOS, macOS, tvOS, watchOS). If large dependencies or network speed are an issue, you can download only a subset of the platforms by using the `--platform` argument:

$ carthagerc download --platform iOS,macOS,tvOS,watchOS

Please note, that invoking the `download` command multiple times with different platform arguments is not supported. The `.version` file will "forget" that `carthagerc` already downloaded the platform specified before the last download. If you need multiple platforms, specify them in a single `download` command once, delimited with a comma.

### Config

To get a quick overview on Xcode / Swift / Framework versions, execute

$ carthagerc config

Which will print similar information:

Xcodebuild: 9C40b
---
Swift: 4.0.3
---
Server: http://localhost:9292/
---
Cartfile.resolved:
github "kayak/attributions" "0.3"
---
Local Build Frameworks:
Attributions 0.3 [:iOS]

### Verify Framework Versions

When switching between development branches, it's very easy to lose track of whether existing framework binaries in `Carthage/Build` match version numbers from `Cartfile.resolved`. As a result, you will probably lose several minutes of your development time, because `Xcode` doesn't tell you about outdated or missing framework binaries.

Luckily, `carthage_remote_cache` provides following command:

carthagerc verify

If existing frameworks match `Cartfile.resolved`, script exits with `0` and doesn't print anything.

In the event of framework version mismatch, you'll be able to observe following output:

Detected differences between existing frameworks in 'Carthage/Build' and entries in 'Cartfile.resolved':

+-----------------+----------------+-------------------+
| Framework | Carthage/Build | Cartfile.resolved |
+-----------------+----------------+-------------------+
| CocoaLumberjack | 3.2.1 | 3.4.1 |
| PhoneNumberKit | 1.3.0 | 2.1.0 |
| HelloWorld | - | 3.0.0 |
+-----------------+----------------+-------------------+

To resolve the issue:
- run `carthagerc download` to fetch missing frameworks from the server.
- if the issue persists, run `carthage bootstrap` to build frameworks and `carthagerc upload` to populate the server.

#### Git Hook

Running `carthagerc verify` manually on every git checkout / merge / pull could be quite cumbersome. To automate this task, integrate following script [carthagerc-verify-githook](https://github.com/kayak/carthage_remote_cache/blob/master/integrations/carthagerc-verify-githook) into your repository's git hooks, e.g. `post-checkout`.

See `$ man githooks` for all available git hooks and their documentation.

### Cache Server

Start the server with

$ carthagerc server

and browse to [localhost:9292](http://localhost:9292/) where you should be able to see the default _Welcome_ message.

Framework binaries will be stored in `~/.carthagerc_server` folder.

Server is bound to port 9292 by default. If you need to use different port, specify the port number via `-pPORT` or `--port=PORT` command line arguments, e.g.:

$ carthage server -p9000
$ carthage server --port=9000

Don't forget to change port number in your version controlled `Cartrcfile`.

#### Version Compatibility

Before each `carthagerc [upload|download]`, the script compares its version number against cache server. If the version doesn't match, `carthagerc` aborts with:

Version mismatch:
Cache server version: 0.0.7
Client version: 0.0.6

Please use the same version as cache server is using by running:
$ gem install carthage_remote_cache -v 0.0.7

Please note, that this functionality only works with clients starting with version [0.0.6](https://github.com/kayak/carthage_remote_cache/releases/tag/0.0.6).

#### Directory Structure

Cache server stores version files and framework archives in following directory structure:

.carthagerc_server/
9C40b/ # Xcode version
4.0.3/ # Swift version
Framework1/
1.0.0/ # Framework1 version
.Framework1.version # Carthage .version file
Framework1-iOS.zip # Framework binary, dSYM and bcsymbolmap files
Framework1-macOS.zip
Framework1-tvOS.zip
Framework1-watchOS.zip
2.0.3/ # Framework1 version
.Framework1.version
Framework1-iOS.zip
Framework2/
v3.2/ # Framework2 version
.Framework2.version
Framework2-iOS.zip

It's safe to delete whole directories since no other metadata is stored.

#### Launch Agent

You can also run the cache server as a launch agent. Copy the template [com.kayak.carthagerc.server.plist](https://github.com/kayak/carthage_remote_cache/blob/master/integrations/com.kayak.carthagerc.server.plist) file to `~/Library/LaunchAgents`, change log
paths to include your username and run:

$ launchctl load -w ~/Library/LaunchAgents/com.kayak.carthagerc.server.plist

If you want to stop the agent, run:

$ launchctl unload ~/Library/LaunchAgents/com.kayak.carthagerc.server.plist

Check out official documentation on [Launch Agents](https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html) for more info.

#### Docker

To build an image based on the latest released gem, run

$ docker build -t carthagerc .

Afterwards you can run the image in a container using

$ docker run -d --publish 9292:9292 --name carthagerc carthagerc:latest

The server will now be available on port 9292 on `localhost`. Note that the command above will cause any data added to `~/.carthagerc_server` to be written into the container layer. While this works, it's generally discouraged due to decreased performance and portability. To avoid this, you can use a volume.

$ docker run -d --publish 9292:9292 --mount "source=carthagerc,target=/root/.carthagerc_server" --name carthagerc carthagerc:latest

We also recommend adding the `--log-opt` option to limit the size of logs, e.g. `--log-opt max-size=50m`.

To inspect the logs after running, use

$ docker logs carthagerc

To stop the container, run

$ docker container stop carthagerc

### Version

$ carthagerc version

### Help

Documentation is also available when running `carthagerc` or `carthagerc --help`. Both commands print list of available commands with brief description.

carthagerc COMMAND [OPTIONS]

...

COMMANDS
config
print environment information and Cartrcfile configuration

download [-f|--force] [-v|--verbose] [-mPLATFORM|--platform=PLATFORM]
fetch missing frameworks into Carthage/Build

init
create initial Cartrcfile in current directory

upload [-f|--force] [-v|--verbose]
archive frameworks in Carthage/Build and upload them to the server

server [-pPORT|--port=PORT]
start cache server

verify
compare versions from Cartfile.resolved to existing frameworks in Carthage/Build

version
print current version number

OPTIONS
-f, --force Force upload/download of framework archives even if local and server .version files match
-h, --help Show help
-m, --platform=PLATFORM Comma delimited list of platforms which should be downloaded from the server; e.g. `--platform iOS,macOS`; Supported values: iOS, macOS, tvOS, watchOS
-n, --no-retry Don't retry download or upload on network failures
-p, --port=PORT Server application port used when starting server, default port is 9292
-v, --verbose Show extra runtime information

## Development

### Setup

After checking out the repo, run `dev/setup` to install dependencies. You can also run `dev/console` for an interactive prompt that will allow you to experiment.

### Development Server

To start development server, run `dev/start_server`, which utilizes `rerun` for automatic reloading of source code and resources.

### Tests

Execute unit tests with `rake test` or start monitoring directories for changes with `bundle exec guard`.

### Source Code Format

Before committing, make sure to auto-format source code wit `rake format`.

### Gem Lifecycle

To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org/gems/carthage_remote_cache).

### Experiments With Example Folder

Repository is bundled with an example Carthage setup for your experiments. Open the [example](https://github.com/kayak/carthage_remote_cache/blob/master/example) folder, where you should be able to see following files, which are preconfigured to bring in a couple of frameworks:
- Cartfile
- Cartfile.resolved
- Cartrcfile

Make sure to build these dependencies with `carthage bootstrap` before attempting to upload them.

Try out a few commands:

$ carthagerc config
$ carthagerc upload
$ carthagerc download

## License

The gem is available as open source under the terms of the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0).