DevOps · Android · CI/CD · AI agents

The Android DevOps Toolbox: CI/CD, Distribution, Install Guides and the Setup Behind AI Agents (MCP)

Khairul Alam·October 2026·~22 min read
DevOpsCI/CDGitHub ActionsCircleCIBitriseJenkinsfastlaneMCP

Every Android team eventually discovers that the hardest part of shipping is not the code. It is the machinery around it: the server that builds the app the same way every time, the key that signs it, the pipe that carries it to testers and then to Google Play, and now the AI agents that want access to all of it. I have set this machinery up and kept it alive for years. This is the toolbox I would hand a new engineer: what each tool is, when to choose it, how to install it, and where the official docs live.

The whole post in 60 seconds
  • Android engineers are software engineers, and software includes how it ships. If you cannot read a CI log, rotate a signing secret or explain how your build reaches Play, you depend on someone else for your own release.
  • The pipeline has six stations: source → build and test → quality → distribute → store → observe. Every tool fits one of them.
  • CI servers run your build: GitHub Actions, CircleCI, Bitrise (hosted), Jenkins (self-hosted). Build tools (Gradle, fastlane) do the work inside them. Distribution (Firebase App Distribution, DeployGate, Play tracks) delivers builds to humans.
  • Pick the CI that is closest to where your code already lives, and keep the real logic in Gradle or fastlane so you can move CI later.
  • MCP (Model Context Protocol) is the plug that lets AI tools use your GitHub, Firebase and tickets. Treat it as production access: least privilege, read-only first, secrets in environment variables, a human approves writes.
Contents
  1. Why Android engineers need DevOps
  2. The map: where each tool sits
  3. CI servers: GitHub Actions, CircleCI, Bitrise, Jenkins
  4. Which CI should you pick?
  5. Build tooling: Gradle, fastlane, Gradle Play Publisher
  6. Distribution: Firebase App Distribution and DeployGate
  7. Google Play, the API and signing
  8. Quality gates, observability, Docker and secrets
  9. The AI era, part 1: MCP setup
  10. The AI era, part 2: agents in your pipeline
  11. Day-1 checklist for a new Android repo
  12. Pitfalls I have paid for
  13. Takeaways and glossary

1. Why Android engineers need DevOps

I hear “that is the DevOps team’s job” less often than I used to, and I am glad. Here is why I push every Android engineer to learn the basics:

Analogy: a restaurant cook who never looks at the kitchen layout, the fridge temperature or how plates reach the table can cook well and still make people ill. DevOps is the kitchen. You do not have to run it alone, but you should be able to walk through it.

2. The map: where each tool sits

Source GitHubGitLabBitbucketbranch rulesPR checks Build GitHub ActionsCircleCIBitriseJenkinsGradleunit tests Quality Android LintktlintdetektSonarQubesize budget Distribute Firebase AppDistributionDeployGatefastlaneFirebase CLI Store Play ConsolePlay tracksPlay APIGradle PlayPublisher Observe CrashlyticsAndroid vitalsPlay reportsSlack alerts Across every stationkeystore · secrets · caches · build images · permissions
Find the station first, then pick the tool. Most “which tool?” debates are really about two neighbouring stations.

3. CI servers: GitHub Actions, CircleCI, Bitrise, Jenkins

A CI server watches your repository, starts a clean machine for each change, runs your commands and reports the result. All four tools below do that. They differ in where they run, how you pay, and how much you maintain.

3.1 GitHub Actions

What: CI built into GitHub. Workflows are YAML files in .github/workflows/. Pick it when your code is already on GitHub and you want the shortest path. Install: nothing to install for hosted runners. Commit a workflow file, then add secrets in Settings → Secrets and variables → Actions. For self-hosted runners, follow the “Add runner” page in the repository settings, which gives you a download and a registration token.

