如何正确触发 TeamCity 在 git 上构建单个包?

How to properly trigger TeamCity to build for a single package on git?

我有一个项目的 Git 存储库,其中包含我已添加到 TeamCity 的各种包。

repo 是这样组织的:

README.md
packages/
packages/buildscript
packages/packageOne/manifest (and files)
packages/packageTwo/manifest (and files)
packages/packageThree/manifest (and files)

我想将 TeamCity 配置为在修改或添加到存储库时执行构建脚本来构建特定包。

我有 运行 构建脚本作为构建步骤的一部分,但我不知道如何确保下载每个包以及每个包的构建脚本 运行。

目前构建脚本采用包名,做一些工作,然后运行 ​​NuGet 包。

我是否正确地认为我必须编写构建步骤来检测哪些包已更改,然后对每个包执行所需的操作?像这样:

  1. 拉包

  2. 运行 包上的构建脚本

  3. 推送到 NuGet 源

或者是否有执行其中某些步骤的内置功能?

编辑:

目前我已将其设置为在对 Git 存储库进行更改后,重新构建所有包...这显然很麻烦。

如果我想让它们单独触发,我似乎需要为每个包创建一个构建配置。

我想到的一个解决方案是让一个步骤确定哪些包自上次构建以来已更新,然后为每个包执行构建脚本。因此,我现在正在寻求有关有效方法的建议,可能涉及某些构建步骤脚本中的 运行 Git 命令。

您有两个选择:

  1. 为每个包设置一个单独的构建配置,添加一个触发器,该触发器仅在该包目录中的文件发生更改时才执行构建。
  2. 作为构建的一部分,获取已更改的文件列表(参见 TeamCity, how to get names of the files edited 的一种方式,或使用 TeamCity API,如下例),读取这些更改并仅触发构建对于已更改的包。

Powershell 函数用于获取更改的文件和提交日志。只是我的设置的复制粘贴。这些功能需要你传入服务器 Url、用户名、密码和构建 ID,所有这些你都可以在 TeamCity 中运行时获得。

# Gets the change log for the specified build ID
function TeamCity-GetChangeLog($serverUrl, $username, $password, $buildId){
    $buildUrl = "$serverUrl/httpAuth/app/rest/changes?build=id:$($buildId)"
    $authToken = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($username + ":" + $password))

    # Get all the changes
    $request = [System.Net.WebRequest]::Create($buildUrl)
    $request.Headers.Add("AUTHORIZATION", "$authToken");
    $xml = [xml](new-object System.IO.StreamReader $request.GetResponse().GetResponseStream()).ReadToEnd()

    # Get all commit messages for each of them
    $changelog = Microsoft.PowerShell.Utility\Select-Xml $xml -XPath `
        "/changes/change" | Foreach {
            TeamCity-GetCommitMessage $serverUrl $username $password $_.Node.id
        }

    return $changelog
}

# Get the commit messages, and files changed for the specified change id
# Ignores empty lines, lines containing "#ignore", "merge branch"" or "TeamCity"
Function TeamCity-GetCommitMessage($serverUrl, $username, $password, $changeId)
{
    $getFilesChanged = $false;
    $request = [System.Net.WebRequest]::Create("$serverUrl/httpAuth/app/rest/changes/id:$changeId")
    $authToken = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($username + ":" + $password))    
    $request.Headers.Add("AUTHORIZATION", "$authToken");

    $xml = [xml](new-object System.IO.StreamReader $request.GetResponse().GetResponseStream()).ReadToEnd()

    Microsoft.PowerShell.Utility\Select-Xml $xml -XPath "/change" |
        where { ($_.Node["comment"].InnerText.Length -ne 0) `
        -and (-Not $_.Node["comment"].InnerText.Contains('#ignore')) `
        -and (-Not $_.Node["comment"].InnerText.StartsWith("Merge branch")) `
        -and (-Not $_.Node["comment"].InnerText.StartsWith("TeamCity change"))} |
        foreach {
            $getFilesChanged = $true;
            "<br /><strong>$($_.Node["user"].name.Trim() + " on " + ([System.DateTime]::ParseExact($_.Node.Attributes["date"].Value, "yyyyMMddTHHmmsszzzz", [System.Globalization.CultureInfo]::InvariantCulture)))</strong><br /><br />"

            "$($_.Node["comment"].InnerText.Trim().Replace("`n", "`n<br />"))"
        }

    if ($getFilesChanged) {
        "<br /><br /><strong>Files Changed</strong><br /><br />"
        Microsoft.PowerShell.Utility\Select-Xml $xml -XPath "/change/files" |
        where { ($_.Node["file"].Length -ne 0)} |    
        foreach { Select-Xml $_.Node -XPath 'file' |
            foreach { "$($_.Node.Attributes["file"].Value)<br />" }
        }   
    }
}