使用 VSTS API 在 VSTS 中连续 integration/continuous 交付过程中将文件提交到 Git

Commit a file to Git during continuous integration/continuous delivery process in VSTS using VSTS API

我们在 VSTS 中配置了多个使用不同数据库的发布环境。这些环境中的每个数据库都包含控制应用程序工作方式的特定元数据。此元数据由管理工具定期配置给用户。

我们想要备份此元数据并在每次发布时将其签入 Git,以便我们将其保存在某个地方,以防数据丢失或需要比较以前的版本。我们有一个实用程序可以从生成 XML 文件的数据库中提取此元数据,因此我将 运行 这个实用程序,然后使用 VSTS 中的任务以某种方式将其放入 Git 中。如果可以做到这一点,我们还计划将我们的 VSTS 版本定义导出到 JSON 并将其也检查到 Git。

如何在发布定义阶段将文件签入存储库?

虽然我通常认为发布到也会触发您的构建的源代码库不是一个好主意,但它相对容易。

您可以调用 git.exe 作为构建的一部分。您可能需要调整存储库设置以克隆整个存储库,而不仅仅是浅克隆。如果您允许访问它,您可以传入构建作业的 OAuth 令牌:

可以看看VSTS自己是如何添加授权的headers:

git remote add origin https://jessehouwing.visualstudio.com/
git config --get-all http.https://jessehouwing.visualstudio.com/_git/Torpydo.extraheader
git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" fetch --tags --prune --progress --no-recurse-submodules origin

备选方案

VSTS 中的每个构建都有一个 "Artefacts" 的概念。您可以使用复制和发布构建工件 任务来捕获数据并确保它们不会丢失。

构建历史

如果您希望自己的构建受源代码控制,请务必查看新的 YAML 构建支持:

经过一些研究并在几个小时后在 Postman/VSTS 中进行测试 - 我能够编写一个 powershell 脚本,该脚本向 VSTS 发送 API 请求并将文件提交到存储库。

我引用了 Create a push documentation here。我需要确定 JSON 请求的以下属性的正确值:

  • oldObjectId - 在任何地方都没有完整记录。这里需要的值可以通过调用list refs API返回。我相信这类似于 git show HEAD
  • changeType
  • contentType

这是一个检索最新的 objectId 以用作 oldObjectId 值的示例:

Invoke-RestMethod -Uri "https://{accountName}.visualstudio.com/DefaultCollection/{project}/_apis/git/repositories/{repositoryId}/refs?filter=heads%2Fmaster&api-version=4.1-preview" -Method Get -Headers $header

我的下一个任务是准备新内容 属性。因为我试图上传一个 XML 文件,所以 rawText 是不可能的,因为所有的特殊字符。唯一允许的其他 contentType 是 base64Encoded

我必须使用 Powershell 的 Get-Content cmdlet 并启用 -Raw 开关才能成功对内容进行 base64 编码。我从之前制作的另一个 那里得知,当时我遇到 XML 的格式问题。

$xmlData = Get-Content -Path $xmlFile -Raw
$xmlDataEncoded = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($xmlData))

然后,为了确定我是在添加新文件还是修改现有文件,我需要向脚本添加逻辑以检查文件是否存在并将 changeType 设置为 addedit。见下文:

$xmlDataRepo = Invoke-RestMethod -Uri "{accountName}.visualstudio.com/DefaultCollection/{project/_apis/git/repositories/{project}/items/?recursionLevel=OneLevel&api-version=4.1-preview" -Method Get -Headers $header
ForEach-Object -InputObject $xmlDataRepo.value -Process {if ($_.path -eq $repoXmlFile) {$changeType = "edit"} else {$changeType = "add"}}

最后,现在我已经收集了所有信息并对我的 XML 内容进行了编码。我需要构建请求正文并调用 API。这是请求的正文:

$body = @"
{
    "refUpdates": [
    {
        "name": "refs/heads/master",
        "oldObjectId": "$objectId"
    }
    ],
    "commits": [
    {
        "comment": "Data backed up",
        "changes": [
        {
            "changeType": "$changeType",
            "item": {
                "path": "$repoXmlFile"
            },
            "newContent": {
                "content": "$xmlDataEncoded",
                "contentType": "base64Encoded"
            }
        }
        ]
    }
    ]
}
"@

最后,樱桃在上面:

Invoke-RestMethod -Uri "https://{accountName}.visualstudio.com/DefaultCollection/{project/_apis/git/repositories/{project}/pushes?api-version=4.1-preview" -Method Post -Headers $header -Body $body -ContentType application/json

希望对您有所帮助