|
| 1 | +# Swift Package for Mozilla's Rust Components |
| 2 | + |
| 3 | +This repository is a Swift Package for distributing releases of Mozilla's various |
| 4 | +Rust-based application components. It provides the Swift source code packaged in |
| 5 | +a format understood by the Swift package manager, and depends on a pre-compiled |
| 6 | +binary release of the underlying Rust code published from [mozilla/application-services]( |
| 7 | +https://github.com/mozilla/application-service). |
| 8 | + |
| 9 | +For more information, please consult: |
| 10 | + |
| 11 | +* [application-services ADR-0003](https://github.com/mozilla/application-services/blob/main/docs/adr/0003-swift-packaging.md), |
| 12 | + which describes the overall plan for distributing Rust-based components as Swift packages. |
| 13 | +* The [Swift Package Manager docs](https://swift.org/package-manager/) and [GitHub repo](https://github.com/apple/swift-package-manager), |
| 14 | + which explain the details of how Swift Packages work (and hence why this repo is set up the way it is). |
| 15 | +* The [`ios-rust` crate](https://github.com/mozilla/application-services/tree/main/megazords/ios) which is currently |
| 16 | + responsible for publishing the pre-built `MozillaRustComponents.xcframework.zip` bundle on which this |
| 17 | + repository depends. |
| 18 | + |
| 19 | +## Overview |
| 20 | + |
| 21 | +Here's a diagram of how this repository relates to the application-services repository |
| 22 | +and its release artifacts: |
| 23 | + |
| 24 | +<!-- |
| 25 | + N.B. you can edit this image in Google Docs and changes will be reflected automatically: |
| 26 | +
|
| 27 | + https://docs.google.com/drawings/d/1tX05I-e6hNBQxch7PescDH7k4G7ddAJwXDPoIqp1RYk/edit |
| 28 | +--> |
| 29 | +<img src="https://docs.google.com/drawings/d/e/2PACX-1vRnyxy7VjdD3bYTso8V3AL5FpIQ4_S54dOCDI6fxfZEbG3_CVBwZZP1uLYbUVE9M54GSXUkNgewzOQm/pub?w=720&h=540" width="720" height="540" alt="A box diagram describing how the rust-components-swift repo, applicaiton-services repo, and MozillaRustComponents XCFramework interact"> |
| 30 | + |
| 31 | +Key points: |
| 32 | + |
| 33 | +* The `rust-components-swift` repo includes the `application-services` repo as a git submodule. |
| 34 | +* The `application-services` repo publishes a binary artifact `MozillaRustComponents.xcframework.zip` containing |
| 35 | + the Rust code and FFI definitions for all components, compiled together into a single library. |
| 36 | +* The `Package.swift` file references `MozillaRustComponents.xcframework.zip` as a Swift binary target. |
| 37 | +* The `Package.swift` file defines an individual module for the Swift wrapper code of each component. |
| 38 | + * Each module references its Swift source code directly as files in the repo. |
| 39 | + * Each module depends on `MozillaRustComponents` to provide the pre-compiled Rust code. |
| 40 | + |
| 41 | +## Cutting a new release |
| 42 | + |
| 43 | +Whenever a new release of the underlying components is availble, we need to tag a new release |
| 44 | +in this repo to make them available to Swift components. To do so: |
| 45 | + |
| 46 | +* Update the git submodule under `./external` to the new release of the underlying components. |
| 47 | +* Edit `Package.swift` to update the URL and checksum of `MozillaRustComponents.xcframework.zip`. |
| 48 | +* Run `./make_tag.sh X.Y.Z` to create the new tag. |
| 49 | +* Run `git push origin X.Y.Z` to publish it to GitHub. |
| 50 | + |
| 51 | +## Adding a new component |
| 52 | + |
| 53 | +To add a new component to be distributed via this repo, you'll need to: |
| 54 | + |
| 55 | +* Add its Rust code and `.h` files to the build for the `MozillaRustComponents.xcframework.zip` bundle, |
| 56 | + following the docs for the [`ios-rust` crate](https://github.com/mozilla/application-services/tree/main/megazords/ios). |
| 57 | +* Add the source for the component to this repository as a git submodule under `./external`. |
| 58 | +* If the component needs to dynamically generate any Swift code (e.g. for UniFFI bindings, or Glean metrics), |
| 59 | + add logic for doing so to the `./generate.sh` script in this repository. |
| 60 | + * Swift packages can't dynamically generate code at build time, so we use the `./generate.sh` script |
| 61 | + to do it ahead-of-time when publishing a release. |
| 62 | +* Edit `./Package.swift` to add the new component. |
| 63 | + * Add a new library product for the component under "products". |
| 64 | + * Add a corresponding target for the component under "targets". |
| 65 | + * Make sure it depends on "MozillaRustComponents" to pull in the pre-compiled Rust code, |
| 66 | + as well as on any third-party Swift packages that it may require. |
| 67 | +* Follow the instructions below to test it out locally. |
| 68 | + |
| 69 | +That's it! The component will be included in the next release of this package. |
| 70 | + |
| 71 | +## Testing locally |
| 72 | + |
| 73 | +Swift Packages can only be installed from a git repository, but luckily it is possible to use a |
| 74 | +local checkout for a git repository for local testing. |
| 75 | + |
| 76 | +You may also need to follow the instructions for [locally testing the `ios-rust` crate]( |
| 77 | +https://github.com/mozilla/application-services/blob/f3228cf1295154d144be64fc0945c9b3e93a07de/megazords/ios-rust/README.md#testing-locally) |
| 78 | +if you need to test changes in the underlying Rust code. |
| 79 | + |
| 80 | +To test out some local changes to this repo: |
| 81 | + |
| 82 | +* Make your changes in a local checkout and commit them. |
| 83 | +* Make a new tag via `./make_tag.sh -f 0.0.1`. |
| 84 | + * (You won't push this tag anywhere, but using a very low version number helps guard against |
| 85 | + any adverse consequences if it does accidentally escape your local machine). |
| 86 | +* In a consuming application, delete the Swift Package dependency on `https://github.com/mozilla/rust-components-swift` |
| 87 | + and replace it with a dependency on `file:///path/to/your/local/checkout/rust-components-swift` at the `0.0.` release. |
| 88 | + |
| 89 | +That's it! The consuming application should be able to import the package from your local checkout. |
| 90 | + |
0 commit comments