Build Pipeline is a sequence of automated stages that code goes through from the moment of commit to a ready-to-deploy artifact. The pipeline includes compilation, running tests, static analysis, and preparing the release package. According to Google Cloud DORA, 2025, teams with a well-configured pipeline achieve 440 times faster delivery of changes compared to teams without automation.
Key Takeaways
Build Pipeline is a formalized sequence of steps that are executed automatically with every code change. Each step checks a certain quality aspect: compilability, test correctness, absence of vulnerabilities, code style compliance. If any step fails, the pipeline stops.
The pipeline concept comes from the production line — like in a factory where each station adds value to the product. In development, each stage adds confidence that the code is ready for release. Modern pipelines are defined as code (Pipeline as Code) and stored in the Git repository alongside the project.
According to Continuous Delivery Foundation, 2025, a mature build pipeline reduces the time from commit to release from weeks to minutes. This is achieved through full automation and parallel execution of independent stages.
Instead of configuring through a web interface, a modern pipeline is described in YAML or Groovy files. Jenkinsfile, `.gitlab-ci.yml`, `.github/workflows/build.yml` are examples of Pipeline as Code. Advantages: versioning, code review, reproducibility.
Jenkins has two syntaxes. Declarative — simpler, with a clear stages/steps structure. Scripted — more flexible, based on Groovy. For most projects, the declarative approach is recommended as more readable and predictable.
A typical build pipeline for a mobile application includes several key stages. Each stage performs its function and filters potential problems at an early stage.
The pipeline starts with cloning the repository. Then dependencies are installed: Gradle/Maven packages, CocoaPods, SPM (Swift Package Manager), npm packages. Using caching at this stage speeds up subsequent builds by 50-70%.
Before compilation, code quality tools are launched: Detekt or ktlint for Kotlin, SwiftLint for Swift, ESLint for JavaScript. They check code style compliance and find potential bugs at the code analysis level.
The code is compiled into binary form, unit tests run in parallel. For Android this is `./gradlew testDebugUnitTest`, for iOS — `xcodebuild test -scheme App -destination 'platform=iOS Simulator'`. Test failure immediately stops the pipeline.
name: Mobile Build Pipeline
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./gradlew detekt
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./gradlew testDebugUnitTest
- run: ./gradlew jacocoTestReport
build-release:
needs: [lint, unit-tests]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./gradlew assembleRelease
- uses: actions/upload-artifact@v4
with:
name: release-apk
path: app/build/outputs/apk/release/app-release.apk
After successful compilation, tests that require the application to run are executed: Espresso for Android, XCTest/XCUITest for iOS, Detox for React Native. At this stage, the artifact is deployed on a simulator or real device through farm services (Firebase Test Lab, BrowserStack, Sauce Labs).
Proper pipeline configuration determines the efficiency of the entire CI/CD process. Configuration includes choosing triggers, defining parallel and sequential stages, parameterization, and integration with external services.
Main triggers: push to repository, pull request (especially for code review with automated checks), Git tag creation (for release builds), schedule (nightly build). Pull request trigger is the most practical for team collaboration as it identifies problems before code merge.
Independent stages (linting, testing on different OS versions) should run in parallel to speed up execution. Dependent ones — sequentially. Modern CI systems automatically manage parallel tasks, distributing them across available agents.
A long pipeline slows down the development cycle and reduces team motivation. Build time optimization is one of the main tasks of a DevOps engineer when working with build pipelines.
Gradle Build Cache saves the results of previous compilations. If a module's source code hasn't changed, it won't be recompiled. Incremental compilation in Swift and Kotlin works similarly. The cache size can reach gigabytes, but the time savings range from 30% to 70%.
Unit tests can be run on multiple agents simultaneously, distributing test classes. Sharding is a technique of splitting tests into groups (shards). GitHub Actions supports `strategy.matrix`, Jenkins — Parallel Test Executor, Gradle — `--parallel --max-workers`.
Each extra stage adds time. Analyze the pipeline regularly: which stages can be combined? For example, linting can run in parallel with compilation rather than before it. Integration tests — only for pull requests, not for every commit.
pipeline {
agent any
options {
timestamps()
timeout(time: 30, unit: 'MINUTES')
}
stages {
stage('Parallel Checks') {
parallel {
stage('Lint') {
steps { sh './gradlew detekt' }
}
stage('Unit Tests') {
steps { sh './gradlew test' }
}
}
}
stage('Build') {
steps { sh './gradlew assembleRelease' }
}
}
}
The build pipeline is a critical element of the software supply chain, and its security cannot be ignored. Pipeline compromise can lead to malicious code being injected into the release artifact, affecting all application users.
Known attacks: SolarWinds (2020), Codecov (2021), 3CX (2023) — all exploited vulnerabilities in CI/CD pipelines. Common vector — an attacker gains access to build server credentials and modifies code at the build stage. Result — a malicious release signed with a legitimate certificate.
Never store signing keys, API tokens, and passwords in the repository or CI system environment variables in plain text. Use CI system secrets (GitHub Secrets, GitLab CI Variables), HashiCorp Vault, AWS Secrets Manager. Minimize access to secrets — each pipeline should only receive the keys needed for its specific steps.
Every artifact coming out of the pipeline must be cryptographically signed and contain attestation — proof of origin (provenance). Tools: SLSA framework, in-toto attestation, cosign for container signatures. Signature verification must be performed before deployment to any environment.
name: Secure Build Pipeline
on: [push]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Scan dependencies
run: ./gradlew dependencyCheckAnalyze
- name: SAST scan
run: ./gradlew detekt
sign-attest:
needs: security-scan
runs-on: ubuntu-latest
steps:
- run: ./gradlew assembleRelease
- name: Sign APK
run: jarsigner -keystore ${{ secrets.KEYSTORE }} \
app-release.apk ${{ secrets.KEY_ALIAS }}
- name: Generate provenance
uses: actions/attest-build-provenance@v1
The build pipeline is a complex system that requires constant monitoring. Without metrics, it's impossible to determine whether the pipeline has slowed down and which stage has become a bottleneck.
Track: total pipeline duration, time of each stage, build failure rate, queue time. For a large team (>20 developers), it's recommended to set up a dashboard in Grafana or Datadog with aggregated statistics for the week/month.
Every pipeline failure requires a response. Set up notifications in messengers (Slack, Telegram, Discord) with a link to the error log and the commit author's name. For critical failures — PagerDuty or Opsgenie with escalation.
Tools like Act (for GitHub Actions) or Jenkins Pipeline Unit Test allow running the pipeline locally without committing. This speeds up pipeline development and debugging, especially when adding new stages or changing configuration.
Frequently Asked Questions
Build pipeline is a part of the CI/CD pipeline responsible for compilation and artifact preparation. CI/CD pipeline is broader: it includes deployment, post-release monitoring, and infrastructure checks.
On every push to the repository. For pull requests — mandatory before merging. Nightly build — for long tests (e2e, performance) that are not required for every commit.
For new projects — YAML (GitHub Actions, GitLab CI, Bitrise). It's readable and simple. Groovy (Jenkins) is more powerful but harder to maintain. The choice depends on the CI system being used.
Main methods: dependency caching, parallel execution of independent stages, test sharding, excluding long tests from the pipeline for every commit, using powerful build agents.
Analyze the logs: which specific test failed and why. If the test is flaky — add a retry mechanism. If it's a real bug — fix the code, don't disable the test. Disabling tests is the last resort.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also