CI/CD setup for mobile apps (iOS/Android)

Releasing a mobile app stalls when builds and signing keys depend on a single engineer, and every release turns into a manual operation. We provide turnkey CI/CD setup for mobile apps: we build the pipeline, automate builds, test channels, and store publishing, and hand the team clear release procedures. Update delivery time is reduced several times over, and release no longer depends on one person.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

Mobile app CI/CD: where the release breaks

As long as a mobile app release is built on a single engineer's machine, the release depends on their environment.

Dependency versions, environment variables, certificates, and signing profiles live locally — on another computer, the same code branch builds differently or does not build at all.

Build reproducibility in such a scheme lasts exactly until the first vacation or workstation change.

Build signing errors are the most expensive spot. The signing key sits in the developer's keychain, no one tracks the certificate expiration date, and the profile is tied to a specific app identifier and distribution type.

A lost key or expired certificate cannot be restored from memory: you have to reissue certificates and rebuild an already tested release.

Manual release builds stretch out the release: building, signing, uploading to the store, and distributing test versions are separate steps, each triggered by a person.

A long app release means tester feedback arrives days later, and an urgent fix requires the same manual operations as a planned release.

Mobile app CI/CD addresses exactly these points: configuration and keys are moved into managed storage, the build runs in a clean environment on every code change, and the test version goes to the team automatically. Below is how this works in practice.

What changes after moving builds to a pipeline

While the build lives on a developer's machine, the time from edit to verifiable artifact depends on whose machine it runs on: one person has a warm local cache, configured signing profiles, matching dependencies — another person sees the same code fail.

A pipeline removes this lottery: the build runs in an immutable environment, dependencies are cached, independent steps are parallelized, and the release cycle fits into tens of minutes instead of hours.

Automation scripts like Fastlane turn signing, building, and artifact upload into a versioned description — the process stops depending on a person who "knows how it should be done." When a release takes half an hour instead of half a day, the team moves from monthly releases to weekly ones, and a fix reaches users on the day it is found, not in the next cycle.

Automated code checks are enabled by the same run: static analysis, linters, unit and UI tests on real devices, build size control.

A build with red status physically does not reach testers — the defect is caught at commit time, when the cost of the fix is one line, not an urgent fix with expedited store review.

Build stability becomes measurable: success rate, time to green status, number of reruns due to flaky tests. Next comes early defect detection by class: signing regressions, startup crashes, memory leaks, rendering slowdowns on low-end devices.

Each such class is closed before release, and the version that goes to the store does not need to be chased with patches.

Mobile release build options: cloud, self-hosted agents, hybrid

The choice of build scheme is determined by two factors: where the signing keys physically reside and how predictable the build queue is. A cloud farm provides ready machines for both platforms and does not require an engineer on call, but build secrets go to a third party.

Self-hosted agents keep keys inside the perimeter and cache dependencies between runs, but the machine fleet must be updated and scaled on your own.

A hybrid setup separates tasks: tests and static checks run in the cloud, while final build and signing run on an isolated agent without external access. This way signing isolation becomes a network property, not a promise: the key never leaves the perimeter at any step.

Option When it fits Limitations
Cloud build Both platforms at once, infrequent releases, no available engineers Signing keys are stored on an external site, limits on build duration
Self-hosted build agents Strict access requirements, frequent releases, a heavy test suite Requires a machine fleet, update policy, redundancy, and downtime monitoring
Hybrid build setup Keys cannot be moved outside, but speed and rented capacity are needed Two perimeters, your own gateway between them, review of access rules

The practical criterion is simple: if the key cannot be moved outside the perimeter — hybrid; if releases are infrequent and the team is small — cloud; if there are many checks and they are heavy — self-hosted agents with a shared cache.

The amount of setup maintenance grows with the number of environments, not projects, so a mixed scheme is introduced together with an access policy for build secrets from the start.

Implementation stages: from build audit to handover of policies

Building a mobile app is not one step but a chain: dependencies, signing, tests, sending to testing channels and stores. If even one link depends on a person, the release becomes an event with manual preparation rather than a routine operation. That is why work proceeds sequentially, from inventory to document handover.

  1. Build and access audit. We look at where and on which machine the app is built, which certificates and profiles are used, who stores keys and store accounts.

    We measure the current time from commit to a build that can be installed on a test device — this is the baseline for verifying the result.

  2. Design of the build setup. We determine which scenarios the team needs: a build on every commit, regular builds with tests, release builds by tag. We define where artifacts live, how environments are separated, who has rights to what, and how signing secrets are stored.

  3. Configuration of build scenarios. We configure the build and tests, dependency cache, version numbering, automatic signing, and generation of installable files.

    We separately verify that signing does not break when the environment changes and that the build is reproducible from a clean state.

  4. Delivery automation. We tie publication to testing channels and sending builds to stores to scenarios, and result notifications to the team's work channels. It becomes possible to roll out a version without manual steps and just as quickly roll back to the previous one.

  5. Validation on a real release. We run the new setup on a live release: from the first build to the version appearing for testers and in the store. We review stage times, analyze failures, and remove manual crutches left after migration.

  6. Handover of policies and training. We give the team documentation on scenarios, instructions on access, certificates, and build recovery, and hold a walkthrough with developers and release managers. After that, releases proceed according to the described process without our involvement.

Build setup, signing keys, and release policies

