在Jenkins管道中生成自定义GitSCM更改日志

时间:2017-03-15 12:48:29

标签: jenkins jenkins-plugins jenkins-pipeline

我有一个Jenkins(2.36)管道工作,在那里我查看了一个git项目,我想控制更改日志中的内容:

CHANGELOG = ""
CHECK_SINCE = 1488326400

stage('Fetch') {
    node('docker') {
        checkout([$class: 'GitSCM', branches: [[name: '*/develop']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'WipeWorkspace'], [$class: 'AuthorInChangelog']], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '...', url: '...']]])
        CHANGELOG = sh(returnStdout: true, script: "git log --after ${CHECK_SINCE} --pretty=fommit %H %ntree %T %nparent %P %nauthor %an <%ae> %ad %ncommiter %cn <%ce> %cd %n %n    %s %n %n %n' --raw --no-abbrev").trim()
        docker.build("pipeline_test", "tools/build").inside {
            sh 'echo HELLO!'
        }
    }
}

stage('Update') {
    node('master') {
        fileExists "${JENKINS_HOME}/jobs/PipelineTest/jobs/${JOB_BASE_NAME}/builds/${BUILD_ID}/changelog0.xml"
        changelog_file = new File("${JENKINS_HOME}/jobs/PipelineTest/jobs/${JOB_BASE_NAME}/builds/${BUILD_ID}/changelog0.xml")
        changelog_file << CHANGELOG
    }
}

当我查看文件changelog0.xml时,内容完全符合原样:

commit b2f615ee31bc51922cdd6ca373a90b70d5c95d1b
tree 9bd57df4c9c85ee1958d7e5b3ba3ab999e18e752
parent 35c47eb0b3a0cb77574465a8136ad37a294f45ca
author ssengupta <ssengupta@gmail.com> 2017-03-10 12:53:41 +0100
committer ssengupta <ssengupta@gmail.com> 2017-03-10 12:53:41 +0100

    Some more changes.



:100644 100644 1ac06d64c274f8e2dbea325a07c15f11d2f5b4d0 6460796ab551fc1b84d25ebadbd369187fdec382 M  ReadMe.md
commit 35c47eb0b3a0cb77574465a8136ad37a294f45ca
tree 7a5cdb20288c4f3504117cfede5451e3b94fc465
parent 5b6d2f65010c0ae758c002d7a7eb0e66677c3193
author ssengupta <ssengupta@gmail.com> 2017-03-10 12:53:26 +0100
committer ssengupta <ssengupta@gmail.com> 2017-03-10 12:53:26 +0100

    Some changes



:100644 100644 dd7dbfe9ab082d444c9510f00fc79d7f72121012 1ac06d64c274f8e2dbea325a07c15f11d2f5b4d0 M  ReadMe.md

但是当我想通过点击“更改”来查看Jenkins网络前端的工作页面中的更改日志时。从左侧菜单链接,当且仅当我删除docker.build().inside{}块时,才会显示更改日志。否则它是空的。

我尝试为每个版本设置一个唯一的图片名称。我试过在各个地方引入延误。没有帮助。

更改内容是什么让更改日志在网络前端显示为空?我该如何解决?

更新

我还尝试了另一种方法:更新currentBuild.changeSets而不是写入changelog0.xml。管道脚本如下所示:

import hudson.plugins.git.GitChangeSet

CHANGELOG = ""
CHECK_SINCE = 1488326400

stage('Fetch') {
    node('docker') {
        checkout([$class: 'GitSCM', branches: [[name: '*/develop']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'WipeWorkspace'], [$class: 'AuthorInChangelog']], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '...', url: '...']]])
        CHANGELOG = sh(returnStdout: true, script: "git log --after ${CHECK_SINCE} --pretty=fommit %H %ntree %T %nparent %P %nauthor %an <%ae> %ad %ncommiter %cn <%ce> %cd %n %n    %s %n %n %n' --raw --no-abbrev").trim()
        docker.build("pipeline_test", "tools/build").inside {
            sh 'echo HELLO!'
        }
        def modified_changes = new GitChangeSet(CHANGELOG.readLines(), true)
        currentBuild.rawBuild.changeSets << modified_changes
    }
}