name: android-ci
on:
  pull_request:
  push:
    branches: [main, "release/**"]

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: 17            # match what your Android Gradle Plugin requires
      - uses: gradle/actions/setup-gradle@v4   # caches Gradle for you
      - name: Lint and unit tests
        run: ./gradlew lintDebug testDebugUnitTest
      - name: Build release bundle
        env:
          KEYSTORE_B64: ${{ secrets.KEYSTORE_B64 }}
          KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
          KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
          KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
        run: |
          echo "$KEYSTORE_B64" | base64 -d > "$RUNNER_TEMP/release.jks"
          ./gradlew bundleRelease -Pandroid.injected.signing.store.file="$RUNNER_TEMP/release.jks" \
            -Pandroid.injected.signing.store.password="$KEYSTORE_PASSWORD" \
            -Pandroid.injected.signing.key.alias="$KEY_ALIAS" \
            -Pandroid.injected.signing.key.password="$KEY_PASSWORD"
      - uses: actions/upload-artifact@v4
        with:
          name: release-aab
          path: app/build/outputs/bundle/release/*.aab

Check the Marketplace for the current major version of each action before you copy this. Useful habits: concurrency cancels stale runs, an environment with required reviewers protects the job that publishes, and permissions: at the top of the file keeps the default token read-only.

Official docs: docs.github.com/actions

3.2 CircleCI

What: a hosted CI service (self-hosted runners also exist) configured in .circleci/config.yml. Pick it when you want strong caching, parallelism and test splitting, or already use it elsewhere in the company. Install: sign in with GitHub or Bitbucket, choose Projects → Set Up Project, and CircleCI adds a deploy key and a webhook. Put shared secrets in an organization context so only chosen jobs can read them.

version: 2.1

orbs:
  android: circleci/android@<version>     # check the orb registry for current version and names

jobs:
  build:
    executor:
      name: android/android_docker
      tag: <image-tag>                     # a cimg/android tag
    steps:
      - checkout
      - android/restore_gradle_cache
      - run: ./gradlew lintDebug testDebugUnitTest bundleRelease
      - android/save_gradle_cache
      - store_artifacts:
          path: app/build/outputs/bundle/release

workflows:
  ci:
    jobs:
      - build:
          context: android-release          # secrets live here, not in the file

The convenience images live under cimg/android on Docker Hub. The orb’s command and executor names change over time, so copy them from the registry page rather than from memory (including mine). Official docs: circleci.com/docs

3.3 Bitrise

What: a hosted CI/CD service built for mobile. You compose a workflow from steps in a web editor or in bitrise.yml. Pick it when the team wants mobile-aware defaults and does not want to write much YAML: Android SDK images, code signing handling and a large step library are built in. Install: sign in, Add new app, connect the repository, choose the stack (a Linux Android image), and let Bitrise scan the project. It proposes a starting workflow. Store secrets under Secrets in the workflow editor, and upload the keystore to Code signing.

format_version: "<version>"
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git

workflows:
  primary:
    steps:
      - git-clone@<version>: {}
      - android-unit-test@<version>:
          inputs:
            - variant: debug
      - android-build@<version>:
          inputs:
            - module: app
            - variant: release
            - build_type: aab
      - deploy-to-bitrise-io@<version>: {}

Bitrise also publishes steps for Firebase App Distribution, Google Play and Slack; search the Step Library for the current step ids and inputs. Official docs: devcenter.bitrise.io

3.4 Jenkins

What: the long-standing open-source automation server you run yourself. Pick it when you need full control, builds must stay inside your network, or a large plugin ecosystem and existing company infrastructure matter more than convenience. The cost is operations: upgrades, plugin security, agents and disk are yours.

Install (pick one; follow the official page for your OS):

# Docker, the quickest way to try it (LTS image)
docker run -d --name jenkins -p 8080:8080 -p 50000:50000 \
  -v jenkins_home:/var/jenkins_home jenkins/jenkins:lts-jdk17

# macOS with Homebrew
brew install jenkins-lts && brew services start jenkins-lts

# then open http://localhost:8080 and unlock with the initial admin password
# (printed in the container log, or in the file shown on the unlock page)

Run builds on agents, not on the controller. An Android agent needs a JDK, the Android command-line tools (sdkmanager to install platforms and build-tools), ANDROID_HOME set, and accepted SDK licenses. Baking all of that into a Docker image makes agents disposable.

// Jenkinsfile (declarative)
pipeline {
  agent { label 'android' }
  environment { ANDROID_HOME = '/opt/android-sdk' }
  stages {
    stage('Test')  { steps { sh './gradlew lintDebug testDebugUnitTest' } }
    stage('Build') {
      steps {
        withCredentials([file(credentialsId: 'release-keystore', variable: 'KS')]) {
          sh './gradlew bundleRelease -Pandroid.injected.signing.store.file=$KS'
        }
      }
    }
  }
  post { always { archiveArtifacts artifacts: 'app/build/outputs/**/*.aab', allowEmptyArchive: true } }
}

