Migrating from Codemagic

BuildMagic reads codemagic.yaml directly. Point it at your repository and your existing pipeline runs — you do not rename the file, rewrite your scripts, or restructure your project.

What to do

  1. Add the application. Connect GitHub or GitLab, pick the repository and choose the project type. The project directory is detected automatically, including inside a monorepo.
  2. Copy your variables. This is the step people forget. Codemagic holds your variable groups; BuildMagic starts empty. Recreate them under app → Settings → Environment, keeping the group names your codemagic.yaml references.
  3. Set up signing. Either upload the certificates, profiles and keystores you already have, or connect an App Store Connect API key and let BuildMagic issue them. See Code Signing.
  4. Select the Android keystore for the app under Settings → Code Signing, along with the Google Play service account if you publish there.
  5. Run a build. Variables your configuration reads but that are not set yet are reported before the build starts, so a missing one is named up front.

What carries over unchanged

  • workflows, with name, instance_type and max_build_duration
  • scripts — each named step becomes a build step, running in order and stopping the build on a non-zero exit
  • environment.vars and environment.groups, matched by group name
  • artifacts, including ** globs and absolute paths such as /tmp/xcodebuild_logs/*.log
  • publishing.app_store_connect and publishing.google_play
  • triggering.branch_patterns

Where a file declares one workflow per platform, instance_type decides which runs: anything starting with mac or osx selects an iOS build machine, anything starting with linux selects a container.

Conventions BuildMagic matches

These are the details that make a configuration written for Codemagic behave the same here.

  • Scripts start at the repository root. A step that says cd apps/mobile resolves against the clone directory, not against the detected project directory, so the path does not resolve twice.
  • CM_PROJECT_PATH defaults to . so cd $CM_PROJECT_PATH is harmless at the repository root.
  • The keystore is a file at CM_KEYSTORE_PATH, in place before the first step runs. The usual storeFile=$CM_KEYSTORE_PATH in a generated key.properties works as written.
  • Expo projects are prebuilt automatically when ios/ and android/ are not committed.
  • iOS build numbers come from App Store Connect, so uploads are not rejected for reusing one. See automatic build numbers.

What is different

AreaDifference
Codemagic CLI toolskeychain, xcode-project and app-store-connect are not available. Rewrite those steps, or drop them and let BuildMagic handle signing, build numbers and publishing through its own settings — which is usually fewer lines than the originals.
xcode: version pinRead but not applied: builds use the Xcode in the machine image, currently 26.4.1. The build reports the mismatch in its first lines so a failure caused by the version gap is recognisable. If your project needs a specific version, tell us — the image is ours to change. The same applies to cocoapods, node, java and ruby; flutter is honoured through FVM.
Android version codesNot incremented automatically. iOS build numbers are; the Google Play equivalent is not implemented yet, so manage versionCode in your project or a script.
Variable scopeVariable groups belong to a single application rather than to the team, so two apps can hold different values under the same name without shadowing each other.

Failures worth recognising

These come up often enough on a first migration to be worth naming.

What you seeWhat it usually is
Gradle: Cannot convert '' to FileA variable the configuration expands into a file is not set. The build lists the missing names before it starts — check that line first.
Malformed root json from processReleaseGoogleServicesGOOGLE_SERVICES_JSON is missing, so the decode step wrote an empty file. Add it under the app's Environment tab.
Expo: the module expo is not installedDependencies were installed somewhere other than the app. A repository whose root holds an unrelated npm project is the usual cause; the app is installed in its own directory when it carries its own lockfile.
npm ci can only install packages when ... in syncThe lockfile has drifted from package.json. The build falls back to a resolving install and continues, but it is no longer reproducible — commit an updated lockfile.
A compiler error deep inside a dependencyCheck the first lines of the build for a version mismatch. A project that pins xcode: usually pins it because another version miscompiles something.

For iOS, the full xcodebuild log is collected with the artifacts, so a failure can be examined after the build machine is gone.

Keeping both files

BuildMagic looks for buildmagic.yaml first and codemagic.yaml second, so you can add a buildmagic.yaml to try something different while leaving the original in place. There is also Ignore repository config in the app's settings, which runs the default pipeline instead — useful for comparing your pipeline against ours, or when the committed file belongs to a CI service you are still running in parallel.

You can also edit the configuration from the dashboard without committing anything: Settings → buildmagic.yaml creates a local override, and discarding it returns to the repository file.