Getting started
Introduction
This is a quick reference for using codemagic.yaml
.
- Full documentation for codemagic.yaml (https://docs.codemagic.io/yaml-basic-configuration/yaml-getting-started/)
Reusing Sections
Define a section at the top of the .yaml file and reuse it later in different workflows.
definitions:
instance_mac_mini_m2: &instance_mac_mini_m2
instance_type: mac_mini_m2
max_build_duration: 120
env_versions: &env_versions
flutter: stable
xcode: latest
cocoapods: default
scripts:
- &add_certs_to_keychain
name: Add certs to keychain
script: |
keychain add-certificates
Reuse the defined section elsewhere by adding a * in front of it.
workflows:
ios-release:
name: iOS release
<<: *instance_mac_mini_m2
environment:
<<: *env_versions
scripts:
- *add_certs_to_keychain
Decoding
base64 decoding during build time in your scripts section using command:
echo $ENV_VAR | base64 --decode > /path/afile
Encoding
base64 encoding the confidential file and copying the result to clipboard.
macOS:
cat your_file | base64 | pbcopy
Windows:
[Convert]::ToBase64String([IO.File]::ReadAllBytes("file.ext")) | \
Set-Clipboard
Linux:
sudo apt-get install xclip
cat your_file | \
base64 | \
xclip -selection clipboard
Syntax
workflows:
hello-world-workflow:
name: Hello world workflow
scripts:
- echo "Hello World!"
Workflow environment
Global Environment variable groups
environment:
groups: # Define your environment variables groups here
- keystore_credentials
- app_store_credentials
- firebase_credentials
Tip: Store all the keystore variables in the same group so they can be imported to codemagic.yaml workflow at once.
Workflow specific variables
Define workflow-specific public environment variables:
environment:
vars: # Define your environment variables here
PUBLIC_ENV_VAR: "value here"
Software versions
environment:
flutter: stable # Channel name or version (e.g. v1.13.4)
xcode: latest # Define latest, edge or version (e.g. 11.2)
cocoapods: 1.9.1 # Define default or version
node: 12.14.0 # Define default, latest, current, etc or version
npm: 6.13.7 # Define default, latest, next, lts or version
ndk: r21d # Define default or ver, also define in build.gradle
java: 1.8 # Define default or platform version (e.g. 11)
ruby: 2.7.2 # Define default or version
Triggering
triggering
: defines the events for automatic build triggering and watched branches. If no events are defined, you can only start builds manually.
Skip building a specific commit
Include [skip ci]
or [ci skip]
in a commit message to not build a particular commit.
Trigger on push to any branch
triggering:
events:
- push
branch_patterns:
- pattern: '*'
Exclude dev*
branch
triggering:
events:
- push
branch_patterns:
- pattern: '*' #default value for include is true
- pattern: 'dev*'
- include: false
Trigger on PR created from any branch to any branch
triggering:
events:
- pull_request
branch_patterns:
- pattern: '*'
Trigger on PR created from the dev
branch to any branch
triggering:
events:
- pull_request
branch_patterns:
- pattern: 'dev*'
- source: true #source is true by default
Trigger on PR created from the dev
branch to any branch excluding master
triggering:
events:
- pull_request
Branch_patterns:
- pattern: 'dev*'
- source: false
- pattern: 'master'
- include: false
Trigger on PR created from any branch to dev
triggering:
events:
- pull_request
branch_patterns:
- pattern: 'dev*'
- source: false #source is true by default
Trigger on push and PR created from any branch and cancel outdated webhook builds
2 builds will start: for push and PR. cancel_previous_builds
will cancel out-dated webhook builds but applies for the next webhook only.
triggering:
events:
- push
- pull_request
branch_patterns:
- pattern: '*'
cancel_previous_builds: true
Avoid running builds on outdated commits by setting cancel_previous_builds
to automatically cancel all ongoing and queued builds triggered by webhooks on push or pull request commit when a more recent build has been triggered for the same branch.
Conditional Build Triggers
Trigger on file changes
Specify the files to watch in the changeset
using the includes
and excludes
keys. Example skips builds for any markdown
files:
workflows:
build-app:
name: Build App
triggering:
events:
- push
when:
changeset:
includes:
- '.' # default value '.'
excludes:
- '**/*.md'
Trigger on push when change in a specific path
workflows:
build-ios:
name: Build iOS
triggering:
events:
- push
when:
changeset:
includes:
- 'iOS/'
Trigger event using when
condition
workflows:
build:
name: Build on PR update
triggering:
events:
- pull_request
when:
condition: not event.pull_request.draft
Scripts
Using multiline scripts
scripts:
- echo "single line script"
- name: Flutter test
script: flutter test
ignore_failure: true
- | # use pipe to write a script in multiple lines.
#!/usr/bin/env python3
print('Multiline python script')
Build Versioning
Flutter
Increment build number and build name:
--build-name=1.0.$PROJECT_BUILD_NUMBER \
--build-number=$PROJECT_BUILD_NUMBER
Native iOS
set -e
set -x
cd $CM_BUILD_DIR/ios
agvtool new-version -all $(($BUILD_NUMBER + 1))
Get the latest build number from App Store
LATEST_BUILD=$(get-latest-app-store-build-number "$APP_STORE_APPLE_ID")
agvtool new-version -all $(($LATEST_BUILD + 1))
Get the latest build number from App Store or TestFlight
LATEST_BUILD=$(app-store-connect get-latest-build-number "$APP_STORE_APPLE_ID")
agvtool new-version -all $(($LATEST_BUILD + 1))
Get the latest build number from TestFlight
LATEST_BUILD=$(app-store-connect get-latest-testflight-build-number "$APP_STORE_APPLE_ID")
agvtool new-version -all $(($LATEST_BUILD + 1))
Artifacts & Publishing
Artifacts
All paths are relative to the clone directory, but absolute paths are supported as well. There are also environment variables for artifact patterns.
artifacts:
- build/**/outputs/apk/**/*.apk # path from root dir
- subfolder_name/build/**/outputs/apk/**/*.apk # path from subdir
- build/**/outputs/**/*.aab
- build/**/outputs/**/mapping.txt
- build/ios/ipa/*.ipa
- build/macos/**/*.pkg
- /tmp/xcodebuild_logs/*.log
- flutter_drive.log
- $HOME/Library/Developer/Xcode/DerivedData/**/Build/**/*.dSYM
Publishing
Codemagic has a number of integrations for publishing, but you can also publish elsewhere with custom scripts.
Note that the publishing scripts are run by default regardless of the build status. You can specify additional conditions with if statements.
publishing:
email:
recipients:
- name@example.com
scripts:
name: Check for apk
script: |
apkPath=$(find build -name "*.apk" | head -1)
if [[ -z ${apkPath} ]]
then
echo "No .apk were found"
else
echo "Publishing .apk artifacts"
fi
Report build status
scripts:
- name: Report build start
script: # build started
. . .
- name: Build finished successfully
script: touch ~/SUCCESS
publishing:
scripts:
- name: Report build status
script: |
if [ -a "~/SUCCESS" ] ; then
# build successful
else
# build failed
fi