虽然我不是Java开发人员,但我希望上面的代码能够做一些有意义的事情,因为GitChangeSet具有构造函数public GitChangeSet(List<String> lines, boolean authorOrCommitter)

管道成功执行。但是,当我点击“更改”时,在网络前端链接,我得到了这个:

org.apache.commons.jelly.JellyTagException: jar:file:/var/lib/jenkins/plugins/workflow-job/WEB-INF/lib/workflow-job.jar!/org/jenkinsci/plugins/workflow/job/WorkflowRun/changes.jelly:33:67: <st:include> No page found 'index.jelly' for class hudson.plugins.git.GitChangeSet
    at org.kohsuke.stapler.jelly.IncludeTag.doTag(IncludeTag.java:124)
    at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
    at org.apache.commons.jelly.TagSupport.invokeBody(TagSupport.java:161)
    at org.apache.commons.jelly.tags.core.ForEachTag.doTag(ForEachTag.java:150)
    at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
    at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
    at org.kohsuke.stapler.jelly.CallTagLibScript$1.run(CallTagLibScript.java:99)
    at org.apache.commons.jelly.tags.define.InvokeBodyTag.doTag(InvokeBodyTag.java:91)
    at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
    at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
    at org.apache.commons.jelly.tags.core.CoreTagLibrary$1.run(CoreTagLibrary.java:98)
    at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
    at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
    at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:120)
    at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
    at org.kohsuke.stapler.jelly.CallTagLibScript$1.run(CallTagLibScript.java:99)
    at org.apache.commons.jelly.tags.define.InvokeBodyTag.doTag(InvokeBodyTag.java:91)
    at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
    at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
    at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99)
    at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
    at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99)
    at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
    at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99)
    at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
    at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99)
    at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
    at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
    at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:120)
    at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
    at org.kohsuke.stapler.jelly.JellyViewScript.run(JellyViewScript.java:95)
    at org.kohsuke.stapler.jelly.DefaultScriptInvoker.invokeScript(DefaultScriptInvoker.java:63)
    at org.kohsuke.stapler.jelly.DefaultScriptInvoker.invokeScript(DefaultScriptInvoker.java:53)
    at org.kohsuke.stapler.jelly.JellyFacet$1.dispatch(JellyFacet.java:97)
    at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:715)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:845)
    at org.kohsuke.stapler.MetaClass$10.dispatch(MetaClass.java:374)
    at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:715)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:845)
    at org.kohsuke.stapler.MetaClass$5.doDispatch(MetaClass.java:248)
    at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
    at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:715)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:845)
    at org.kohsuke.stapler.MetaClass$5.doDispatch(MetaClass.java:248)
    at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
    at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:715)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:845)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:649)
    at org.kohsuke.stapler.Stapler.service(Stapler.java:238)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:135)
    at com.smartcodeltd.jenkinsci.plugin.assetbundler.filters.LessCSS.doFilter(LessCSS.java:47)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:132)
    at org.jenkinsci.plugins.modernstatus.ModernStatusFilter.doFilter(ModernStatusFilter.java:52)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:132)
    at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:126)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
    at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:49)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:84)
    at hudson.security.UnwrapSecurityExceptionFilter.doFilter(UnwrapSecurityExceptionFilter.java:51)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at jenkins.security.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:117)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:142)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:271)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at jenkins.security.BasicHeaderProcessor.doFilter(BasicHeaderProcessor.java:93)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:249)
    at hudson.security.HttpSessionContextIntegrationFilter2.doFilter(HttpSessionContextIntegrationFilter2.java:67)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at hudson.security.ChainedServletFilter.doFilter(ChainedServletFilter.java:76)
    at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:171)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
    at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:49)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
    at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:82)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
    at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:30)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:553)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
    at org.eclipse.jetty.server.Server.handle(Server.java:499)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
    at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
    at winstone.BoundedExecutorService$1.run(BoundedExecutorService.java:77)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused: javax.servlet.ServletException
    at org.kohsuke.stapler.jelly.JellyFacet$1.dispatch(JellyFacet.java:105)
    at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:715)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:845)
    at org.kohsuke.stapler.MetaClass$10.dispatch(MetaClass.java:374)
    at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:715)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:845)
    at org.kohsuke.stapler.MetaClass$5.doDispatch(MetaClass.java:248)
    at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
    at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:715)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:845)
    at org.kohsuke.stapler.MetaClass$5.doDispatch(MetaClass.java:248)
    at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
    at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:715)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:845)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:649)
    at org.kohsuke.stapler.Stapler.service(Stapler.java:238)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:135)
    at com.smartcodeltd.jenkinsci.plugin.assetbundler.filters.LessCSS.doFilter(LessCSS.java:47)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:132)
    at org.jenkinsci.plugins.modernstatus.ModernStatusFilter.doFilter(ModernStatusFilter.java:52)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:132)
    at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:126)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
    at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:49)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:84)
    at hudson.security.UnwrapSecurityExceptionFilter.doFilter(UnwrapSecurityExceptionFilter.java:51)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at jenkins.security.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:117)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:142)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:271)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at jenkins.security.BasicHeaderProcessor.doFilter(BasicHeaderProcessor.java:93)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:249)
    at hudson.security.HttpSessionContextIntegrationFilter2.doFilter(HttpSessionContextIntegrationFilter2.java:67)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at hudson.security.ChainedServletFilter.doFilter(ChainedServletFilter.java:76)
    at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:171)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
    at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:49)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
    at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:82)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
    at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:30)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:553)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
    at org.eclipse.jetty.server.Server.handle(Server.java:499)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
    at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
    at winstone.BoundedExecutorService$1.run(BoundedExecutorService.java:77)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

