Integrating Into CI
Uploading from CI
With Emerge's CI integration, you can configure automated comparisons (PR Comments / Status Checks) to show in your VCS, making it easy for everyone in your organization to be aware of your performance metrics.
For CI builds to work, we require additional metadata to be included with the upload that describes where the build was generated. Following a standard Git Flow setup, this would typically be:
- Base build: a build from the
main
ormaster
branch - Head build: a build from a development branch, like a Pull Request
We recommend configuring this in two steps:
- Create a PR to configure uploading a base build. Once this PR is merged, it will upload a base build which future pull requests can use as a base.
- Create a second PR to configure uploading head builds. Uploading head builds is most commonly done from CI that is run on each pull request.
The Emerge Fastlane Plugin (iOS) and Emerge Gradle Plugin (Android) make it easy to integrate Emerge into your CI pipeline. If your team doesn't use Fastlane or Gradle, you also have the option to use our REST API directly.
Metadata fields
The following metadata fields need to be included with your uploads in CI:
Field | Required |
---|---|
filename | Yes (both) |
branch | Yes (both) |
sha | Yes (both) |
repoName | Yes (both) |
tag | No (defaults to release if not provided) |
prNumber | Only for head builds |
baseSha | Only for head builds |
previousSha | No, but encouraged for all builds (required for certain features) |
Tags
tag
is an optional parameter that defaults to release
if not provided when uploading. We recommend changing this value for head builds (eg using pull_request
) and setting it to default
for builds of your default branch.
You can set this value to anything you'd like. For example, you might want to track sizes per device architecture using x86_64
and arm64
tags.
SHA and base SHA
The sha
and baseSha
parameters are used to provide Emerge information about the position of your build within your version control system structure. Both values should be sent using the SHA's long form. If you send a shortened SHA value this may result in errors.
The sha
field should be the commit SHA that your upload was built from. This represents the HEAD position for the build, whether the build is on main or a branch.
The baseSha
field is used specifically for branch builds. This field represents the point in your git tree that your branch was created from, allowing Emerge to identify all the changes on a branch. The baseSha
should remain the same for all builds on a branch, unless the branch is rebased.
Previous SHA
The previousSha
parameter is just like the sha
param, but for the commit before the current one (in git terms: HEAD^
).
It similarly should be sent using the SHA's long form.
We use this value to stitch together a historical relationship across your uploads, without needing code access in your repository. This field enables new features like Snapshot History which allow you to conveniently see changes over time!
Testing the Integration
On a build, you can see the status of your integration by clicking Actions (top-right of screen) > Emerge Metadata > Test Git Integration
Which builds should be uploaded?
For reliable PR diffs, we recommend uploading a branch build after pushing to a PR and when PRs are merged back to your default branch, i.e. main
or master
. Builds from your default branch act as base builds for comparison against branch builds.
It's also important to only compare builds generated from the same (or very similar) build configuration. For example, comparing a debug build against a release build will show unexpected results.
Unique apps per SHA
Emerge will compare uploads by SHA then appId (
packageName
on Android,bundleId
on iOS) to ensure accuracy. Itβs important to make sure there arenβt multiple uploads from the same commit SHA with the same appId, as this could result in inaccurate comparisons.For example, if you upload a debug and release build on each commit, one should be
com.company.app.debug
and the other should becom.company.app
. Otherwise, the release build could be compared against the debug build, resulting in incorrect comparisons.If your build system does not have separate appIds, you can use the parameter
appIdSuffix
for iOS uploads (which is an option in the fastlane action) and applicationIdSuffix for Android apps.
iOS
Test builds
Test builds for running unit tests in CI are created by the xcodebuild test
command and generally use the Debug configuration and target the simulator architecture.
Emerge supports processing these builds with the caveat that the app size and performance may be inaccurate for what your user will see due to skipped compiler optimizations and the target architecture format. Comparisons will still be accurate and allow you to find unexpected size increases, potential savings, and unused code.
Archive builds
Archive builds are created by xcodebuild archive
and are the most accurate representations of app size. These can be used to track size over time or generate PR diffs.
If your app supports iOS 10 or earlier you'll be building multiple architectures when submitting to the App Store. To save time when building for Emerge you can optionally disable the 32-bit architecture since only one CPU slice is needed to measure app size.
Android
Debug builds
Debug builds are created by using debug
Gradle build variants.
Emerge supports processing these builds with the caveat that the app size and performance may be inaccurate for what your user will see. For example, Proguard/R8 code optimizations are disabled by default for debug builds. It's also likely that the shrinkResources
Gradle configuration is disabled. Comparisons will still be accurate and allow you to find unexpected size increases, potential savings, and unused code.
Release builds
Release builds are created by using release
Gradle build variants.
We recommend uploading release builds with Proguard/R8 optimizations enabled, as well as shrinkResources
turned on.
AAB vs APK
Emerge supports both .aab
and .apk
formats, however, diffs must be between builds of the same format.
We recommend uploading AAB builds as they are now required for new apps (as of August 2021). For AAB builds, Emerge will analyze the outputted APKs Google Play would serve for your AAB on a Pixel 5 running Android 11.
Special notes for cross-platform Monorepos
Monorepos, specifically those that contain both iOS and Android projects, introduce some complexity into CI uploads.
Emerge relies on a base build being present for size, performance, and snapshot checks. If you open a pull request with commit SHA bar
against base commit SHA foo
, we first need to find the Emerge build associated with commit foo
. For a Monorepo setup, this can present a challenge if the base commit for the pull request did not trigger a build for the respective platform, e.g. an iOS pull request was branched from an Android commit.
To ensure every code change has a base to compare against, make sure to upload both iOS and Android builds as part of the main branch push. In a GitHub workflow, this looks like:
name: Emerge Android upload
on:
push:
branches: [ main ]
# Notice we only specify a path for pull_request events, not pushes to main
pull_request:
branches: [ main ]
paths: [android/**]
Doing so for your CI system will ensure that no matter the platform a pull request targets, there always will be both an iOS and Android base build present to compare against.
Updated about 2 months ago