在 VSTS 中提交到 master 后增加版本

问题描述 投票:0回答:3

我们的应用程序在 CI 流程中使用 VSTS,并且我们要求每次代码合并回 master 时补丁版本都应增加一。

我们创建了一个 shell 脚本,它将更改应用程序的版本并标记存储库,但现在我们正在寻找流程中注入它的最佳位置。我们想到了以下几点:

  1. Master commit hook build - 把它放在这里的问题是我们用某些策略保护了 master 分支(必须解决所有评论,项目必须构建等)。因此,构建代理运行脚本无权推送更改。

  2. 拉取请求构建 - 此选项会将脚本集成到用于验证构建的构建作业中。这实际上是有效的,但是当更新被推送到分支时,这会触发无限构建循环,因为 PR 会自动重建分支。总的来说,这个选项看起来比较脆弱。

我很想解决方案 1,但尽管尽一切努力授予代理适当的角色,但它仍然无法访问存储库。我们收到以下错误:

TF402455: Pushes to this branch are not permitted; you must use a pull request to update this branch.

有没有我缺少的标准方法来做到这一点?

continuous-integration azure-devops azure-pipelines azure-pipelines-build-task
3个回答
2
投票

要通过 CI 构建更新文件版本并为新提交添加标签,您可以添加 PowerShell 任务。详细步骤如下:

  1. 在构建定义中设置权限并配置

    首先进入版本控制选项卡,为构建服务允许以下项目:

    • 创建分支:允许
    • 贡献:允许
    • 阅读:继承允许
    • 标签创建:继承允许

    然后在构建定义中,在变量选项卡中将变量

    system.prefergit
    添加为
    true
    ,并在选项选项卡中启用 允许脚本访问 OAuth 令牌

    更多详细信息,您可以参考在脚本中运行Git命令

  2. 添加powershell脚本

    git -c http.extraheader="AUTHORIZATION: bearer %SYSTEM_ACCESSTOKEN%" fetch
    git checkout master
    # Get the line of the file that contain the version
    # split the line, and only get the version number major.minor.patch.
    # check the version numbers (such as if patch less than 9) and increase the version
    #replace the old version with new version in the file
    git add .
    git commit -m 'change the version as $newVersion'
    git tag $newVersion
    git push origin master --tags
    

注意: 即使新版本和标签可以成功推送到远程仓库,PowerShell 任务也可能会失败。因此,您应该在具有自定义选项的 PowerShell 任务之后将任务设置为即使前一个任务失败。



0
投票

这是我对类似问题的回答的交叉帖子,以防万一。

2024 年投入使用
Azure DevOps 管道解决方案

@Kailash Uniyal 对他们的答案没有足够的支持,@Newteq Developer 对他们的评论也没有足够的支持。

首先,您必须向构建服务用户授予正确的权限

  • 完成拉取请求时绕过策略:允许
  • 推送时绕过策略:允许
  • 贡献:允许
  • 强制推送(重写历史记录、删除分支和标签):允许

Screenshot of aforementioned permissions for Build Service

有关访问系统令牌的签出步骤的 Microsoft 文档

如果您要创建 git 标签或执行任何可能持续存在的操作,则结帐步骤的

clean: true
配置选项至关重要。 “构建管道不会自动清除对本地存储库的某些类型的更改

这是 2024 年提供的所有答案中唯一对我有用的方法。(下面的 YAML 是一个非常基本的自定义脚本,用于基于包含常规提交消息的合并 PR 来增加语义版本控制)。

trigger:
  - main

pool:
  vmImage: "ubuntu-latest"

jobs:
  - job: PreMergeValidation
    displayName: "Pre-Merge Validation"
    condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
    steps:
      - task: PowerShell@2
        inputs:
          targetType: "inline"
          script: |
            if ($env:SYSTEM_PULLREQUEST_PULLREQUESTID) {
              # PR Validation context
              $url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/git/repositories/$($env:BUILD_REPOSITORY_ID)/pullRequests/$($env:SYSTEM_PULLREQUEST_PULLREQUESTID)?api-version=7.0"

              $headers = @{
                Authorization = "Bearer $($env:SYSTEM_ACCESSTOKEN)"
              }

              $pullRequestInfo = Invoke-RestMethod -Uri $url -Method 'GET' -ContentType 'application/json' -Headers $headers
              # Write-Host "Pull Request Info: $($pullRequestInfo | ConvertTo-Json -Depth 100)"

              $title = $pullRequestInfo.title
              Write-Host "PR Title: $title"

              # Regular expression for conventional commits
              $regex = "^(feat|fix|docs|style|refactor|perf|test|chore|build|ci|revert|BREAKING CHANGE)(\(.+\))?!?: .+"
              if ($title -notmatch $regex) {
                Write-Error "PR title does not follow Conventional Commit guidelines. Please ensure the title starts with one of the allowed types (e.g., feat, fix) followed by an optional scope and a colon."
                exit 1
              } else {
                Write-Host "PR title follows Conventional Commits format"
              }
            }
        env:
          SYSTEM_ACCESSTOKEN: $(System.AccessToken)
        displayName: "Validate PR Title against Conventional Commits"

  - job: PostMergeActions
    displayName: "Post-Merge Actions"
    condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
    steps:
      - checkout: self
        persistCredentials: true #Important - Persist creds to run further git command
        clean: true #Important - Certain kinds of changes to the local repository aren't automatically cleaned up by the build pipeline
      - task: PowerShell@2
        inputs:
          targetType: "inline"
          script: |
            git config --global user.email "[email protected]"
            git config --global user.name "ADO pipeline"

            # Fetch the latest changes
            git fetch --all

            # Ensure the branch exists and switch to it
            git checkout main

            # Read and increment the version number
            $versionFilePath = "version.txt"
            $version = Get-Content $versionFilePath
            $versionParts = $version -split '\.'

            $major = [int]$versionParts[0]
            $minor = [int]$versionParts[1]
            $patch = [int]$versionParts[2]

            $commitMessage = git log -1 --pretty=%B
            Write-Host "Latest commit message: $commitMessage"

            if ($commitMessage -match "(?i)^Merged PR \d+: BREAKING CHANGE") {
                $major++
                $minor = 0
                $patch = 0
            } elseif ($commitMessage -match "(?i)^Merged PR \d+: feat") {
                $minor++
                $patch = 0
            } else {
                $patch++
            }

            # Update the version number
            $newVersion = "$major.$minor.$patch"
            Set-Content -Path $versionFilePath -Value $newVersion
            Write-Host "Bumping version to $newVersion"

            # Commit and tag the new version
            git add $versionFilePath
            git commit -m "chore(release): bump version to $newVersion [skip ci]"
            # git tag -a "v$newVersion" -m "Release $newVersion"

            # Push changes and tags
            git push --follow-tags
        displayName: "Validate Commit Message and Bump Version"
© www.soinside.com 2019 - 2024. All rights reserved.