用途
本参考用于执行 Flutter/Dart SDK 约束升级:在 VGV 项目的各个包中提升 Dart 与 Flutter 的 SDK 版本要求,并同步更新 CI 工作流。每个项目一个 PR,只改动 CI workflow 与 pubspec.yaml,不改逻辑、不升级依赖版本、不改测试。
核心标准
- Flutter 与 Dart 版本号不同:一个 Flutter 发行版附带特定的 Dart SDK,其版本号与 Flutter 无关;pubspec 中的 sdk: 约束取 Dart 版本号,绝不是 Flutter 版本号。两者对应关系可在发布归档 https://docs.flutter.dev/install/archive 查阅。
- 不得凭记忆给出捆绑的 Dart 版本,不得由 Flutter 版本推断。只能来自用户提供、归档页面读取或主动询问。
- Flutter CI 使用 MAJOR.MINOR.x,无脱字符,.x 通配符解析到最新补丁。
- Dart CI 使用精确补丁号 MAJOR.MINOR.PATCH,无脱字符、无通配符。
- pubspec 固定精确补丁:使用 ^MAJOR.MINOR.PATCH。
- 纯 Dart 包直接使用 Dart 版本,无需 Flutter 映射;CI 键是 dart_package.yml 中的 dart_sdk,而非 flutter_package.yml 中的 flutter_version,environment 块只写 sdk:,没有 flutter: 行。
- 即使没有拿到 workflow 文件,也应按包类型写出 CI 块,并指明所属文件名。
- 用 pub get 与 analyze 验证,不静默解决冲突。
- 拒绝越界修改,不做附带说明式的妥协。
步骤 0:确定目标版本
SDK 升级始终涉及两个版本:目标 Flutter 发行版,以及它附带的 Dart 发行版。查找 Dart 版本:打开 https://docs.flutter.dev/install/archive,找到目标 Flutter stable 发行版,记录其旁列出的 Dart 版本。Flutter 目标来自 $ARGUMENTS;若为空或未替换,则取该页最新 Flutter stable。纯 Dart 包无需映射,Dart 版本即 $ARGUMENTS 指定或最新 Dart stable。
归档不可访问时,不要凭记忆填补,应说明 Dart 版本必须从归档获取,并请用户确认。用户已提供两个版本号时按给定值使用,并说明各自对应什么。编辑任何文件前,先陈述两个已解析版本并取得确认。
步骤 1:CI 工作流 — .github/workflows/
VGV 包使用 VeryGoodOpenSource/very_good_workflows 可复用工作流,保留 @v1 标签不动。
Flutter 包使用 MAJOR.MINOR.x:
uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1
with:
flutter_version: "3.41.x" # ← MAJOR.MINOR.x,解析到最新补丁
纯 Dart 包注意键是 dart_sdk,不是 flutter_version:
uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/dart_package.yml@v1
with:
dart_sdk: "3.11.0" # ← 精确 Dart 版本(不是 Flutter 版本)
若文件使用 flutter_channel: stable 而非固定版本,应改为固定版本,VGV 始终在 CI 中固定 Flutter 版本。
未拿到 workflow 文件时:按包类型写出 with: 块,并说明目标是哪个工作流和哪个键。不要凭空编造 name:、on: 或 jobs: 键,也不要猜版本号。
步骤 2:pubspec.yaml environment 约束
格式为 ^MAJOR.MINOR.PATCH(脱字符 + 精确补丁)。与 CI 不同,pubspec 固定具体补丁版本。
Flutter 包(dependencies 下有 flutter:):
environment:
sdk: ^<dart-version> # ← 目标 Flutter 发行版附带的 Dart 版本
flutter: ^<flutter-version> # ← 目标 Flutter 发行版本身
两个占位符需通过步骤 0 的归档查询填写,且数字从不相同。把 Flutter 版本写进 sdk: 是此变更中最常见的错误。
纯 Dart 包(无 Flutter SDK 依赖):
environment:
sdk: ^3.11.0 # ← 仅 Dart 版本
# 无 flutter: 行
在 monorepo 中,逐个更新每个包的 pubspec.yaml;共享 CI 工作流只需更新一次。
步骤 3:验证
在每个包目录下运行(优先使用 Dart/Flutter MCP 工具,否则用 Bash):
flutter pub get # 或:dart pub get(纯 Dart 包)
flutter analyze # 或:dart analyze
若 pub get 因依赖冲突失败,报告冲突,不得通过升级包静默解决。说明阻塞包、其版本以及与新 SDK 约束冲突之处,把决定交回用户:提升该依赖应作为独立 PR。若 analyze 出现 SDK 升级引入的新错误,报告而非在本 PR 中修复。参见 references/version-conflicts.md。
步骤 4:越界请求
用户常将 SDK 升级与其他修改混在一起请求。应直接拒绝额外修改。附带说明的妥协不算拒绝。返回的 pubspec 只改 environment 块,不改依赖约束。之后明确说明未做的事项及其归属:依赖升级属于独立 PR;analyzer 警告只报告文件、行号和规则,不修复。
步骤 5:PR 范围检查
提交前确认 diff 仅包含:.github/workflows/*.yml、pubspec.yaml(一个或多个)。可用 git diff HEAD --name-only 检查。
建议提交/PR 信息:
chore: bump Flutter to <flutter-version> / Dart to <dart-version>
- Update flutter_version in .github/workflows/ to MAJOR.MINOR.x (CI resolves latest patch)
- Update dart_sdk in .github/workflows/ to the exact Dart patch
- Update environment sdk/flutter constraints in pubspec.yaml
No logic or code changes.
两个版本号都出现在标题行,因为审阅历史的 reviewer 需要看到此次升级附带的 Dart 发行版。
适用场景与限制
适用于 VGV(VeryGoodOpenSource)Flutter/Dart 项目的 SDK 约束升级与 CI 版本固定,包括单包与 monorepo 多包场景。限制:只处理 SDK 约束和 CI 版本,不处理依赖升级、lint 修复或代码更改;版本号必须来自归档页面或用户,不可凭记忆推断;官方资料未提供价格、平台支持等其它信息。