Flutter艺术探索-Flutter CI/CD配置:GitHub Actions自动化部署
走到这里,你已经掌握了使用 GitHub Actions 为 Flutter 项目搭建自动化部署管道的核心方法。从代码提交触发,到质量检查、多平台构建,再到最终部署,整个过程完全自动化,这能把你和团队从重复劳动中解放出来。关键是,这套流程不是一成不变的。你可以从本文提供的配置出发,根据自己项目的实际需求进行调整:也许你需要接入 Firebase App Distribution,也许需要自动生成更
Flutter CI/CD 配置指南:使用 GitHub Actions 实现自动化部署
引言
如今移动应用迭代速度越来越快,持续集成与持续部署(CI/CD)早就不再是“加分项”,而是保障开发效率和代码质量的标准实践。对于 Flutter 开发者来说,如果还停留在手动打包、测试、发布的老路上,不仅浪费时间,也容易出错。
好在 GitHub 官方提供的自动化工具 GitHub Actions,为我们搭建 Flutter 项目的 CI/CD 流水线提供了强大又灵活的支持。今天,我们就来一起完成从零开始配置一条完整的自动化部署流程,让你的代码在提交后自动完成检查、测试、构建,甚至发布。
理解核心概念
GitHub Actions 是如何工作的?
简单来说,GitHub Actions 采用事件驱动模式:当特定事件(比如推送代码、创建 PR)发生时,它会执行你在仓库中预设的自动化流程。这些流程通过 YAML 文件定义,主要包含几个核心概念:
- Workflow(工作流程):一个完整的自动化流程,对应
.github/workflows/目录下的一个 YAML 文件。 - Event(事件):触发工作流程运行的动作,例如
push、pull_request、release等。 - Job(作业):工作流程中的一个执行单元,包含一系列步骤,在同一个 Runner 上运行。
- Step(步骤):作业内的具体任务,可以是执行一条 shell 命令,或调用一个预定义的动作。
- Runner(运行器):执行作业的服务器,可以使用 GitHub 托管的,也可以自己搭建。
设计 Flutter 的 CI/CD 流水线
一条健壮的 Flutter CI/CD 流水线通常会包含以下几个阶段,我们可以根据项目需求进行增减:
- 代码质量检查:运行静态分析和代码格式化检查。
- 依赖管理:获取项目依赖,并利用缓存加速后续流程。
- 构建验证:尝试编译不同平台(Android/iOS/Web)的产物,确保代码可构建。
- 自动化测试:执行单元测试和集成测试,生成测试覆盖率报告。
- 产物构建:生成用于发布的应用包(APK/IPA/Web 资源)。
- 部署发布:将构建产物自动上传到应用商店、测试平台或静态网站。
实战:编写 CI/CD 工作流
基础工作流配置文件
让我们先来看一个完整的 flutter-ci-cd.yml 示例,你可以将它保存到项目的 .github/workflows/ 目录下:
name: Flutter CI/CD Pipeline
on:
push:
branches: [ main, develop ]
tags: [ 'v*' ]
pull_request:
branches: [ main ]
env:
FLUTTER_VERSION: '3.19.0'
JAVA_VERSION: '17'
jobs:
quality-check:
name: Code Quality Check
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
channel: 'stable'
cache: true
- name: Show Flutter Environment
run: flutter doctor -v
- name: Get Dependencies
run: flutter pub get
- name: Analyze Code
run: flutter analyze --no-fatal-infos
- name: Check Format
run: flutter format --set-exit-if-changed .
- name: Run Tests
run: flutter test --coverage
- name: Upload Coverage
uses: codecov/codecov-action@v3
with:
file: ./coverage/lcov.info
fail_ci_if_error: false
android-build:
name: Android Build
runs-on: ubuntu-latest
needs: quality-check
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: ${{ env.JAVA_VERSION }}
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
- name: Get Dependencies
run: flutter pub get
- name: Build APK
run: flutter build apk --release --split-per-abi
env:
KEY_PROPERTIES: ${{ secrets.ANDROID_KEY_PROPERTIES }}
KEYSTORE: ${{ secrets.ANDROID_KEYSTORE }}
- name: Upload APK Artifacts
uses: actions/upload-artifact@v4
with:
name: android-apks
path: build/app/outputs/flutter-apk/*.apk
retention-days: 7
ios-build:
name: iOS Build
runs-on: macos-latest
needs: quality-check
if: startsWith(github.ref, 'refs/tags/v')
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
- name: Install CocoaPods
run: |
cd ios
pod install
- name: Build iOS
run: flutter build ios --release --no-codesign
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
- name: Upload IPA Artifact
uses: actions/upload-artifact@v4
with:
name: ios-ipa
path: build/ios/ipa/*.ipa
retention-days: 7
web-build:
name: Web Build
runs-on: ubuntu-latest
needs: quality-check
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
- name: Get Dependencies
run: flutter pub get
- name: Build Web
run: flutter build web --release
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
if: github.ref == 'refs/heads/main'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./build/web
keep_files: false
这个配置定义了一个多任务的工作流:代码质量检查通过后,才会并行触发 Android、iOS(仅针对版本标签)和 Web 的构建任务。
一些有用的辅助脚本
复杂的构建流程通常需要脚本辅助。这里有两个例子:
1. Android 构建环境配置脚本 (scripts/android_setup.sh)
这个脚本负责在 CI 环境中安全地设置签名密钥。
#!/bin/bash
set -e
echo "🔧 Setting up Android build environment..."
if [ -z "$KEY_PROPERTIES" ] || [ -z "$KEYSTORE" ]; then
echo "❌ Missing required secrets: KEY_PROPERTIES or KEYSTORE"
exit 1
fi
echo "$KEY_PROPERTIES" > android/key.properties
echo "$KEYSTORE" | base64 --decode > android/app/keystore.jks
chmod 600 android/key.properties
chmod 600 android/app/keystore.jks
echo "✅ Android build environment setup completed"
2. 版本管理工具类 (lib/utils/version_manager.dart)
在 CI 中自动递增版本号是个好习惯,这个 Dart 类可以帮你管理 pubspec.yaml 中的版本。
import 'dart:io';
import 'package:yaml/yaml.dart';
class VersionManager {
final String pubspecPath = 'pubspec.yaml';
Future<Map<String, dynamic>> getCurrentVersion() async {
final file = File(pubspecPath);
final content = await file.readAsString();
final yaml = loadYaml(content);
final version = yaml['version'] as String;
final parts = version.split('+');
return {
'version': parts[0],
'buildNumber': int.parse(parts[1]),
};
}
Future<void> incrementVersion({String? newVersion, int? buildIncrement = 1}) async {
final current = await getCurrentVersion();
final currentVersion = current['version'] as String;
final currentBuild = current['buildNumber'] as int;
final versionParts = currentVersion.split('.');
final major = int.parse(versionParts[0]);
final minor = int.parse(versionParts[1]);
final patch = int.parse(versionParts[2]);
String updatedVersion;
if (newVersion != null) {
updatedVersion = newVersion;
} else {
updatedVersion = '$major.$minor.${patch + 1}';
}
final newBuildNumber = currentBuild + (buildIncrement ?? 1);
final file = File(pubspecPath);
List<String> lines = await file.readAsLines();
for (int i = 0; i < lines.length; i++) {
if (lines[i].contains('version:')) {
lines[i] = 'version: $updatedVersion+$newBuildNumber';
break;
}
}
await file.writeAsString(lines.join('\n'));
print('✅ Version updated: $updatedVersion+$newBuildNumber');
}
}
// ... 更多方法详见原文
一步步集成到你的项目
第一步:项目初始化
- 启用 GitHub Actions:在你的项目根目录创建
.github/workflows/文件夹,并将上面的 YAML 配置文件放进去。 - 生成并配置密钥:
- 使用
keytool生成 Android 签名密钥。 - 将生成的
keystore.jks文件用 Base64 编码(base64 -i keystore.jks)。
- 使用
- 添加 GitHub Secrets:在仓库的 Settings -> Secrets and variables -> Actions 页面,添加
ANDROID_KEY_PROPERTIES和ANDROID_KEYSTORE等密钥。这些信息会安全地注入到工作流环境中。
第二步:在本地进行测试
在推送到 GitHub 触发线上 Action 之前,最好先在本地模拟测试。可以创建一个简单的测试脚本:
#!/bin/bash
set -e
echo "🚀 Starting local CI test..."
export CI=true
echo "📋 Running quality checks..."
flutter analyze
flutter format --set-exit-if-changed .
flutter test --coverage
echo "🤖 Testing Android build..."
flutter build apk --release --split-per-abi
echo "🌐 Testing Web build..."
flutter build web --release
echo "✅ All local CI tests passed!"
第三步:遇到问题怎么办?
CI/CD 配置过程难免会遇到失败。建议创建一个问题排查文档,记录常见错误和解决方案。例如:
- Flutter 版本不匹配:在 workflow 文件中明确指定稳定的 Flutter 版本号。
- 依赖下载缓慢:为 Flutter SDK 和 Pub 依赖配置缓存。
- Android 签名失败:仔细检查
key.properties文件格式和 secrets 的配置是否正确。 - iOS 证书问题:考虑使用
fastlane match等工具在团队间同步证书和描述文件。
让流水线更快更智能
优化缓存策略
合理利用缓存可以极大缩短工作流运行时间。你可以基于 pubspec.lock 文件的哈希值来创建缓存键,确保依赖变更时缓存自动失效。
- name: Generate Cache Key
id: cache-key
run: |
HASH=$(sha256sum pubspec.lock | cut -d' ' -f1)
echo "key=flutter-deps-$HASH" >> $GITHUB_OUTPUT
- name: Cache Pub Dependencies
uses: actions/cache@v3
with:
path: |
${{ github.workspace }}/.pub-cache
${{ github.workspace }}/build
key: ${{ steps.cache-key.outputs.key }}
实现条件执行
不是每次提交都需要构建所有平台。使用 paths-filter 等 Action 可以智能地根据文件变更来决定执行哪些任务,比如只有 ios/ 目录下的文件变动了才触发 iOS 构建。
- name: Detect Changes
id: changes
uses: dorny/paths-filter@v2
with:
filters: |
android:
- 'android/**'
- 'lib/**'
ios:
- 'ios/**'
- 'lib/**'
- name: Build Android
if: steps.changes.outputs.android == 'true'
run: flutter build apk
值得遵循的最佳实践
- 最小权限原则:在 workflow 文件中显式定义所需的权限,只赋予必要的
read或write权限,避免安全风险。 - 建立监控通知:可以编写一个简单的 Python 脚本,调用 GitHub API 检查工作流状态,并在失败时通过 Slack、Teams 或邮件通知团队。
- 文档与代码同步:将 CI/CD 的配置、脚本和排查指南都纳入版本控制,并随着项目演进不断更新。
总结
走到这里,你已经掌握了使用 GitHub Actions 为 Flutter 项目搭建自动化部署管道的核心方法。从代码提交触发,到质量检查、多平台构建,再到最终部署,整个过程完全自动化,这能把你和团队从重复劳动中解放出来。
关键是,这套流程不是一成不变的。你可以从本文提供的配置出发,根据自己项目的实际需求进行调整:也许你需要接入 Firebase App Distribution,也许需要自动生成更新日志。随着项目的成长,持续优化你的 CI/CD 流水线,让它成为团队交付高质量应用的坚实后盾。
扩展资源与下一步:
- GitHub Actions 官方文档:深入了解工作流语法和社区 Action。
- Flutter 官方部署指南:获取平台特定的部署建议。
- Fastlane:如果你需要更复杂的应用商店发布自动化,可以将其集成到工作流中。
希望这篇指南能帮助你顺利启动 Flutter 项目的自动化之旅。在实践中如果遇到问题,多查阅日志、善用社区资源,通常都能找到解决方案。 Happy automating!
更多推荐



所有评论(0)