简体   繁体   中英

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.

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.

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.

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

  3. Push to NuGet feed

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.

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.

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.

Powershell functions to get the changed files and commit log. 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.

# 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 />" }
        }   
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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