Official docs: jenkins.io/doc

4. Which CI should you pick?

ToolHostingCost modelStrengthsAndroid fit
GitHub ActionsHosted, self-hosted runners optionalFree minutes then per minute; larger runners cost moreLives next to the code, huge action ecosystem, easy PR checksGood. Linux runners suit most builds; emulator tests need care
CircleCIHosted, self-hosted runners optionalCredits by machine size and timeFast caching, test splitting, flexible executorsGood. Android images and orb are first class
BitriseHosted (self-hosted possible on some plans)Plans by build credits and concurrencyMobile-focused, step library, signing handling, UI editorVery good. Least YAML to start
JenkinsSelf-hostedFree software; you pay for servers and peopleTotal control, plugins, runs inside your networkGood if you maintain agents. More upkeep

Prices and free tiers change, so check each vendor before you decide. My rules of thumb:

5. Build tooling: Gradle, fastlane, Gradle Play Publisher

Gradle

Gradle is the build tool Android already uses, so make CI call it directly. Always run ./gradlew (the wrapper), which pins the Gradle version in the repository, instead of a Gradle installed on the machine. Turn on the build cache and configuration cache where your plugins support them, and use the CI vendor’s Gradle caching so repeated runs skip work. Docs: developer.android.com/studio/build

fastlane

fastlane is a Ruby toolkit that scripts mobile release tasks as lanes: build, sign, upload to Play, upload to Firebase, post to Slack. It is CI-agnostic, which is exactly why I like it.

# install (either one)
brew install fastlane
# or, pinned per project (recommended): add `gem "fastlane"` to a Gemfile, then
bundle install && bundle exec fastlane init   # choose manual setup for Android

# fastlane/Fastfile
default_platform(:android)

platform :android do
  desc "Build the release bundle and push it to Play internal testing"
  lane :internal do
    gradle(task: "bundle", build_type: "Release")
    upload_to_play_store(
      track: "internal",
      aab: lane_context[SharedValues::GRADLE_AAB_OUTPUT_PATH],
      json_key: ENV["PLAY_JSON_KEY_PATH"]
    )
  end

  desc "Send an APK to testers through Firebase App Distribution"
  lane :beta do
    gradle(task: "assemble", build_type: "Release")
    firebase_app_distribution(
      app: ENV["FIREBASE_APP_ID"],
      groups: "qa",
      release_notes: "Build from CI"
    )   # needs: fastlane add_plugin firebase_app_distribution
  end
end

The Play upload action is called upload_to_play_store (also known as supply). Docs: docs.fastlane.tools

Gradle Play Publisher

If you would rather avoid Ruby, the Gradle Play Publisher plugin adds Play upload tasks to Gradle itself.

plugins {
    id("com.github.triplet.play") version "<version>"
}

play {
    serviceAccountCredentials.set(file(System.getenv("PLAY_JSON_KEY_PATH") ?: "play.json"))
    track.set("internal")
}
// then: ./gradlew publishReleaseBundle

fastlane or Gradle Play Publisher? I choose fastlane when the team also needs Firebase, Slack and screenshots in one place, and the plugin when the project is Gradle-only and I want zero extra runtimes on CI.

6. Distribution: Firebase App Distribution and DeployGate

Distribution tools put a build in front of testers before the store. They are faster than Play review and need no store listing.

Firebase App Distribution

Part of Firebase, free to use, with groups, release notes and tester feedback. Choose it when you already use Firebase, or want one place for builds and crashes. For concepts see the App Distribution overview. Three ways to use it from CI: the Gradle plugin, the Firebase CLI, or fastlane.

# install the Firebase CLI (needs Node.js)
npm install -g firebase-tools
# or the standalone binary from the official install page

# in CI, authenticate with a service account instead of your own login
export GOOGLE_APPLICATION_CREDENTIALS="$RUNNER_TEMP/firebase-sa.json"

firebase appdistribution:distribute app/build/outputs/apk/release/app-release.apk \
  --app "$FIREBASE_APP_ID" \
  --groups "qa" \
  --release-notes "Build $GITHUB_RUN_NUMBER from $GITHUB_REF_NAME"

