GitHub Actions构建号未正常递增问题排查求助
我遇到GitHub Actions构建号有时递增有时不递增的问题,生成的版本号有时从现有序列中间、开头或末尾开始。例如:
v0.98.4 -> expected: v0.98.5
GitHub: v0.98.1
以下是我的工作流配置:
name: Build and Push Docker Image on Release on: push: branches: - 'release/*' permissions: contents: write jobs: build-and-push: runs-on: ubuntu-latest steps: - name: Check out code uses: actions/checkout@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - name: Log in to DockerHub uses: docker/login-action@v1 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - name: Fetch all git tags run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* - name: Get the latest tag id: latest-tag run: | TAG=$(git describe --tags `git rev-list --tags --max-count=1`) echo "Latest tag is $TAG" echo "::set-output name=tag::${TAG}" - name: Increment the version id: next-version run: | TAG="${{ steps.latest-tag.outputs.tag }}" BASE_VERSION=${TAG#v} # Strip the 'v' prefix IFS='.' read -ra VERSION <<< "$BASE_VERSION" PATCH=$((VERSION[2]+1)) NEXT_VERSION="v${VERSION[0]}.${VERSION[1]}.$PATCH" echo "Next version is $NEXT_VERSION" echo "::set-output name=version::$NEXT_VERSION" - name: Build the Docker image with new version run: | docker build -t xxx/yyyy:${{ steps.next-version.outputs.version }} . docker push xxx/yyyy:${{ steps.next-version.outputs.version }} - name: Tag the image as latest and push run: | docker tag xxx/yyyy:${{ steps.next-version.outputs.version }} xxx/yyyy:latest docker push xxx/yyyy:latest - name: Tag the repository with the new version run: | git tag ${{ steps.next-version.outputs.version }} git push origin ${{ steps.next-version.outputs.version }} --tags
我怀疑git fetch --depth=1 origin +refs/tags/*:refs/tags/*命令未拉取所有标签(至少未拉取最新的),但该命令在本地运行正常,请问问题的根因可能是什么?
根因分析
浅克隆导致标签关联失效:
actions/checkout@v2默认使用浅克隆(depth=1),仅拉取仓库最新的一个commit。你的git fetch --depth=1命令虽然能拉取所有标签,但标签是绑定到特定commit的,本地没有这些标签对应的完整历史,git rev-list --tags无法正确识别标签的实际顺序,只能找到本地存在的commit关联的标签,导致拿到旧版本标签。git rev-list的排序逻辑依赖完整历史:
git rev-list --tags默认按commit提交时间倒序返回结果,但在浅克隆环境下,本地缺失大部分commit历史,这个排序会出现偏差,返回的可能不是语义化版本最新的标签,而是本地能找到的任意旧标签。标签推送后的同步延迟:当工作流推送新标签后,后续触发的工作流因为使用浅克隆,可能还未拉取到新标签对应的commit,此时即使fetch了标签,git也无法将其识别为最新标签,因为本地没有对应的commit上下文。
修复方案
- 改用完整克隆仓库:在
actions/checkout步骤中添加fetch-depth: 0,拉取完整的仓库历史,确保所有标签对应的commit都存在,git能正确识别最新标签:
- name: Check out code uses: actions/checkout@v2 with: fetch-depth: 0
- 基于语义化版本排序获取最新标签:避免依赖git的commit排序,直接对标签按版本号语义排序,修改
Get the latest tag步骤:
TAG=$(git tag -l "v*" | sort -V | tail -n1)
这个方法直接按vX.Y.Z的版本规则排序,能准确拿到最新的语义化标签,不受commit历史影响。
- 调整fetch命令获取标签关联的commit:如果必须使用浅克隆,需要修改fetch命令拉取标签对应的commit,替换原fetch步骤为:
git fetch origin --tags
不过这种方式在复杂历史下仍可能出现问题,优先推荐完整克隆方案。
内容的提问来源于stack exchange,提问作者itinance

