10 min readEngineering
CI/CD when AI writes the code: a practical guide from one repo to a whole company
What to automate first, when to add more, and how to choose between Codemagic and Fastlane with GitHub Actions, with real build times and prices.
Most code I review this year was written, at least in part, by an AI tool. That's not a complaint. It's faster, and a lot of it is good. But it changes what a CI/CD pipeline is for. When people wrote every line, the pipeline was a safety net. Now it's often the only thing that reads every line before it ships.
This guide is what I'd set up for a team today, from a weekend project to a company with a dozen services and two mobile apps. It comes from running pipelines on real products, including a Flutter app with GitHub Actions and Codemagic, and a React Native monorepo with GitHub Actions and Fastlane. The build times and prices below are real, measured or checked in October 2026.
What AI changed about CI/CD
The basics haven't moved: check the code, build it, ship it the same way every time. What changed is the shape of the work coming in.
- More pull requests, and bigger onesAn agent can open five PRs before lunch. Each one triggers your checks, so slow or expensive checks now cost real money and real waiting.
- Code nobody fully readAI output is confident even when it's wrong. A test suite that runs on every PR is the reviewer that never skims.
- Secrets in the wrong placeTools happily paste an API key into a config file to make something work. Secret scanning on every push is no longer optional. I've written about finding keys in your front end too.
- Agents can run your commandsIf an assistant can push to a branch, it can edit a workflow file. Your pipeline's permissions are now part of your security model.
So the goal is the same as ever, with one addition: the pipeline should catch what a tired human or a confident model misses, and it should be hard to misuse even by someone, or something, with write access.
Start simple: the first workflow every project needs
For a new or small project, you need exactly one workflow and one setting.
The workflow runs on every pull request and does five things: install, lint, type check, test, build. If your project has no tests yet, start with the other four. A build that fails in CI is far cheaper than one that fails on launch day.
name: PR checks
on:
pull_request:
concurrency:
group: pr-${{ github.ref }}
cancel-in-progress: true
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run lint
- run: npx tsc --noEmit
- run: npm test
- run: npm run buildThe setting is branch protection: nothing merges into main until this check passes. Without it, the workflow is a suggestion.
Then add deploy on merge. When a PR lands on main, build and deploy. Most hosting platforms (Vercel, Netlify, Cloudflare) do this for you, and for a small project that's the right call. Don't build what your host already gives you.
That's it for stage one. I'd add a free secret scanner like gitleaks as a second job, and stop there. Resist the urge to build the pipeline you'll need in two years.
When to add more
Add pieces when a real problem shows up, not before. These are the signals I watch for:
- Real users depend on itNow a bad deploy costs something. Split dev and production.
- CI takes longer than a coffeeAdd path filters and caching before you buy bigger machines.
- More than one service in the repoA change to the web app shouldn't redeploy the API.
- Someone deployed the wrong thing to productionYou need a gate, not a reminder.
- You can't say which commit is liveYou need tags or release records.
- A cloud key lives in your CI secretsPlan to replace it with short-lived credentials.
The complex setup: what a grown-up pipeline has
When a product has paying users, several services and more than a couple of people (or agents) pushing code, these are the layers I add, roughly in this order.
- Path filters and concurrencyEach workflow runs only when its own folder changes, and a newer push cancels an older run of the same dev deploy. In a busy repo this alone can halve your CI bill. Be careful with cancelling production deploys, though; a half-finished deploy can leave things in a mixed state.
- Dev is automatic, production is a decisionMerges deploy to a dev environment on their own. Production is a separate workflow that only runs by hand, behind a GitHub environment with required reviewers. One codebase I work on goes further: a small script fails CI if anyone adds an automatic trigger to a production workflow. That kind of rule matters more now that agents edit YAML.
- Short-lived credentialsGitHub can mint a short-lived token for each run (OIDC), and AWS, Google Cloud and Azure all accept it. Nothing sits in your secrets to leak or rotate. A long-lived cloud key in CI is the single riskiest thing I find in audits.
- Rollback you've actually runA workflow that redeploys the previous version, tested before you need it. The worst time to write a rollback is during an outage.
- Know what's liveTag every release with the commit it came from, and write release notes from merged PR titles. When a tester says "it's broken in the latest build", you can answer "which one" in seconds.
- Turn team rules into checksIf there's a rule like "no production IDs hard-coded in the app", write a script that fails the build when it's broken. People forget rules. AI tools never knew them. A check holds for both.
- Drift checksA scheduled job that compares what's deployed with what's in the repo. Someone always changes a setting in a console by hand.
- Watch the trigger itselfThis is the one most teams miss. On one project, the mobile build service stopped receiving push events from GitHub. Nothing failed, so nothing alerted. Testers just quietly stopped getting builds for about two weeks. Now a simple rule closes the gap: if a merge touches the app and no new build tag appears within an hour, someone hears about it.
Mobile apps: Codemagic or Fastlane with GitHub Actions?
Mobile is where CI/CD gets expensive and fiddly, because iOS needs a Mac and both stores need signing. There are two common paths:
- CodemagicA CI service built for mobile, configured with one
codemagic.yamlin your repo. It handles signing, store uploads and Firebase App Distribution for you. - Fastlane with GitHub ActionsFastlane is a free, open-source tool that scripts builds, signing and uploads. You run it on GitHub's machines.
Codemagic doesn't use GitHub Actions at all. GitHub notifies it on every push, it reads codemagic.yaml from that commit and builds on its own machines. That's also why its trigger can break silently, as in the story above.
Real build times
From a Flutter app on Codemagic, measured from merge to finished, uploaded build:
- Android release build to Firebase App Distribution: 28 to 29 minutes, across four runs.
- iOS build to TestFlight on an M2 Mac: about 27 minutes.
GitHub's standard Mac runners are older M1 machines, so the same iOS build will take longer there. I haven't timed this exact app on them, so treat 35 to 50 minutes as an estimate; caching makes a big difference.
Real prices (checked October 2026)
- Codemagic, pay as you go: Linux $0.045 a minute, Mac mini M2 $0.095, Mac mini M4 $0.114. A fixed plan with unlimited M2 builds is $3,990 a year.
- GitHub Actions, private repos: Linux $0.006 a minute, standard Mac $0.062. The Team plan includes 3,000 minutes a month, shared by every workflow in the organisation, and Mac minutes draw that allowance down much faster than Linux ones.
Per build, that works out to:
- AndroidAbout $1.26 on Codemagic against about $0.18 to $0.27 on GitHub Actions. GitHub is roughly five times cheaper, always.
- iOSAbout $2.57 on Codemagic against about $2.20 to $3.10 on GitHub Actions. It breaks even when the GitHub build takes about 41 minutes, which is right inside that estimate.
For thirty Android and thirty iOS builds a month, that's around $115 on Codemagic and $70 to $100 on GitHub Actions. The difference is real but small. For most teams, setup time and upkeep matter more than price.
How to choose
Choose Codemagic if:
- The app is in Flutter. Codemagic was built for it, and its machine images keep the Flutter, Xcode and Android tools current for you.
- Nobody on the team wants to own iOS signing. Codemagic manages certificates and profiles through an App Store Connect key.
- iOS build speed matters more than a few dollars a month.
- You don't have a spare Mac.
Choose Fastlane with GitHub Actions if:
- The rest of your CI is already on GitHub Actions and you want one place to look.
- Android builds are frequent. That's where the savings are.
- Someone on the team knows Fastlane, or Ruby, and is happy to own it. Signing with Fastlane
matchworks well once it's set up, but setting it up is a project. - You have a Mac you can run as a self-hosted runner. GitHub doesn't charge for self-hosted minutes, which makes iOS builds nearly free.
A mixed setup (Android on GitHub Actions, iOS on Codemagic) is the cheapest on paper. In practice, two pipelines mean two dashboards, two signing setups and two places tester builds come from. I'd only split if Android volume is high enough to justify it.
Whichever you choose, the same rules apply: build numbers should come from the store, not a file someone edits by hand. Production uploads should go to internal testing first, never straight to users. And every build should check it was signed with the right key before it uploads anything. I covered the Fastlane side in more detail in how I automated store releases for a React Native app.
Rules for pipelines in the AI era
Here's the short list I now apply to every project, on top of the stages above:
- Protect workflow filesPut
.github/workflows/(andcodemagic.yaml) under CODEOWNERS, so a change to how code ships always gets a human review. - Pin third-party actionsUse a version or, better, a commit SHA. An action that tracks
@masterruns whatever its owner pushes next. - Give agents the rules in writingA short
AGENTS.mdorCLAUDE.mdsaying "production is manual, never add secrets to workflows" helps. A check that enforces it helps more. - Make checks fastIf PR checks take 25 minutes, people and agents start working around them. Cache dependencies and split slow suites.
- Fail loudly, in plain languageA check that says "this IPA would upload to a different app than intended" saves an hour of log reading. AI tools fix clear errors well too.
- Measure the bill monthlyMore PRs mean more runs. Check your CI usage page once a month, before it surprises you.
Where to start, by stage
- Solo or side projectPR checks, branch protection, deploy through your host. One afternoon.
- Small team with usersAdd secret scanning, separate dev and production, a manual production deploy with approval, and path filters.
- Growing product with mobile appsAdd short-lived credentials, release tags and notes, a tested rollback, and pick one mobile path using the rules above.
- Many services and teamsAdd rule-checking scripts, drift checks, monitoring of the triggers themselves, and a monthly cost review.
A good pipeline isn't the one with the most workflows. It's the one where a bad change, from a person or a model, gets stopped before users see it, and where shipping a good change takes one merge.
If your app was built quickly with AI tools and you're not sure what its pipeline is or isn't catching, that's the first thing I look at in an audit.
Questions people ask
- What is the first CI/CD workflow a new project should have?
- One workflow that runs on every pull request: install, lint, type check, test and build. Then protect the main branch so nothing merges until it passes. Everything else can wait.
- Is Codemagic or Fastlane with GitHub Actions cheaper?
- For Android, GitHub Actions is about five times cheaper per build ($0.006 a minute against $0.045 in October 2026). For iOS they come out roughly even, because Codemagic's newer Macs finish faster. Most teams should choose on setup time and upkeep, not price.
- Can I let an AI agent change my CI/CD workflows?
- Yes, but review workflow changes like you would review a change to production access. Put workflow files under CODEOWNERS, keep production deploys manual, and give pipelines short-lived credentials so a bad change can't leak a long-lived key.
- Do I need separate pipelines for dev and production?
- Once real users depend on the product, yes. Let merges deploy to dev automatically, and make production a manual run behind an approval, so it is always a decision and never a side effect.