Create changelog artifact in TeamCity

前端 未结 4 1582
半阙折子戏
半阙折子戏 2021-02-01 07:40

Is there a simple way to have TeamCity include a text or html change-log as one of its output artifacts?

Perhaps I need to go down the route of having msbuild or some ot

相关标签:
4条回答
  • 2021-02-01 08:01

    Possible you should use Service Messages

    0 讨论(0)
  • 2021-02-01 08:09

    You can generate a change log via the REST API of TeamCity. A PowerShell script for this can be found here

    For TeamCity v10.x & above:

    <#
    .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
    

    For versions before 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
    
    0 讨论(0)
  • 2021-02-01 08:15

    Yes, the change-log is accessible as a file, path to this file is in the TeamCity build parameter:

    %system.teamcity.build.changedFiles.file%
    

    So you could do this:

    • Add a command-line build step to your build.
    • Use type Custom Script.
    • Enter this script:
    copy "%system.teamcity.build.changedFiles.file%" changelog.txt
    
    • Finally edit the artifact rules for your build to include the changelog.txt in your artifacts (General settings -> Artifact paths -> Add "changelog.txt").
    0 讨论(0)
  • 2021-02-01 08:28

    The above script works, however it only includes check in comments of the current build. So I've slightly amended this script so that it does include all changes since the last successful build. In Teamcity it's tricky to get the last successful build number so that's why I just get the last 10 builds and then iterate over these changes until I've found the last successful build.

    <#
    .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
    
    0 讨论(0)
提交回复
热议问题