Environment Variables
Environment variables pass configuration values and secrets to your builds. They are available as ordinary shell environment variables in every pipeline step, whether the step comes from the default pipeline or from your own configuration file.
Adding variables
- Open the application and go to Settings → Environment.
- Create a variable group — a named set of variables, such as
androidorfirebase. - Add variables to the group as name/value pairs.
- Mark a variable secret if its value should not be displayed back to you in the dashboard.
Scope: variables belong to one app
A variable group belongs to the application it was created in. Another app in the same team does not see it, does not list it, and cannot use it. This matters when several apps use variables with the same names — a GOOGLE_SERVICES_JSON per app, for instance — and each one needs its own value.
Groups are matched to a workflow by name. A configuration file that declares environment.groups: [android] pulls in the group named android from that app.
How values are stored
Every value is encrypted at rest with AES-256-GCM, whether or not it is marked secret. The secret flag controls one thing only: whether the dashboard shows the value back to you after saving.
| Shown in the dashboard | Stored | |
|---|---|---|
| Plain | Value is visible and editable | Encrypted |
| Secret | Masked as ********; can be replaced, not read back | Encrypted |
Values are decrypted only when a build needs them, and injected into that build's environment. Note that a value your own script echoes will appear in the build log — the secret flag does not mask log output.
Variables a configuration expects but you have not set
Before a build starts, BuildMagic reads the variables your configuration file references and warns about any that are not defined:
Warning: this configuration reads variables that are not set in BuildMagic: GOOGLE_SERVICES_JSON
Add them under the app's Environment tab, or the steps using them may fail.This is a warning, not a block — a script may well handle a missing variable itself. It exists because a script like echo $GOOGLE_SERVICES_JSON | base64 --decode > google-services.json writes an empty file when the variable is absent, and the build then fails much later with something that looks unrelated.
Built-in variables
BuildMagic provides these automatically. You do not set them; they are populated from your app, workflow and signing configuration.
Build context
| Variable | Description |
|---|---|
CM_BUILD_ID | Unique identifier for the current build. |
CM_BRANCH | The Git branch being built. |
CM_COMMIT | The commit SHA being built. |
CM_REPO_URL | The repository clone URL. |
CM_GIT_PROVIDER | github or gitlab. |
CM_APP_NAME | The application name as configured in BuildMagic. |
CM_WORKFLOW | The workflow being executed. |
CM_PROJECT_TYPE | flutter, flutter_android, ios_native, android_native, react_native or react_native_android. |
CM_PLATFORM | ios or android. |
CM_PROJECT_PATH | The project directory relative to the repository root, detected automatically. Empty (defaulting to .) when the project sits at the root. |
PROJECT_ROOT | Absolute path to the detected project directory inside the build machine. |
iOS signing and publishing
Present when the corresponding material is configured.
| Variable | Description |
|---|---|
CM_BUNDLE_ID | The iOS bundle identifier. |
CM_CERTIFICATE_URL | Download URL for the distribution certificate, with CM_CERTIFICATE_NAME and CM_CERTIFICATE_PASSWORD. |
CM_PROVISIONING_PROFILE_URL | Download URL for the profile, with CM_PROVISIONING_PROFILE_NAME. |
CM_EXTRA_PROFILE_COUNT | How many additional extension profiles were matched, exposed as CM_EXTRA_PROFILE_URL_1 and so on. |
CM_ASC_KEY_URL | App Store Connect API key, with CM_ASC_KEY_ID and CM_ASC_ISSUER_ID. |
Android signing and publishing
| Variable | Description |
|---|---|
CM_KEYSTORE_PATH | Path to the keystore on the build machine. It is placed there before any step runs, so a configuration written for Codemagic finds it where it expects. |
CM_KEYSTORE_PASSWORD | Keystore password, with CM_KEY_ALIAS, CM_KEY_PASSWORD and CM_KEYSTORE_NAME. |
CM_KEYSTORE_URL | Download URL for the keystore. Prefer CM_KEYSTORE_PATH; this exists for scripts that fetch it themselves. |
CM_PACKAGE_NAME | The Android application id used when publishing. |
CM_GOOGLE_PLAY_KEY_URL | Google Play service account key, with CM_GOOGLE_PLAY_TRACK. |
Variables you can set to change behaviour
| Variable | Effect |
|---|---|
CM_AUTO_BUILD_NUMBER | Set to false to stop resolving the iOS build number from App Store Connect and keep whatever the project carries. |
CM_FLUTTER_VERSION | Pin the Flutter SDK version used by the build. |
CM_DOCKER_IMAGE | Use a different container image for Android builds. |
GOOGLE_SERVICES_JSON | Base64 (or raw JSON) of google-services.json. Written into the right place for your project layout before the Android build runs, for projects that keep it out of version control. |
Common uses
FIREBASE_TOKEN = your-firebase-ci-token (secret)
SENTRY_AUTH_TOKEN = your-auth-token (secret)
GOOGLE_MAPS_API_KEY = AIza... (secret)
GOOGLE_SERVICES_JSON = ewogICJwcm9qZWN0X2luZm8i... (secret)
APP_ENVIRONMENT = productionReference them in a script step like any other environment variable:
scripts:
- name: Deploy to Firebase
script: |
firebase appdistribution:distribute build/app.apk \
--app $FIREBASE_APP_ID \
--token $FIREBASE_TOKEN