Give the service account only the App Distribution role it needs. Docs: firebase.google.com/docs/app-distribution. Prefer to trigger uploads from the IDE? See the Android Studio plugin article.

DeployGate

DeployGate is a distribution service popular in Japan and across Asia. Testers install through its app or a link, and it shows per-build install status and device information. Choose it when your organization or clients already use it, or you need its team management features. It has a web API, a command-line tool, a Gradle plugin and a fastlane plugin; pick the one that matches your pipeline. The API route is the most universal:

# upload an APK with the DeployGate API (token comes from your account settings, kept as a CI secret)
curl -F "token=$DEPLOYGATE_API_TOKEN" \
     -F "file=@app/build/outputs/apk/release/app-release.apk" \
     -F "message=Build $BUILD_NUMBER" \
     "https://deploygate.com/api/users/<owner>/apps"

Check the docs for current parameters (distribution pages, release notes, groups). Docs: docs.deploygate.com

ChannelBest forReview waitNotes
Firebase App DistributionDaily QA, dogfooding, UAT buildsNoneIntegrates with Crashlytics and Gradle
DeployGateTeams and clients that use it alreadyNoneOwn app and install tracking
Play internal testingThe exact bundle that will shipMinutesSame signing and install path as production
Play closed and open testingWider betaCan need reviewReal Play Store experience

7. Google Play, the API and signing

Play Console and the Publisher API

The Play Console is the web UI. For automation you use the Google Play Developer API, which fastlane and Gradle Play Publisher call for you. Setup, in order:

  1. In Google Cloud, create or pick a project, enable the Google Play Android Developer API, and create a service account with a JSON key.
  2. In the Play Console, open Users and permissions, invite the service account’s email, and grant only the app permissions it needs (for example, release to testing tracks, not to production).
  3. Store the JSON key as a CI secret, write it to a temporary file during the job, and delete it after.
  4. Do a first upload by hand in the console, since apps usually must exist and be set up before the API can release them.

Console menus move around. If a step in my list does not match what you see, follow the current Play Console help pages rather than my wording.

Signing

With Play App Signing, Google holds the key that signs what users install, and you sign uploads with a separate upload key. That is the setup I recommend: if the upload key leaks, you can ask Google to reset it. Without it, a lost keystore can end the app.

# create an upload keystore (store it in a secrets manager, not in git)
keytool -genkeypair -v -keystore upload.jks -alias upload \
  -keyalg RSA -keysize 2048 -validity 10000

# base64 it so it can live in a CI secret
base64 -i upload.jks | pbcopy        # macOS; use `base64 -w0 upload.jks` on Linux

Docs: developer.android.com/studio/publish/app-signing

8. Quality gates, observability, Docker and secrets

Quality gates

ToolWhat it checksHow you run it
Android LintAndroid-specific problems: API misuse, unused resources, accessibility, security hintsBuilt in: ./gradlew lintDebug. Docs
ktlintKotlin code styleCLI or a Gradle plugin. Docs
detektKotlin code smells and complexityGradle plugin with a baseline file for legacy code. Docs
SonarQubeBugs, vulnerabilities, coverage trends, quality gate on pull requestsServer (self-hosted or cloud) plus a Gradle scanner step. Docs
Size and startup budgetsAPK or AAB size, cold startA CI step that fails when a number crosses its limit

Introduce these with a baseline: freeze today’s warnings, then fail only on new ones. Otherwise the first pipeline run is red forever and people stop caring.

Observability after the release

Crashlytics and Android vitals in Play Console tell you crash and ANR rates per version. Wire a Slack or chat notification into the pipeline: build result, version name, a link to the release, and a link to the crash dashboard. See the Crashlytics overview.

Docker for build images

If builds differ between machines, put the toolchain in an image: JDK, Android command-line tools, SDK platforms and build-tools, Node for the Firebase CLI. Start from the CI vendor’s image (cimg/android for CircleCI) or a maintained community image, and pin the tag. Build your own only when you need something unusual. Install Docker from docs.docker.com.

Secrets

