Skip to content

Codemagic Integration

Codemagic Workflow Integration

This guide will help you integrate Shorebird into your Codemagic Workflow using the Codemagic YAML.

The reference code is available on GitHub at https://github.com/shorebirdtech/codemagic_demo.

Prerequisites

This guide assumes that:

  1. Shorebird CLI is installed on your machine (guide).
  2. Codemagic is connected to your repository (guide).

Authentication

Most Shorebird functionality, like creating releases and patches, requires being authenticated. In order to authenticate with Shorebird in CI, you will need to generate a CI token.

Terminal window
shorebird login:ci

You will be prompted to go through a similar OAuth Flow as when using shorebird login, however, shorebird login:ci will not store any credentials on your device. Instead, it will output a base-64 encoded auth token that you will use in your CI environment.

The output of this command should look something like:

$ shorebird login:ci
The Shorebird CLI needs your authorization to manage apps, releases, and patches on your behalf.
In a browser, visit this URL to log in:
https://accounts.google.com/o/oauth2/v2/auth...
Waiting for your authorization...
🎉 Success! Use the following token to login on a CI server:
qwerasdf1234asdfqwer1234asdfqwer1234asdfqwer1234asdfqwer1234asdfqwer1234asdfqwer1234asdfqwer1234asdfqwer1234asdfqwer1234asdfqwer1234asdfqwer1234asdfqwer1234asdfqwer1234asdfqwer1234asdfqwer1234asdfqw==
Example:
export SHOREBIRD_TOKEN="$SHOREBIRD_TOKEN" && shorebird patch android

Next, copy the generated SHOREBIRD_TOKEN and navigate to your Codemagic secrets:

  1. Select the “teams” tab on the left sidebar.
  2. Select the team you want to add the secret to.
  3. Select the “Global Variables and Secrets” tab.
  4. Enter SHOREBIRD_TOKEN as variable name.
  5. Paste the token into the variable value field.
  6. Add it to a group named shorebird.
  7. Ensure “Secure” is checked.

Screenshot of the "Environment Variables" tab in
Codemagic

Set up an Android workflow

This section shows you how to set up a Codemagic workflow to create Android releases, distribute them to the Play Store, and patch them once they’ve been distributed.

As a preview, our finished codemagic.yaml file will look like this:

definitions:
environment:
shared_env: &shared_env
flutter: 3.24.1
groups:
- shorebird
- play_store
vars:
FLUTTER_VERSION: 3.24.1
scripts:
- &shorebird_install
name: Install Shorebird
script: |
# Install Shorebird
curl --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/shorebirdtech/install/main/install.sh -sSf | bash
# Add Shorebird to PATH
echo PATH="$HOME/.shorebird/bin:$PATH" >> $CM_ENV
- &fetch_dependencies
name: Fetch Dependencies
script: |
flutter pub get
workflows:
release-android-workflow:
name: Release Android
instance_type: mac_mini_m1
environment:
<<: *shared_env
android_signing:
- android_keystore
scripts:
- *shorebird_install
- *fetch_dependencies
- name: Shorebird Release
script: |
shorebird release android \
--flutter-version="$FLUTTER_VERSION"
artifacts:
- build/**/outputs/**/*.aab
- build/**/outputs/**/mapping.txt
- flutter_drive.log
publishing:
google_play:
credentials: $GCLOUD_SERVICE_ACCOUNT_CREDENTIALS
track: internal
patch-android-workflow:
name: Patch Android
instance_type: mac_mini_m1
environment:
<<: *shared_env
android_signing:
- android_keystore
inputs:
release_version:
description: The release version to patch
scripts:
- *shorebird_install
- *fetch_dependencies
- name: Shorebird Patch
script: |
shorebird patch android \
--release-version=${{ inputs.release_version }}

Prerequisites

Give Codemagic permission to publish to the Play Store

You can follow the Codemagic guide here to set this up. We put the GCLOUD_SERVICE_ACCOUNT_CREDENTIALS variable in a group named play_store.

Set up your Android keystore in Codemagic

You can follow the Codemagic guide here to create a keystore and upload it to Codemagic. We used android_keystore as the name of the uploaded keystore.

You will also also need to update your android/app/build.gradle file to use this keystore in the Codemagic CI environment:

signingConfigs {
release {
if (System.getenv()['CI']) { // CI=true is exported by Codemagic
storeFile file(System.getenv()['CM_KEYSTORE_PATH'])
storePassword System.getenv()['CM_KEYSTORE_PASSWORD']
keyAlias System.getenv()['CM_KEY_ALIAS']
keyPassword System.getenv()['CM_KEY_PASSWORD']
} else {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}
}

Create Shared Configuration

At the top of our codemagic.yaml file, define shared environment variables and scripts that will be used by multiple workflows. This has been annotated to explain what each part does.

definitions:
environment:
# Use &shared_env to allow us to reference this environment in other
# parts of the file
shared_env: &shared_env
flutter: 3.24.1
groups:
# Add the shorebird group to make $SHOREBIRD_TOKEN available to
# the Shorebird CLI.
- shorebird
# Add the play_store group to make $GCLOUD_SERVICE_ACCOUNT_CREDENTIALS
# available to the Google Play Publishing step.
- play_store
vars:
FLUTTER_VERSION: 3.24.1
scripts:
# A step to install Shorebird and add it to the host machine's PATH
- &shorebird_install
name: Install Shorebird
script: |
# Install Shorebird
curl --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/shorebirdtech/install/main/install.sh -sSf | bash
# Add Shorebird to PATH
echo PATH="$HOME/.shorebird/bin:$PATH" >> $CM_ENV
- &fetch_dependencies
name: Fetch Dependencies
script: |
flutter pub get

Add the Android release workflow

Add the following workflow to your codemagic.yaml file. This has been annotated to explain what each part does.

workflows:
release-android-workflow:
name: Release Android
# This can run on any instance type.
instance_type: mac_mini_m1
environment:
# Add the shared_env we defined in the definitions section.
<<: *shared_env
# Make the keystore available so we can use release signing.
android_signing:
# "android_keystore" is the name of the keystore we uploaded
# to Codemagic.
- android_keystore
scripts:
- *shorebird_install
- *fetch_dependencies
# Run `shorebird release android` to create a release.
# This will upload the release to Shorebird and generate
# the artifacts listed below.
- name: Shorebird Release
script: |
shorebird release android \
--flutter-version="$FLUTTER_VERSION"
# Tell Codemagic where to find the artifacts to publish.
artifacts:
- build/**/outputs/**/*.aab
- build/**/outputs/**/mapping.txt
- flutter_drive.log
publishing:
# Publish to the Google Play Store on the internal track.
google_play:
credentials: $GCLOUD_SERVICE_ACCOUNT_CREDENTIALS
track: internal

With this, you should be able to create a release in Shorebird and publish it to the Google Play Store via Codemagic.

Add the Android patch workflow

Add the following workflow to your codemagic.yaml file. This has been annotated to explain what each part does.

workflows:
patch-android-workflow:
name: Patch Android
# As with the release workflow, this can run on any instance type.
instance_type: mac_mini_m1
environment:
# Add the shared_env we defined in the definitions section.
<<: *shared_env
# Make the keystore available so we can use release signing.
android_signing:
# "android_keystore" is the name of the keystore we uploaded
# to Codemagic.
- android_keystore
# Add an input to allow us to specify the release version to patch.
# This will make this workflow reusable across releases.
inputs:
release_version:
description: The release version to patch
scripts:
- *shorebird_install
- *fetch_dependencies
- name: Shorebird Patch
# Run `shorebird patch android` to patch the specified release.
script: |
shorebird patch android \
--release-version=${{ inputs.release_version }}

With this, you should be able to patch a release in Shorebird via Codemagic.

Set up an iOS workflow

This section shows you how to set up a Codemagic workflow to create iOS releases, distribute them to TestFlight, and patch them once they’ve been distributed.

Prerequisites

Prepare your iOS code signing

Codemagic has a guide on how to set up code signing for iOS here. This guide will help you generate the necessary keys, certificates, and provisioning profiles and load them into Codemagic.

Once you’ve done that, you will need to make these available to your codemagic.yaml scripts. You will end up with four environment variables to support this:

  • KEY_ID: This will be copied directly from App Store Connect.
  • ISSUER_ID: This will be copied directly from App Store Connect.
  • APP_STORE_CONNECT_PRIVATE_KEY: This will be the contents of the private key file you downloaded from App Store Connect. An easy way to get this into Codemagic is to run cat /path/to/AuthKey_12345678.p8 | pbcopy which will copy the contents of the file to your clipboard. You can then paste this into Codemagic.
  • CERTIFICATE_PRIVATE_KEY: Follow this guide to obtain ios_distribution_private_key file. You can then paste the contents of this file into Codemagic. cat ios_distribution_private_key | pbcopy works well for this.

We put all of these variables into a group named app_store.

Create a shared configuration

At the top of our codemagic.yaml file, define shared environment variables and scripts that will be used by multiple workflows. This has been annotated to explain what each part does.

definitions:
environment:
shared_env: &shared_env
flutter: 3.24.1
groups:
# Export the shorebird group to make $SHOREBIRD_TOKEN available to
# the Shorebird CLI.
- shorebird
# Export the app_store group to make the iOS code signing variables
# available the scripts below.
- app_store
vars:
# The bundle ID of this example app.
# Replace this with your app's bundle id.
BUNDLE_ID: dev.shorebird.codemagic-demo
FLUTTER_VERSION: 3.24.1
scripts:
# Download the Shorebird CLI and add it to the PATH.
- &shorebird_install
name: Install Shorebird
script: |
# Install Shorebird
curl --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/shorebirdtech/install/main/install.sh -sSf | bash
# Add Shorebird to PATH
echo PATH="$HOME/.shorebird/bin:$PATH" >> $CM_ENV
- &ios_initialize_keychain
# Set up the keychain to be used for code signing. Create the keychain
# at specified path with specified password with given timeout.
# Make it default and unlock it for upcoming use.
name: Set up keychain to be used for codesigning using Codemagic CLI 'keychain' command
script: |
keychain initialize
- &fetch_signing_files
# Fetch provisioning profiles and code signing certificates for
# the Bundle ID with given identifier.
name: Fetch signing files
script: |
app-store-connect fetch-signing-files "$BUNDLE_ID" \
--type IOS_APP_STORE --create \
--issuer-id "$ISSUER_ID" \
--key-id "$KEY_ID" \
--private-key="$APP_STORE_CONNECT_PRIVATE_KEY"
- &add_certs_to_keychain
name: Add certs to keychain
script: |
keychain add-certificates
- &use_profiles
# This generates an export_options.plist file that tells Xcode
# how to package our app. We explicitly set
# manageAppVersionAndBuildNumber so that we can control which
# version and build number are used for releasing and patching.
name: Set up code signing settings on Xcode project
script: |
xcode-project use-profiles --custom-export-options={\"manageAppVersionAndBuildNumber\":false}
- &fetch_dependencies
name: Fetch Dependencies
script: |
flutter pub get

Add the iOS release workflow

Add the following workflow to your codemagic.yaml file. This has been annotated to explain what each part does.

workflows:
release-ios-workflow:
name: Release iOS
# This needs to run on a Mac instance.
instance_type: mac_mini_m1
integrations:
# "Codemagic" is the name of our App Store Connect API key name.
app_store_connect: Codemagic
environment:
<<: *shared_env
# Tell Codemagic that we're signing our app for App Store distribution
# and to use the bundle ID we defined above.
ios_signing:
distribution_type: app_store
bundle_identifier: "$BUNDLE_ID"
scripts:
# Use the scripts we defined in the definitions section.
- *shorebird_install
- *fetch_dependencies
- *fetch_signing_files
- *ios_initialize_keychain
- *add_certs_to_keychain
- *use_profiles
- name: Shorebird Release
# Run `shorebird release ios` to create a release.
script: |
shorebird release ios \
--flutter-version="$FLUTTER_VERSION" \
--export-options-plist=/Users/builder/export_options.plist
# Tell Codemagic where to find the artifacts generated by
# the `shorebird release ios` command.
artifacts:
- build/ios/ipa/*.ipa
publishing:
app_store_connect:
# Use referenced App Store Connect API key to authenticate binary upload.
auth: integration
# Submit the release to TestFlight, where it can be downloaded by beta
# users and later patched by Shorebird.
submit_to_testflight: true

With this, you should be able to create a release in Shorebird and publish it to TestFlight via Codemagic.

Add the iOS patch workflow

Add the following workflow to your codemagic.yaml file:

workflows:
patch-ios-workflow:
name: Patch iOS
# This needs to run on a Mac instance.
instance_type: mac_mini_m1
environment:
<<: *shared_env
# Tell Codemagic that we're signing our app for App Store distribution
# and to use the bundle ID we defined above.
ios_signing:
distribution_type: app_store
bundle_identifier: "$BUNDLE_ID"
# Add an input to allow us to specify the release version to patch.
# This will make this workflow reusable across releases.
inputs:
release_version:
description: The release version to patch
scripts:
- *shorebird_install
- *fetch_dependencies
- *fetch_signing_files
- *ios_initialize_keychain
- *add_certs_to_keychain
- *use_profiles
- name: Shorebird Patch
# Run `shorebird patch ios` to patch the specified release.
script: |
shorebird patch ios \
--release-version=${{ inputs.release_version }} \
--export-options-plist=/Users/builder/export_options.plist

With this, you should be able to patch a release in Shorebird via Codemagic.