You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GitHub Actions中自动递增pubspec.yaml的版本号?

问题背景

我对传统Linux命令及grep工具不熟悉,已经在GitHub Actions中搭建了流水线,期望在应用发布大版本时完成两个操作:

  • 创建GitHub标签
  • 递增pubspec.yaml中的版本号与构建号(例如:1.2.3+22 → 1.2.4+23;2.14.9+99 → 2.14.10+100)

目前创建标签的命令已经正常运行,但版本号递增的现有实现还有优化空间,现有命令如下:

- name: "Retrieve version"
  id: version
  run: |
    echo "OLD_VERSION=$(cat ${GITHUB_WORKSPACE}/pubspec.yaml | grep 'version:' | head -1 | cut -f2- -d: | sed -e 's/^[ 	]*//')" >> $GITHUB_OUTPUT
    echo "NEW_VERSION=$(awk '{ match($0,/([0-9]+)\+([0-9]+)/,a); a[1]=a[1]+1; a[2]=a[2]+1; sub(/[0-9]+\+[0-9]+/,a[1]"+"a[2])}1' ${GITHUB_WORKSPACE}/pubspec.yaml | grep 'version:' | head -1 | cut -f2- -d: | sed -e 's/^[ 	]*//')" >> $GITHUB_OUTPUT
- name: "Increment version"
  run: |
    sed -i 's/${{ steps.version.outputs.OLD_VERSION }}/${{ steps.version.outputs.NEW_VERSION }}/g' ${GITHUB_WORKSPACE}/pubspec.yaml
    echo ${{ steps.version.outputs.OLD_VERSION }}
    echo ${{ steps.version.outputs.NEW_VERSION }}

优化建议与替代方案

方案1:简化Shell命令逻辑,减少冗余操作

现有命令多次读取pubspec.yaml文件并嵌套多层管道,可读性和效率都可以优化。拆分版本号提取与递增逻辑,更清晰易维护:

- name: "Retrieve & increment version"
  id: version
  run: |
    # 直接提取第一行version字段的值,避免多余操作
    OLD_VERSION=$(grep '^version:' ${GITHUB_WORKSPACE}/pubspec.yaml | sed 's/version: //')
    
    # 拆分语义版本(比如1.2.3)和构建号(比如22)
    SEMVER=$(echo "$OLD_VERSION" | cut -d'+' -f1)
    BUILD_NUM=$(echo "$OLD_VERSION" | cut -d'+' -f2)
    
    # 递增语义版本的最后一位
    NEW_SEMVER=$(echo "$SEMVER" | awk -F. '{print $1"."$2"."($3+1)}')
    # 递增构建号
    NEW_BUILD_NUM=$((BUILD_NUM + 1))
    
    NEW_VERSION="$NEW_SEMVER+$NEW_BUILD_NUM"
    
    echo "OLD_VERSION=$OLD_VERSION" >> $GITHUB_OUTPUT
    echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT

- name: "Update pubspec.yaml"
  run: |
    # 只替换以version:开头的行,避免全局替换误改其他内容
    sed -i "s/^version: ${{ steps.version.outputs.OLD_VERSION }}/version: ${{ steps.version.outputs.NEW_VERSION }}/" ${GITHUB_WORKSPACE}/pubspec.yaml

优势:

  • 仅读取一次pubspec.yaml文件,减少IO操作
  • 逻辑拆分后更易理解和修改
  • 用^version:限定替换范围,避免误改文件中其他出现旧版本号的内容

方案2:用Dart官方工具pub version(最可靠)

如果是Flutter/Dart项目,直接用官方的pub version命令递增版本号,完全规避手动解析版本号的边缘问题(比如版本号进位、格式异常等):

- name: "Increment version with pub"
  id: version
  run: |
    cd ${GITHUB_WORKSPACE}
    # 保存旧版本号
    OLD_VERSION=$(grep '^version:' pubspec.yaml | sed 's/version: //')
    # 递增补丁版本号(对应x.y.z → x.y.z+1),--no-git-tag-version避免自动创建本地标签
    pub version patch --no-git-tag-version
    # 获取新版本号
    NEW_VERSION=$(grep '^version:' pubspec.yaml | sed 's/version: //')
    
    echo "OLD_VERSION=$OLD_VERSION" >> $GITHUB_OUTPUT
    echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT

- name: "Create GitHub tag"
  uses: actions/github-script@v6
  with:
    script: |
      github.rest.git.createRef({
        owner: context.repo.owner,
        repo: context.repo.repo,
        ref: `refs/tags/${{ steps.version.outputs.NEW_VERSION }}`,
        sha: context.sha
      })

优势:

  • 官方工具,完美兼容pubspec.yaml的版本格式规范
  • 自动处理版本号进位场景(比如2.14.9→2.14.10)
  • 无需手动编写复杂正则或拆分逻辑,出错概率极低

方案3:用社区GitHub Action替代Shell命令

如果不想写Shell命令,可以用社区维护的Action完成版本号递增,配置化操作更省心:

- name: "Increment version"
  id: version
  uses: poad/flutter-version-action@v1
  with:
    path: ${{ GITHUB_WORKSPACE }}/pubspec.yaml
    version: patch
    build-number: auto-increment

- name: "Create GitHub tag"
  uses: actions/github-script@v6
  with:
    script: |
      github.rest.git.createRef({
        owner: context.repo.owner,
        repo: context.repo.repo,
        ref: `refs/tags/${{ steps.version.outputs.version }}`,
        sha: context.sha
      })

优势:

  • 完全无需编写Shell命令,通过参数配置完成操作
  • 自动处理版本号与构建号的递增逻辑
  • 内置格式验证,避免版本号格式错误

内容的提问来源于stack exchange,提问作者Thomas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 11:55:25