WhereUse it forWatch out
CI secrets (GitHub secrets and environments, CircleCI contexts, Bitrise secrets, Jenkins credentials)Keystore, passwords, Play and Firebase service accounts, API tokensScope them per environment. Secrets are masked in logs only if printed exactly as stored
A secrets manager (Vault, a cloud secret manager, a password-manager CLI)Many teams, rotation, auditAdds a dependency; use short-lived credentials where possible
The repositoryNever. Not even “private” repositoriesAdd secret scanning and a pre-commit hook

9. The AI era, part 1: MCP setup

The Model Context Protocol is an open standard for connecting AI applications to tools and data. Instead of every AI tool writing its own GitHub or Firebase integration, a tool exposes an MCP server once and any MCP-capable app can use it. For a DevOps engineer, that makes it the new “API access” question: who is allowed to do what, through which agent?

Host (the AI app)Claude Code, an IDE, a chat app MCP client 1 MCP client 2 MCP client 3 HTTP + token stdio stdio GitHub serverremote · issues, PRs, code Firebase serverlocal · via Firebase CLI Filesystem serverlocal · folders you allow messages are JSON-RPC; servers offer tools, resources and prompts
The host decides which servers it talks to. A server only does what its tools allow, and only with the credentials you gave it.

What you need on the machine

NeedWhyInstall
Node.jsMany servers start with npxFrom nodejs.org or a version manager
Python with uvPython servers start with uvxdocs.astral.sh/uv
DockerSome servers ship as images, which also isolates themdocs.docker.com
Tokens and keysA GitHub token, a Firebase login or service account, a Jira tokenCreate them with the smallest scope that works
An MCP hostClaude Code, an IDE, or another MCP-capable clientSee the Claude Code setup

Adding servers to Claude Code

# local server over stdio (everything after -- is the command that starts it)
claude mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem /path/to/allowed/dir

# remote server over HTTP
claude mcp add --transport http github https://api.githubcopilot.com/mcp/ \
  --header "Authorization: Bearer $GITHUB_PAT"

# see what is configured, and check status inside Claude Code with /mcp
claude mcp list

Scopes decide who gets the server: local to you, shared with the team in a project file, or for all your projects. The shared project file is .mcp.json at the repository root, so the whole team starts with the same servers. Keep tokens out of it by referencing environment variables:

{
  "mcpServers": {
    "github": {
      "type": "http",
      "url": "https://api.githubcopilot.com/mcp/",
      "headers": { "Authorization": "Bearer ${GITHUB_PAT}" }
    },
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "./docs"]
    }
  }
}

Other MCP hosts use a very similar shape: a name, a command with arguments (stdio) or a URL (HTTP), and environment variables. Options and flags change between releases, so confirm them with claude mcp --help and the Claude Code MCP documentation.

Servers that earn their place in an Android and DevOps team

These are examples to evaluate, not an endorsement list. Check each project’s own page for the current install command and permissions.

ExampleUseWhere to look
GitHub MCP serverRead issues and PRs, review diffs, check workflow runsgithub/github-mcp-server
Firebase MCP serverInspect projects, apps, Crashlytics and Remote Config from the agent. It is started through the Firebase CLIFirebase docs
Filesystem serverRead and write inside folders you list, nowhere elsemodelcontextprotocol/servers
Issue tracker server (Jira and Confluence via Atlassian’s offering, or your tracker’s)Turn tickets into context for a fixThe vendor’s documentation

The full catalogue and the specification are at modelcontextprotocol.io.

Security, because an MCP server is an access path

How this goes wrong
  • A personal token with full repository rights pasted into a shared config file.
  • A server installed from an unknown package that runs on your laptop with your permissions.
  • Prompt injection: a ticket, web page or code comment contains instructions, and the agent follows them with the tools you gave it.
  • An agent allowed to write to production systems with no human in the loop.
What I require
  • Least privilege. Fine-grained, short-lived tokens limited to the repositories and actions needed. Read-only first; add writes one at a time.
  • Secrets in the environment. Reference ${VARIABLES} in config; never commit values.
  • Trusted servers only. Official or reviewed code, pinned versions, and run untrusted ones in a container.
  • Approvals. Keep the host’s permission prompts on for anything that writes, deletes, publishes or spends money.
  • Treat all fetched text as untrusted input, especially content from tickets, web pages and third-party code.
  • Audit. Know who connected what, and keep logs of tool calls where the host supports it.