3 个答案:

答案 0 :(得分:1)

我真的不明白你的问题,但是管道不支持使用Java File API - 它不会像你期望的那样运行。

你真的应该避免直接写入$JENKINS_HOME目录 - 将文件写入构建工作区,然后使用archiveArtifacts步骤确保它存储在Jenkins主程序中。

您可以使用writeFile step执行此操作,例如:

def changelog = sh returnStdout: true, script: "git log …"
writeFile file: 'changelog0.xml', text: changelog
archiveArtifacts 'changelog0.xml'

另请注意,您应该在同一checkout块中运行git lognode('docker')步骤(但它们仍然可以位于单独的stage块中node)。否则,无法保证在这两种情况下都能获得相同的工作空间,因此当您致电git log时,您可能会遇到空的或过时的工作空间。

答案 1 :(得分:1)

如果完成所有必要的脚本批准,则以下管道脚本应向更改日志添加1个提交。

import hudson.scm.SubversionSCM
import hudson.scm.SubversionChangeLogParser

node('master') {
  stage('build')
  {

  }
  stage('test') {
    writeFile file: 'changelog.xml', text: '''<?xml version="1.0" encoding="UTF-8"?>
<log>
  <logentry revision="12344">
    <author>me</author>
    <date>2017-12-21T16:57:06.737430Z</date>
    <paths>
      <path prop-mods="false" text-mods="true" kind="file" action="M">/path/to/repo/modified/file.cpp</path>
    </paths>
    <msg>my commit message</msg>
  </logentry>
</log>'''
    def parser = new SubversionChangeLogParser(false)
    def file = new File(env.WORKSPACE,"changelog.xml")
    def modified_changesets = parser.parse(currentBuild.rawBuild, null, file)
    currentBuild.rawBuild.changeSets.add(modified_changesets)
  }
}

答案 2 :(得分:0)

我正在寻找类似的解决方案,最后得到了这个:-

而不是更新当前变量 currentBuild.rawBuild.changeSets

在管道/管道库中的checkout语句之前使用它-

 currentBuild.getChangeSet().clear()

因此,一旦currentChangeSet被清除,它将从下一个git checkout获取更改,您可以使用checkout()或git plugin语法进行更改。它还会根据您在Pipeline中指定的存储库中的提交(而不是托管Pipeline的存储库中的提交)更新changelog0.xml(如果您正在开发自己的Pipeline Library

现在,您可以照常使用$ CHANGES变量来进一步使用它。