在TeamCity中创建变更日志工件

16

有没有一种简单的方法使TeamCity包括文本或HTML变更日志作为其输出构件之一?

也许我需要采用msbuild或其他某个过程来创建变更日志,但由于TeamCity为每个构建生成一个变更日志,因此我想知道是否已经有一种简单的方法可以访问它并将其包含在构件路径指令中,以便它可以成为发布包的一部分。


你能澄清一下这个日志是从哪里生成的吗?通常将文件作为工件附加应该不会有问题。 - Ray 'user1578904'
4个回答

15

是的,变更日志可以作为文件访问,此文件的路径在TeamCity构建参数中:

%system.teamcity.build.changedFiles.file%

所以您可以这样做:

  • 将命令行构建步骤添加到您的构建中。
  • 使用类型为“自定义脚本”的类型。
  • 输入此脚本:
copy "%system.teamcity.build.changedFiles.file%" changelog.txt
  • 最后,编辑您的构建工件规则以将changelog.txt包括在您的工件中(通用设置->工件路径->添加“changelog.txt”)。

+1 这对我来说是一个不错的开始。但是 changelog.txt 文件缺少与列出的每个文件相关联的注释。您知道是否有一种方法可以同时包含注释吗? - slolife
1
不这么认为。我们有同样的需求,最终开发了一个控制台应用程序来访问TC的rest api以获取提交注释。然后将运行此控制台应用程序添加为最终构建步骤。 - peter_raven
你能分享一下那段代码吗?或者解释一下你从TC获取了哪些数据/参数来调用控制台应用程序? - slolife

13

您可以通过TeamCity的REST API生成变更日志。这里可以找到相应的PowerShell脚本here

适用于TeamCity v10.x及以上版本:

<#
.SYNOPSIS
    Generates a project change log file.
.LINK
    Script posted over:
    http://open.bekk.no/generating-a-project-change-log-with-teamcity-and-powershell
    Also See https://dev59.com/w2855IYBdhLWcg3weUQQ

#>

# Where the changelog file will be created
$outputFile = "%system.teamcity.build.tempDir%\releasenotesfile_%teamcity.build.id%.txt"
# the url of teamcity server
$teamcityUrl = "%teamcity.serverUrl%"
# username/password to access Teamcity REST API
$authToken=[Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("%system.teamcity.auth.userId%:%system.teamcity.auth.password%"))
# Build id for the release notes
$buildId = %teamcity.build.id%

