【问题标题】:Create changelog artifact in TeamCity在 TeamCity 中创建变更日志工件
【发布时间】:2019-05-24 19:50:15
【问题描述】:

是否有一种简单的方法可以让 TeamCity 将文本或 html 更改日志作为其输出工件之一包含在内?

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

【问题讨论】:

  • 你能澄清这个日志是从哪里生成的吗?通常将文件作为人工制品附加应该不是问题。

标签: continuous-integration teamcity changelog


【解决方案1】:

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

%system.teamcity.build.changedFiles.file%

所以你可以这样做:

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

【讨论】:

  • +1 这对我来说是一个好的开始。但是 changelog.txt 文件缺少与列出的每个文件关联的 cmets。你知道是否有办法让 cmets 也包含在内?
  • 不这么认为。我们有同样的要求,最终制作了一个控制台应用程序,它可以访问 TC 的 rest api 来获取提交 cmets。然后将运行此控制台应用程序添加为最后的构建步骤。
  • 您有机会分享该代码吗?或者解释一下你从 TC 那里得到什么数据/参数来调用控制台应用程序?
【解决方案2】:

您可以通过 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://stackoverflow.com/questions/4317409/create-changelog-artifact-in-teamcity

#>

# 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://stackoverflow.com/questions/4317409/create-changelog-artifact-in-teamcity
#>

# 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

【讨论】:

  • 这是一个很棒的脚本,它可以完全完成它应该做的事情,而无需任何进一步的配置。
  • 不错的脚本。正是我想要的
  • 在 TeamCity 10.x 中使用上述脚本的任何人都希望将 AUTHORIZATION 的标头更新为“Basic $authToken”。
  • 这太棒了。很棒的社区贡献。
  • 感谢 Hastarin 的提示!
【解决方案3】:

可能你应该使用Service Messages

【讨论】:

    【解决方案4】:

    上面的脚本可以工作,但是它只包括当前构建的 cmets 的签入。 所以我稍微修改了这个脚本,使它包含自上次成功构建以来的所有更改。 在 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-08
      • 2023-03-13
      • 2020-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多