We hand over not a "script that builds the app" but a set of settings and documents by which your team releases on its own. Everything lives in your repository and secrets storage — a new engineer goes from code change to publication without messaging us.

  • Build configuration for iOS and Android: steps, dependencies, environment variables. The build is reproduced with one command on a clean machine.
  • Build setup diagram: where agents live, how dependencies are cached, what runs on every branch change, and what runs only on a release tag.
  • Signing key storage: private keys and certificates are placed in secure storage, access is granted by roles, and they do not end up in the repository or build artifacts.
  • Environment access policies: it is fixed who runs builds, who publishes to app stores, who sees secrets, and who rotates them.
  • Release policy: version numbering, build number increment procedure, pre-publication checklist, and the list of approvals without which a release does not go out.
  • Rollback instructions: how to return the previous build, stop a staged rollout, and withdraw a release from the store.
  • Maintenance map: extension points of the setup, known limitations, contacts, and a schedule of planned updates.

The policies are described in the language of processes, not a specific tool: you can change the build tool or environment without rewriting the rules. During handover, we go through each item together with your engineer and answer questions along the way.

How the release stopped depending on one engineer

Before the changes, the mobile app release depended on one engineer: they were the only one who knew the sequence of steps — build the build for the required configuration, sign it, send it for distribution.

A release took a day and a half, the build success rate hovered around 55%, and before each release more than thirty operations were performed manually. This person's vacation or sick leave stopped the release entirely.

What we changed

We moved the build into a declarative pipeline inside the repository: environment configurations are described as code, signing keys are stored in secure storage and injected at the build stage via fastlane, and dependencies are cached between runs.

The same set of steps runs for debug and release builds — the only difference is the configuration profile. The only manual step left is confirming submission to the app store.

A release now takes 40 minutes instead of a day and a half, the build success rate has grown to 92%, and manual operations are down to four.

A separate class of failures due to environment mismatch is gone: a build that passed checks no longer breaks on the distributor side because of a different tool version or a missing certificate. Rolling back to the previous release is restarting the pipeline at the required tag.

Knowledge no longer lives in one person's head: the release procedure is described in the repository and a short policy document, and a new engineer performs their first release independently in the second week.

Release resilience no longer depends on who is online: the pipeline is reproducible and launched from the interface, without access to someone else's workstation.

How a build pipeline differs from automated tests on devices

These are two different layers, and they should not be mixed in one definition. The build pipeline is responsible for turning a commit into a signed artifact: dependency resolution, compilation, signing of the release configuration, build number assignment, and upload to storage.

Automated tests on devices begin where the artifact has already been built — their job is to verify app behavior on a specific platform.

Inside the build pipeline, what matters is not the fact of running but predictability: the same result when rebuilding the same commit, dependency cache, separate signing profiles for internal and release builds, and clear version numbering.

Then the time from code submission to a ready artifact is measured in minutes, not in messages asking "whose build succeeded."

Automated tests on devices are a separate layer with its own cost. Emulators and real devices catch different things: an emulator is fast and cheap in parallel runs but does not reproduce the camera, sensors, biometrics, and vendor skin specifics.

That is why critical scenarios go to a device farm — a set of real models where installation, update over the previous version, background operation, and behavior on a weak network are checked.

The separation of verification layers looks like this: for every commit — a build and quick checks on emulators; for the release branch and before publication — a full run on the device farm. This way expensive machine time is not spent on what is caught in seconds. What you specifically need depends on the number of platforms and models in support.

Common concerns: signing, keys, and test builds

Build signing, keys, and app store access are three places where automation usually gets stuck: without them, the build pipeline either fails validation or remains a manual operation of one person. Below are questions asked before starting and how we address them.

Where are certificates and signing keys stored?

In secure secrets storage with role-based access and an operations log. Signing is moved into a separate step, keys are not stored in the repository and are not transmitted in plaintext, and the rotation and revocation procedure is described in advance.

We establish the division of responsibility up front: we handle the technical part and signing reproducibility, you own the accounts and final release approval.

Is it necessary to maintain your own servers?

No. The build runs on managed build agents that scale for peak load before a release — no own hardware is needed. If internal policy requires an isolated setup, we deploy the build in your infrastructure with the same steps.

Everything builds manually for us — will the process have to be redone?

First we describe what already works and migrate steps one by one without stopping releases. In parallel, we enable test build automation and critical defect checks, while manual release remains as a fallback until the new process proves stable across several releases.

Do you need your own device farm?

For a basic set — installation, update, login, payment, notifications — emulators and cloud devices are enough. A dedicated farm is justified if there are requirements for specific models, older OS versions, or operation in a closed network.

Let's discuss the task: what we will clarify about your release scheme

To come back with an estimate and work plan for your build and release setup, rather than general considerations, we need a short set of inputs.

Nothing needs to be prepared in advance — what already exists in the repository, on build machines, and in app store accounts is enough. Based on this data, we will describe the target scheme, estimate the scope of work, and show where time is lost in the current process.

  • Branching scheme and release cycle: how often builds go out, who creates the tag, what is considered a release branch, whether there is a separate setup for urgent fixes.
  • Build environments: where the project is built now — on engineers' workstations or dedicated agents, whether builds for both platforms are needed in parallel.
  • Signing and keys: how signing keys and device profiles are stored, who has access to them, and how they are passed into the build environment. This is the most common point of failure during automation, and we address it first.
  • Delivery channels: test builds for the internal team and external testers, publication to stores, staged rollout, and the ability to roll back a published version.
  • Environments and parameters: how many environments there are, how they differ, how service addresses and third-party integration keys are currently set, and what is already moved into variables.
  • Manual steps: what exactly is still done by hand — versioning, building release notes, merging artifacts, sending for review.

Separately, name the requirements that have emerged from practice: artifact retention period, access restrictions, mandatory checks before rollout.

Describe the task and send a link to the repository — we will come back with an estimate and work plan for your build and release setup.