10. The AI era, part 2: agents in your pipeline

Once an agent can read a ticket, edit code and run tests, the natural next step is to run it from CI: a label on a ticket or a crash threshold starts a job that opens a pull request. The thinking is in the Jira to pull request agent article and the team-level setup in automation and teams. The DevOps view is about the box the agent runs in.

Triggerlabel, schedule,or alert Runnerclean sandbox,no prod access Agentscoped token,runs the tests Pull requestnever a pushto main Humanrequired review,then merge Guardrails across every steptime limit · cost cap · tool allowlist · audit log · branch protection
The agent is a very fast junior colleague with a tight leash. The pull request and the human review are the leash.

What you need to set up:

# sketch: a GitHub Actions job that runs an agent on a labelled issue
on:
  issues:
    types: [labeled]
permissions:
  contents: write
  pull-requests: write
jobs:
  agent:
    if: github.event.label.name == 'agent-fix'
    runs-on: ubuntu-latest
    timeout-minutes: 20
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with: { distribution: temurin, java-version: 17 }
      - name: Run the agent
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        run: |
          npm install -g @anthropic-ai/claude-code
          claude -p "Fix issue #${{ github.event.issue.number }}. Run ./gradlew testDebugUnitTest. Open a pull request, do not push to main." \
            --max-turns 20

Treat that as a shape, not a recipe: flags, package names and the official Action evolve, so read the current documentation before you copy anything into a repository that matters.

11. Day-1 checklist for a new Android repo

#Do thisWhy
1Commit the Gradle wrapper and pin the JDK versionSame build everywhere
2Protect main: required PR review and required checksNothing unreviewed or red gets in
3Add a CI workflow: lint, unit tests, assembleFeedback on every PR
4Turn on Gradle caching in CIBuilds in minutes, not tens of minutes
5Create the upload keystore; enable Play App Signing; store secrets in CISafe, recoverable signing
6Add a lane or job that sends every merge to main to App Distribution or DeployGateTesters always have the latest
7Add a manual, approved job that uploads to the Play internal trackRelease without a laptop
8Set version code from a CI counter or tag, never by handNo “version code already used” surprises
9Add ktlint, detekt and a baselineStyle debates end
10Notify chat with result and links; connect CrashlyticsThe team sees the release
11Write RELEASING.md: who, how, rollback, contactsThe bus factor is not one
12Only then: MCP servers and agents, read-only firstAutomate a working process, not a missing one

12. Pitfalls I have paid for

What goes wrong
  • Logic hidden in the CI UI. Click-configured steps nobody can review or move. Keep logic in files in the repo.
  • Unpinned everything. “latest” images and action versions change under you on a Friday.
  • Keystore only on one laptop. Or committed to git. Both end badly.
  • Overpowered service accounts. A CI token that can publish to production from any branch.
  • Secrets exposed to pull requests from forks or printed into logs.
  • No cache, no timeout. Slow builds and runaway jobs that burn minutes.
  • Flaky emulator tests as a hard gate. People learn to re-run until green. Quarantine flakes.
  • Jenkins snowflakes. One hand-built agent that nobody dares to restart.
  • Giving an agent more access than a new hire would get.
What works
  • Thin CI files that call Gradle and fastlane.
  • Pinned versions, updated on purpose with a bot such as Dependabot or Renovate.
  • Separate credentials per environment, rotated on a schedule.
  • A release job that is boring, repeatable and approved by a human.

13. Takeaways and glossary

TermIn plain words
CI / CDContinuous integration builds and tests every change. Continuous delivery gets the result to testers or users.
Runner / agentThe machine that executes a CI job.
Workflow / pipelineThe ordered set of jobs that run for a change.
ArtifactA file a job produces, such as an AAB or APK.
AABAndroid App Bundle, the format you upload to Google Play.
Upload keyThe key you sign uploads with when Play App Signing is on.
Service accountA non-human identity that automation uses to call an API.
LaneA named fastlane task such as internal or beta.
MCPModel Context Protocol, a standard way for AI apps to use tools and data.
stdio / HTTP transportHow an MCP client talks to a server: through a local process, or over the network.
Prompt injectionHidden instructions in content an AI reads, trying to steer its actions.
Least privilegeGive an identity only the access it needs and nothing more.
← Back to all writing