【问题标题】:Commit a file to Git during continuous integration/continuous delivery process in VSTS using VSTS API在 VSTS 中使用 VSTS API 在持续集成/持续交付过程中将文件提交到 Git
【发布时间】:2018-03-01 20:02:55
【问题描述】:

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

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

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

【问题讨论】:

  • 由于您通过 REST API 解决了您的问题,您可以添加答案并接受它。

标签: git azure-devops azure-pipelines azure-pipelines-release-pipeline


【解决方案1】:

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

我引用了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

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

我必须使用 Powershell 的 Get-Content cmdlet 并启用 -Raw 开关才能成功对内容进行 base64 编码。我是从另一个StackOverflow post 那里了解到的,这是我之前遇到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

希望有帮助

【讨论】:

    【解决方案2】:

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

    您可以在构建过程中调用git.exe。您可能需要调整存储库设置以克隆整个存储库,而不仅仅是浅层克隆。如果您启用对它的访问权限,则可以传入构建作业的 OAuth 令牌:

    您可以看到 VSTS 本身是如何添加授权标头的:

    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 中的每个构建都有一个“人工制品”的概念。您可以使用复制和发布构建工件任务来捕获数据并确保它们不会丢失。

    构建历史

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

    【讨论】:

    • 谢谢 - 我浏览了 VSTS API 文档,发现他们有一个 API 调用可能会做类似的事情。 visualstudio.com/en-us/docs/integrate/api/git/… 这个 API 调用看起来我可以发送一个更新的文件。您是否听说过用于从存储库添加/更新/删除文件的 API 调用?
    • 这也可以。我仍然建议使用构建工件而不是推回 git。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    • 2018-07-28
    • 2017-07-18
    • 1970-01-01
    相关资源
    最近更新 更多