# Get the commit messages for the specified change id
# Ignore messages containing #ignore
# Ignore empty lines
Function GetCommitMessages($changeid)
{
    $request = [System.Net.WebRequest]::Create("$teamcityUrl/httpAuth/app/rest/changes/id:$changeid")     
    $request.Headers.Add("AUTHORIZATION", "Basic $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'))} |
        foreach {"+ $($_.Node["user"].name) : $($_.Node["comment"].InnerText.Trim().Replace("`n"," "))`n"}
}

# Grab all the changes
$request = [System.Net.WebRequest]::Create("$teamcityUrl/httpAuth/app/rest/changes?build=id:$($buildId)")
$request.Headers.Add("AUTHORIZATION", "Basic $authToken");
$xml = [xml](new-object System.IO.StreamReader $request.GetResponse().GetResponseStream()).ReadToEnd()

# Then get all commit messages for each of them
$changelog = Microsoft.PowerShell.Utility\Select-Xml $xml -XPath "/changes/change" | Foreach {GetCommitMessages($_.Node.id)}
$changelog > $outputFile
Write-Host "Changelog saved to ${outputFile}:"
$changelog

对于 Teamcity v10.x 之前的版本:

<#
.SYNOPSIS
    Generates a project change log file.
.LINK
    Script posted over:
    http://open.bekk.no/generating-a-project-change-log-with-teamcity-and-powershell
    Also See https://dev59.com/w2855IYBdhLWcg3weUQQ
#>

# Where the changelog file will be created
$outputFile = "%system.teamcity.build.tempDir%\releasenotesfile_%teamcity.build.id%.txt"
# the url of teamcity server
$teamcityUrl = "%teamcity.serverUrl%"
# username/password to access Teamcity REST API
$authToken=[Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("%system.teamcity.auth.userId%:%system.teamcity.auth.password%"))
# Build id for the release notes
$buildId = %teamcity.build.id%

# Get the commit messages for the specified change id
# Ignore messages containing #ignore
# Ignore empty lines
Function GetCommitMessages($changeid)
{
    $request = [System.Net.WebRequest]::Create("$teamcityUrl/httpAuth/app/rest/changes/id:$changeid")     
    $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'))} |
        foreach {"+ $($_.Node["user"].name) : $($_.Node["comment"].InnerText.Trim().Replace("`n"," "))`n"}
}

# Grab all the changes
$request = [System.Net.WebRequest]::Create("$teamcityUrl/httpAuth/app/rest/changes?build=id:$($buildId)")
$request.Headers.Add("AUTHORIZATION", "$authToken");
$xml = [xml](new-object System.IO.StreamReader $request.GetResponse().GetResponseStream()).ReadToEnd()

# Then get all commit messages for each of them
$changelog = Microsoft.PowerShell.Utility\Select-Xml $xml -XPath "/changes/change" | Foreach {GetCommitMessages($_.Node.id)}
$changelog > $outputFile
Write-Host "Changelog saved to ${outputFile}:"
$changelog

1
这是一个非常棒的脚本,它可以完美地执行它应该做的事情,而无需任何进一步的配置。 - Sergii Volchkov
5
在TeamCity 10.x中使用上述脚本的人需要更新AUTHORIZATION标头为"Basic $authToken"。 - Hastarin
这太棒了。社区贡献真是太棒了。 - KnowHoper
感谢Hastarin提供的提示! - timmkrause
为什么在2020年这么难?TC有这些信息。每个人都想使用它(自动化,放入文件并发送到某个地方:部署,构建发布页面等),但你仍然必须使用REST API? :/ - dariol
显示剩余3条评论

0
上述脚本是有效的,但它只包括当前构建的签入注释。因此,我稍微修改了这个脚本,以便它包括自上次成功构建以来的所有更改。在Teamcity中,要获取最后一个成功构建的编号有些棘手,所以我只获取最近的10个构建,然后迭代这些更改,直到找到最后一个成功构建为止。
<#
.SYNOPSIS
Generates a project change log file.
.LINK
Script posted over:
http://open.bekk.no/generating-a-project-change-log-with-teamcity-and-powershell
#>

# Where the changelog file will be created
$outputFile = 
"%system.teamcity.build.tempDir%\releasenotesfile_%teamcity.build.id%.txt"
# Get the commit messages for the specified change id
# Ignore messages containing #ignore
# Ignore empty lines

# the url of teamcity server
$teamcityUrl = "%teamcity.serverUrl%"

# username/password to access Teamcity REST API
$authToken=[Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("%system.teamcity.auth.userId%:%system.teamcity.auth.password%"))
# Build id for the release notes
$buildId = %teamcity.build.id%
#unique id of the project
$buildType = "%system.teamcity.buildType.id%"
$changelog =""

Function GetCommitMessages($changeid)
{   
    $request = [System.Net.WebRequest]::Create("$teamcityUrl/httpAuth/app/rest/changes/id:$changeid")     
    $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'))} |
    foreach {"+ $($_.Node["user"].name) : $($_.Node["comment"].InnerText.Trim().Replace("`n"," "))`n"}
}

# Grab the previous 10 builds together with their changes
$request = [System.Net.WebRequest]::Create($teamcityUrl +'/httpAuth/app/rest/builds? 
locator=untilBuild:(id:'+$buildId +'),count:10,running:any,buildType: 
(id:'+$buildType+')&fields=$long,build(id,number,status,changes($long))')
$request.Headers.Add("AUTHORIZATION", $authToken);
$xml = [xml](new-object System.IO.StreamReader 
$request.GetResponse().GetResponseStream()).ReadToEnd()

# Then get all commit messages for each of them
Foreach($x in Microsoft.PowerShell.Utility\Select-Xml $xml -XPath 
"/builds/build/changes/change") 
{    
#we collect the changes until we've found the previous successfull build. so we must always collect the changes of the current build and then stop once we find a succesful build
if($x.Node.ParentNode.ParentNode.status -eq "SUCCESS" -and $x.Node.ParentNode.ParentNode.id -ne $buildId)
  { break;}
   $changelog +=GetCommitMessages($x.Node.id)  
}

$changelog > $outputFile
Write-Host "Changelog saved to ${outputFile}:"
$changelog

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接