CI/CD with Codemagic: Workflows and Triggers
CI/CD with Codemagic: Workflows and Triggers
Codemagic is a cloud-based CI/CD platform purpose-built for Flutter and mobile applications. Rather than wrestling with generic CI tools, Codemagic understands Flutter's build system out of the box — it handles Flutter version management, platform-specific signing, and direct publication to Google Play and the App Store without additional scripting. In this lesson you will learn how to define repeatable, automated build pipelines using both the declarative codemagic.yaml file and the GUI Workflow Editor.
The codemagic.yaml File
The preferred way to configure Codemagic is to place a codemagic.yaml file in the root of your repository. This approach is version-controlled, reviewable in pull requests, and can define multiple independent workflows in a single file. Each top-level key under workflows is one named pipeline.
Minimal codemagic.yaml skeleton
# codemagic.yaml — place in repo root
workflows:
android-release:
name: Android Release
max_build_duration: 60 # minutes; build cancelled if exceeded
environment:
flutter: stable # or a specific version like 3.22.0
android_signing:
- my_keystore # references a code signing identity stored in Codemagic
triggering:
events:
- tag # run only when a git tag is pushed
tag_patterns:
- pattern: 'v*'
include: true
scripts:
- name: Get dependencies
script: flutter pub get
- name: Run tests
script: flutter test
- name: Build release APK
script: |
flutter build apk --release \
--build-name=$PROJECT_BUILD_NUMBER \
--build-number=$BUILD_NUMBER
artifacts:
- build/**/outputs/**/*.apk
publishing:
google_play:
credentials: $GPLAY_SERVICE_ACCOUNT_JSON
track: internal
codemagic.yaml file is loaded at build time from the commit being built. This means changes to the pipeline take effect as soon as they land on the target branch — no manual re-configuration in the Codemagic dashboard is needed.Triggering Builds: Events and Patterns
The triggering block decides when a workflow runs. Codemagic supports five core trigger events:
- push — every commit pushed to matched branches
- pull_request — when a PR is opened or its head branch receives new commits
- tag — when a git tag is pushed (ideal for release builds)
- scheduled — cron-based nightly or weekly runs
- manual — triggered only from the Codemagic dashboard or API
Branch and tag patterns use glob syntax. You can combine include: true and include: false entries to whitelist or blacklist specific refs:
Branch and tag pattern examples
triggering:
events:
- push
- pull_request
branch_patterns:
- pattern: 'main'
include: true
source: true # the source branch of a PR
- pattern: 'release/*'
include: true
- pattern: 'wip/*'
include: false # never build work-in-progress branches
tag_patterns:
- pattern: 'v[0-9]*.[0-9]*.[0-9]*' # semver tags like v1.4.2
include: true
cancel_previous_builds: true # avoid queuing duplicate builds
Managing Signing Identities in Codemagic's Secure Storage
Code signing credentials — Android keystores, iOS certificates, and provisioning profiles — must never be committed to your repository. Codemagic provides Secure Storage (encrypted at rest, injected as environment variables or files at build time) via two mechanisms:
- Environment variable groups — store base64-encoded secrets or plain API tokens; referenced in
codemagic.yamlwith thegroupskey underenvironment.vars. - Code Signing Identities (Android) — upload a
.jksor.keystorefile through the Codemagic dashboard; reference its alias underandroid_signing. Codemagic sets theCM_KEYSTORE,CM_KEY_ALIAS,CM_KEY_PASSWORD, andCM_KEYSTORE_PASSWORDenvironment variables automatically. - iOS Automatic Signing — connect your Apple Developer account once in Codemagic; it handles certificate and provisioning profile renewal. Reference the bundle ID under
ios_signing.
Android signing wired up in codemagic.yaml
workflows:
android-production:
name: Android Production
environment:
flutter: stable
android_signing:
- my_production_keystore # alias set in Codemagic dashboard
groups:
- google_play_credentials # env var group containing GPLAY_SERVICE_ACCOUNT_JSON
scripts:
- name: Build release bundle
script: |
flutter build appbundle --release \
--build-name=1.0.$BUILD_NUMBER \
--build-number=$BUILD_NUMBER
artifacts:
- build/**/outputs/**/*.aab
publishing:
google_play:
credentials: $GPLAY_SERVICE_ACCOUNT_JSON
track: production
submit_as_draft: false
codemagic.yaml. The file lives in your public repository. Always reference secrets through Codemagic's Secure Storage environment variables.Publishing Artifacts to Testers Automatically
After a successful build, Codemagic can push artifacts directly to distribution channels without any manual steps:
- Firebase App Distribution — upload APKs/IPAs and notify tester groups instantly.
- Google Play — publish AABs to internal, alpha, beta, or production tracks.
- App Store Connect (TestFlight) — submit IPAs for TestFlight review automatically.
- Email / Slack notifications — alert stakeholders on build success or failure.
Publishing to Firebase App Distribution
publishing:
firebase:
firebase_token: $FIREBASE_TOKEN # from Codemagic Secure Storage
android:
app_id: $FIREBASE_ANDROID_APP_ID
groups:
- qa-team
- beta-testers
artifact_type: apk
email:
recipients:
- dev@example.com
notify:
success: true
failure: true
GUI Workflow Editor vs codemagic.yaml
For teams new to CI/CD, Codemagic's GUI Workflow Editor (available in the dashboard) offers a point-and-click alternative. It writes the same underlying configuration but exposes it through form fields. The trade-off is that GUI workflows are not stored in the repository — they can drift from the codebase. The recommendation is to start with the GUI to learn the options, then export to codemagic.yaml for long-term maintainability.
codemagic.yaml approach from day one in production projects. It gives you a full audit trail via git history, enables peer review of pipeline changes, and lets multiple developers manage the CI configuration the same way they manage application code.Summary
Codemagic brings production-grade CI/CD to Flutter with minimal boilerplate. A codemagic.yaml file in your repository root defines one or more named workflows, each with its own trigger rules (push, tag, PR, schedule), environment (Flutter version, signing identities from Secure Storage), build scripts, and publishing destinations. Keeping secrets out of the repository and using Codemagic's encrypted variable groups is mandatory for secure pipelines. Once configured, every green commit on main or every v* tag can automatically build, sign, and ship your Flutter app to testers or the stores.