Flutter Web 浏览器版本升级实战:基于 upgrade-browser 技能解析 Chrome 与 Firefox 的完整 Roll 流程
Flutter Web 浏览器版本升级实战基于 upgrade-browser 技能解析 Chrome 与 Firefox 的完整 Roll 流程【免费下载链接】flutterFlutter makes it easy and fast to build beautiful apps for mobile and beyond项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutterFlutter Web 引擎与 Framework 测试依赖固定版本的 Chrome 与 Firefox 二进制通过 CIPD 分发因此升级浏览器在 Flutter 仓库中是一个需要跨多个文件协同修改的工程化流程既要改 引擎的包锁文件又要同步 根目录的 .ci.yaml 与引擎 CI builder 配置最后还要把新版本的浏览器上传到 CIPD。本文基于仓库内置的 upgrade-browser 技能文档 展开完整覆盖其五步工作流版本校验、本地文件更新、CI 配置同步、本地测试、CIPD 上传并结合 fetch_versions.dart、package_roller.dart、generate_builder_json.dart 等源码解释每一步背后的实现原理与验证手段。一、为什么需要跨文件协同升级浏览器版本的三处落点从技能文档的定义可以确认浏览器版本信息分散在仓库的三个位置Flutter Web 引擎的包锁文件engine/src/flutter/lib/web_ui/dev/package_lock.yaml它锁定了 CIPD 测试所用浏览器的版本。当前仓库中的实际内容为# Please refer to the Upgrade Browser Version section in the README.md for # more details on how to update browser version numbers. chrome: version: 145.0.7632.117 firefox: version: 148.0 edge: launcher_version: 1.2.0.0 esbuild: version: 0.19.5注意chrome与firefox都使用version字段edge和esbuild是相邻但独立锁定的组件不属于浏览器升级范畴。Framework 测试的 CI 定义根目录 .ci.yaml 中所有chrome_and_driver依赖。在dev/felt拉取 CIPD 浏览器之前LUCI 需要先按此声明下载浏览器包。当前仓库中该依赖出现了数十次例如{dependency: chrome_and_driver, version: version:145.0.7632.117}技能文档特别强调.ci.yaml中目前只以这种方式管理 ChromeFirefox 不在此列因此升级 Firefox 时只需修改package_lock.yaml。引擎 CI 的 builder 配置engine/src/flutter/ci/builders/linux_web_engine_test.json其中第 227 行附近同样声明了chrome_and_driver依赖。该文件不手工编辑而由generate-builder-json命令从包锁文件生成。三处版本号必须保持一致。这正是引擎 README 中 Upgrade Browser Version 一节反复强调由于引擎代码与 infra recipes 不在同一个仓库升级浏览器需要多个步骤的原因CIPD 上的包由引擎仓库的脚本上传而 Framework 测试的 LUCI recipes 在独立仓库中消费它们。二、步骤一识别并校验目标版本查询最新稳定版技能文档给出的第一个命令dart scripts/fetch_versions.dart latest chrome|firefox该脚本位于 .agents/skills/upgrade-browser/scripts/fetch_versions.dart。阅读源码可知latest chrome调用fetchChromeLatest()解析 Chrome for Testing 官方的last-known-good-versions.json取channels.Stable.version即完整四段版本号latest firefox调用fetchFirefoxLatest()解析 Mozilla 的firefox_versions.json取LATEST_FIREFOX_VERSION省略浏览器参数时dart scripts/fetch_versions.dart latest脚本会同时查询两者并输出一个 JSON例如{chrome:...,firefox:...}。技能文档示例中把所有地方的 Chrome 和 Firefox 都升到最新对应的正是这种用法。校验指定版本是否存在dart scripts/fetch_versions.dart verify chrome|firefox version该命令输出true或false。源码中两个浏览器的校验数据源不同ChromeverifyChromeVersion拉取 Chrome for Testing 的known-good-versions.json检查versions列表中是否存在version字段等于目标值的条目FirefoxverifyFirefoxVersion先查 Mozilla 的firefox_history_major_releases.json主版本发布历史若未命中再查firefox_history_stability_releases.json稳定性分支发布历史任一命中即返回true。因此 Firefox 的校验能同时覆盖主版本如130.0与稳定性分支版本而 Chrome 只能识别 Chrome for Testing 收录的已知良好版本。校验规则技能文档的强制约定默认强制verify返回false时不得继续执行后续步骤用户显式要求跳过时可以跳过例如用户说升级到 X 版本不做校验则允许直接进入文件更新校验失败但用户确认继续可以向用户复述风险如 Firefox 的例子中会提示我无法通过 Mozilla 官方发布历史验证 Firefox 版本 130.0你确定这是正确的版本号吗用户确认后继续。三、步骤二更新本地文件用户可能要求只升级其中一个位置也可能两个位置同时升级甚至两个位置使用不同的版本号——这是技能文档明确支持的能力。3.1 引擎侧package_lock.yaml只更新chrome或firefox的version字段chrome: version: NEW_VERSION firefox: version: NEW_VERSION版本号格式有讲究Chrome 必须是完整四段式如118.0.5993.70与 README 中 Chrome for Testing 一节的说明一致Firefox 使用主版本号如当前仓库中的148.0。3.2 Framework 侧.ci.yaml把 .ci.yaml 中所有chrome_and_driver出现处的版本号替换为新值- {dependency: chrome_and_driver, version: version:NEW_VERSION}技能文档要求用支持多实例替换的编辑方式replace且allow_multiple: true完成因为当前仓库中该依赖出现了几十处。由于目前只有 Chrome 通过该依赖管理Firefox 升级不涉及.ci.yaml。四、步骤三CI 配置同步generate-builder-json修改package_lock.yaml后需要重新生成引擎 CI 的 builder 配置落点文件是 engine/src/flutter/ci/builders/linux_web_engine_test.json。从engine/src/flutter/lib/web_ui目录运行dev/felt generate-builder-json验证是否需要运行的小技巧先看文件修改时间ls -l engine/src/flutter/ci/builders/linux_web_engine_test.json命令执行后再次确认该文件获得了新的时间戳。这一步只需运行一次——无论本次升级的是 Chrome、Firefox 还是两者。从源码看其工作原理generate_builder_json.dart 读取PackageLock后为每个平台 浏览器组合生成测试步骤其中依赖声明直接取自包锁文件if (browser BrowserName.chrome) String, dynamic{ dependency: chrome_and_driver, version: packageLock.chromeLock.version, }, if (browser BrowserName.firefox) String, dynamic{ dependency: firefox, version: version:${packageLock.firefoxLock.version}, },见 generate_builder_json.dart 第 138-147 行这解释了为什么linux_web_engine_test.json可以机械地由包锁文件再生成只要package_lock.yaml更新builder JSON 中的依赖版本就会随之更新无需人工维护。五、步骤四本地验证dev/felt test在上传 CIPD 之前先在本地跑测试确认无回归。从engine/src/flutter/lib/web_ui目录运行dev/felt test可以追加--browser chrome|firefox把范围限定到本次升级的浏览器缩短反馈时间。这一步的价值在于新的浏览器版本可能改变渲染输出或测试行为本地先跑可以在把二进制发布到 CIPD影响面是所有 CI builder之前发现问题。引擎 README 也提示较新的 Chromium 版本可能会破坏一些测试或 Goldens需要一并修复。六、步骤五CIPD 上传package_roller这是工作流的最后一步因为它会把浏览器二进制真正上传到 CIPD需要特殊的临时的上传权限。先询问用户是否具备 CIPD 权限不确定时可联系 Flutter Discord 的 #hackers-infra 频道这一点在 web_ui README 中也有对应说明通常还需先完成cipd auth-login确认权限后从engine/src/flutter/lib/web_ui目录运行dart dev/package_roller.dart想先试跑时加--dry-run脚本会完成下载与打包但在发布前停止产物保留在临时目录/tmp/browser-roll-随机串供检查。package_roller.dart 的源码级细节package_roller.dart 支持两个命令行参数README 同样有记录--dry-run下载并准备所有 bundle但在上传到 CIPD 之前停下--verbose-v大幅增加 stdout 输出。从源码结构看它的行为要点包括覆盖的平台linux-amd64、mac-amd64、mac-arm64、windows-amd64四个平台组合_PackageRoller._platformspackage_roller.dart 第 98-103 行roll 的范围不止浏览器每个平台都会依次 roll Chromium、Chromedriver、esbuild而Firefox 只在 Linux 平台 roll代码注释For now, we only test Firefox on Linux第 119-122 行——这与 CI 中 Firefox 只出现在linux_web_engine_testbuilder 相吻合幂等跳过每个上传前都会先调用cipdKnowsPackageVersion检查 CIPD 是否已有该版本versiontag 即package_lock.yaml中的版本号已存在则打印 Skipping ... Already uploaded to CIPD! 并建议更新 package_lock.yaml 并换一个版本号CIPD 包路径Chrome 上传到flutter_internal/browsers/chrome/平台Chromedriver 上传到flutter_internal/browser-drivers/chrome/平台Firefox 上传到flutter_internal/browsers/firefox/平台esbuild 上传到flutter/tools/esbuild/平台平台包布局差异脚本注释第 44-57 行说明 Linux/Windows 要求chrome(.exe)直接位于 zip 根目录而 Mac 的Chromium.app需要放在chrome-mac目录内脚本在打包时会尊重这一历史布局差异。七、典型使用示例技能文档原版技能文档给出了三类典型交互值得直接对照使用用户把所有地方的 Chrome 和 Firefox 都升级到最新稳定版。执行① 运行dart scripts/fetch_versions.dart latest不带参数同时取回两者② 更新package_lock.yaml与.ci.yaml③ 运行dev/felt generate-builder-json同步 CI 配置④ 建议运行本地测试⑤ 最后询问 CIPD 权限。用户把 Chrome 升到 135.0.0.0跳过校验。执行① 因用户明确要求而跳过verify② 直接把package_lock.yaml与.ci.yaml写入135.0.0.0③ 继续 Sync → Test → CIPD 的后续流程。用户把 Web 引擎的 Firefox 更新到 130.0。执行① 用dart scripts/fetch_versions.dart verify firefox 130.0校验② 若校验失败向用户确认版本号是否正确③ 用户确认或校验通过后更新package_lock.yaml注意此场景不改.ci.yaml④ 继续 Sync → Test → CIPD。八、流程与文件对照总览步骤命令 / 操作运行目录影响的文件1. 查询版本dart scripts/fetch_versions.dart latest chrome\|firefox技能脚本目录—2. 校验版本dart scripts/fetch_versions.dart verify chrome\|firefox version技能脚本目录—3. 引擎包锁手工编辑—package_lock.yaml4. Framework CI多实例替换chrome_and_driver—.ci.yaml5. CI 同步一次dev/felt generate-builder-jsonengine/src/flutter/lib/web_uilinux_web_engine_test.json6. 本地验证dev/felt test [--browser chrome\|firefox]engine/src/flutter/lib/web_ui—7. CIPD 上传需权限dart dev/package_roller.dart [--dry-run]engine/src/flutter/lib/web_uiCIPD 上的flutter_internal/browsers/*与flutter_internal/browser-drivers/*包需要提醒的适用前提本文所有版本号Chrome145.0.7632.117、Firefox148.0均为当前仓库快照中的值实际执行时以fetch_versions.dart latest查询结果或上游官方发布为准CIPD 上传步骤依赖临时授权普通贡献者应先用--dry-run完整演练并在提交 PR 前把本地测试尤其是受新浏览器版本影响的 Golden 测试一并修复。完整的背景说明另可参阅 引擎 Web 模块 README 的 Upgrade Browser Version 章节。【免费下载链接】flutterFlutter makes it easy and fast to build beautiful apps for mobile and beyond项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考