简体   繁体   English

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

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

I have a Git repo for a project containing various packages that I have added to TeamCity. 我有一个项目的Git存储库,其中包含我已添加到TeamCity的各种软件包。

The repo is organized like this: 回购的组织方式如下:

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

I want to configure TeamCity to execute the buildscript to build a particular package when it is either modified or added to the repo. 我想配置TeamCity来执行构建脚本,以在修改或添加到仓库中时构建特定的程序包。

I've got running the buildscript as part of the build steps, but I don't know how to make sure that each package is downloaded and the buildscript ran for each one. 作为构建步骤的一部分,我已经运行了构建脚本,但是我不知道如何确保下载了每个软件包并为每个构建了构建脚本。

Currently the buildscript takes a package name, does some work, and then runs a NuGet pack. 当前,构建脚本采用包名称,进行一些工作,然后运行NuGet包。

Am I correct in thinking that I have to write build steps that detect which packages have been changed, and then does the required actions per package? 我是否正确地认为必须编写构建步骤来检测哪些软件包已更改,然后对每个软件包执行必要的操作? Like this: 像这样:

  1. Pull package 拉包

  2. Run buildscript on package 在包上运行buildscript

  3. Push to NuGet feed 推送至NuGet提要

Or is there built-in functionality for doing some of these steps? 还是有内置功能可以执行某些步骤?

Edit: 编辑:

Currently I have it set up so that after changes are made to the Git repo, all packages are rebuilt... which is obviously cumbersome. 目前,我已经进行了设置,以便在对Git存储库进行更改之后,可以重新构建所有软件包……这显然很麻烦。

It seems that I need to either create a build configuration for each package if I want them to trigger individually. 如果希望它们分别触发,似乎需要为每个软件包创建一个构建配置。

One solution that occurs to me is to have one step that determines which packages have been updated since the last build and then executes the build script for each of them. 我想到的一个解决方案是第一步,确定自上次构建以来已更新了哪些软件包,然后针对每个软件包执行构建脚本。 Thus, I am now seeking advise on effective ways of doing so, probably involving running Git commands in some build step scripts. 因此,我现在正在寻求有关有效方法的建议,可能涉及在某些构建步骤脚本中运行Git命令。

You have two options: 您有两种选择:

  1. Setup a separate build configuration for each package, add a trigger that will only do a build if the files in that package directory have changed. 为每个软件包设置一个单独的构建配置,添加一个仅在该软件包目录中的文件已更改时才进行构建的触发器。
  2. As part of your build, get the list of files changed (see TeamCity, how to get names of the files edited for one way, or use the TeamCity API, example below), read those changes and only trigger a build for the package that has changed. 作为构建的一部分,获取已更改文件的列表(请参见TeamCity,如何以一种方式编辑文件的名称 ,或使用TeamCity API,如下例所示),读取这些更改并仅触发该软件包的构建已经改变。

Powershell functions to get the changed files and commit log. Powershell可以获取更改的文件并提交日志。 Just a copy paste of my setup. 只是我的设置的副本粘贴。 These functions require you to pass in the server Url, username, password and build ID, all of which you can get at runtime in TeamCity. 这些功能要求您传入服务器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 />" }
        }   
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM