Build Pipeline(构建管道)——是一系列自动化阶段的序列,代码从提交时刻到准备部署的工件通过它进行处理。管道包括编译、运行测试、静态分析和发布包准备。根据Google Cloud DORA, 2025的数据,拥有良好配置管道的团队比没有自动化的团队实现440倍更快的变更交付。
要点
构建管道——是在每次代码更改时自动执行的形式化步骤序列。每个步骤检查质量的特定方面:可编译性、测试正确性、无漏洞、符合代码风格。如果任何步骤以错误结束,管道将停止。
管道的概念源自生产线——就像在工厂中,每个站点为产品增加价值。在软件开发中,每个阶段增加信心,确保代码已准备好发布。现代管道被定义为代码(Pipeline as Code)并与项目一起存储在Git仓库中。
根据Continuous Delivery Foundation, 2025,成熟的构建管道将提交到发布的时间从数周缩短到数分钟。这是通过完全自动化和独立阶段的并行执行实现的。
不通过Web界面配置,现代管道在YAML或Groovy文件中描述。Jenkinsfile、`.gitlab-ci.yml`、`.github/workflows/build.yml`——是管道即代码的示例。优点:版本控制、代码审查、可重复性。
在Jenkins中存在两种语法。声明式——更简单,具有清晰的stages/steps结构。脚本化——更灵活,基于Groovy。对于大多数项目,推荐使用声明式方法,因为它更易读且可预测。
移动应用的典型构建管道包括几个关键阶段。每个阶段执行其功能并在早期过滤潜在问题。
管道从克隆仓库开始。然后安装依赖:Gradle/Maven包、CocoaPods、SPM(Swift Package Manager)、npm包。在此阶段使用缓存可将后续构建加速50-70%。
在编译之前,启动代码质量控制工具:Kotlin的Detekt或ktlint、Swift的SwiftLint、JavaScript的ESLint。它们检查代码风格一致性,并在代码分析级别发现潜在错误。
代码被编译为二进制形式,同时运行单元测试。对于Android,这是`./gradlew testDebugUnitTest`,对于iOS——`xcodebuild test -scheme App -destination 'platform=iOS Simulator'`。测试失败立即停止管道。
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
编译成功后,执行需要启动应用程序的测试:Android的Espresso、iOS的XCTest/XCUITest、React Native的Detox。在此阶段,工件通过farm服务(Firebase Test Lab、BrowserStack、Sauce Labs)部署到模拟器或真实设备上。
管道的正确配置决定了整个CI/CD过程的效率。配置包括选择触发器、定义并行和串行阶段、参数化以及与外部服务的集成。
主要触发器:推送到仓库、拉取请求(特别是带有自动检查的代码审查)、创建Git标签(用于发布构建)、计划(夜间构建)。拉取请求触发器——对于团队工作最实用,因为它能在代码合并前发现问题。
独立阶段(代码检查、在不同操作系统版本上测试)应并行执行以加快速度。依赖阶段——串行执行。现代CI系统自动管理并行任务,将其分配到可用代理之间。
过长的管道会减慢开发周期并降低团队动力。构建时间优化——是DevOps工程师在处理构建管道时的主要任务之一。
Gradle构建缓存保存先前编译的结果。如果模块的源代码未更改,则不重新编译。Swift和Kotlin中的增量编译类似。缓存大小可能达到千兆字节,但时间节省为30%到70%。
单元测试可以同时在多个代理上运行,分配测试类。分片——将测试分组(shards)的技术。GitHub Actions支持`strategy.matrix`,Jenkins支持Parallel Test Executor,Gradle支持`--parallel --max-workers`。
每个额外阶段都会增加时间。定期分析管道:哪些阶段可以合并?例如,代码检查可以与编译并行运行,而不是在其之前。集成测试——仅针对拉取请求,而不是每次提交。
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' }
}
}
}
构建管道是软件供应链的关键元素,其安全性不容忽视。管道受损可能导致恶意代码注入到发布工件中,影响应用程序的所有用户。
已知攻击:SolarWinds(2020)、Codecov(2021)、3CX(2023)——都利用了CI/CD管道中的漏洞。共同载体——攻击者获得构建服务器的凭据访问权,并在构建阶段修改代码。结果——由合法证书签名的恶意发布版。
切勿将签名密钥、API令牌和密码以明文形式存储在仓库或CI系统的环境变量中。使用CI系统密钥(GitHub Secrets、GitLab CI Variables)、HashiCorp Vault、AWS Secrets Manager。最小化对密钥的访问——每个管道只应获取其特定步骤所需的密钥。
从管道输出的每个工件都应经过加密签名并包含证明——来源证明(provenance)。工具:SLSA框架、in-toto证明、用于签名容器的cosign。签名验证应在部署到任何环境之前执行。
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
构建管道——是一个需要持续监控的复杂系统。没有指标,无法确定管道是否变慢以及哪个阶段成为瓶颈。
跟踪:通过时间(总管道持续时间)、每个阶段的时间、故障频率(构建失败率)、队列等待时间。对于大型团队(>20名开发者),建议在Grafana或Datadog中配置带有周/月聚合统计数据的仪表板。
每次管道故障都需要响应。在即时通讯工具(Slack、Telegram、Discord)中配置通知,包含错误日志链接和提交作者信息。对于关键故障——使用PagerDuty或Opsgenie进行升级。
像Act(用于GitHub Actions)或Jenkins Pipeline Unit Test这样的工具允许在本地运行管道而无需提交。这加速了管道的开发和调试,尤其是在添加新阶段或更改配置时。
常见问题
构建管道是CI/CD管道的一部分,负责编译和准备工件。CI/CD管道更广泛:包括部署、发布后监控和基础设施检查。
每次推送到仓库时。对于拉取请求——在合并前必须运行。夜间构建——用于长测试(端到端、性能测试),这些测试不是每次提交都必需的。
对于新项目——YAML(GitHub Actions、GitLab CI、Bitrise)。它可读且简单。Groovy(Jenkins)更强大,但维护更困难。选择取决于所使用的CI系统。
主要方法:缓存依赖、并行执行独立阶段、测试分片、将长测试排除在每次提交的管道之外、使用强大的构建代理。
分析日志:哪个测试失败了以及为什么。如果测试不稳定(flaky)——添加重试机制。如果是真正的错误——修复代码,不要禁用测试。禁用测试是最后的手段。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。