【问题标题】:Generating Custom GitSCM Changelog in Jenkins Pipeline在 Jenkins 流水线中生成自定义 GitSCM 变更日志
【发布时间】:2017-08-06 05:17:53
【问题描述】:

我有一个 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 Web 前端的工作页面查看更改日志时,当且仅当我删除 docker.build().inside{} 块时,更改日志才可见。否则为空。

我尝试为每个构建设置一个唯一的图像名称。我尝试在各个地方引入延迟。没有帮助。

是什么导致更改日志在 Web 前端显示为空?我该如何解决?

更新

我还尝试了一种不同的方法:更新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&lt;String&gt; 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)

【问题讨论】:

  • 为什么您希望更改信息不准确? Jenkins 会自动向您显示自上次构建以来的提交。此外,您不能将纯文本 git 日志写入内部 Jenkins XML 文件。无论如何,Docker Build 插件做了一些指纹识别,但我不知道它会改变更改的原因。
  • 监控管道的人完全有可能希望看到自上次夜间构建以来的变化,而不仅仅是上次成功构建。在构建过程中,可能会调用一些外部依赖管理器,如“gitman”或“bower”,并且用户希望看到子模块的更改,因此在同一个更改日志中更新。它是否不准确取决于用户想要什么,对吧?
  • 这对我来说暗示了一个奇怪的工作设置,但是是的,你可以做到——我再次认为将你自己的变更集添加到构建中可能是最好的方法。
  • 你应该使用 currentBuild.rawBuild.changeSets.add() 或 currentBuild.rawBuild.changeSets.push() 而不是语法 currentBuild.rawBuild.changeSets &lt;&lt; modified_changes

标签: jenkins jenkins-plugins jenkins-pipeline


【解决方案1】:

我不太明白您的问题,但 Pipeline 不支持使用 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'

还请注意,您应该在同一 node('docker') 块中同时运行 checkout 和 git log 步骤(尽管它们仍然可以在单独的 stage 块中,在 node 内)。否则,不能保证在这两种情况下您都会获得相同的工作空间,因此当您调用git log 时,您可能会进入一个空的或过时的工作空间。

【讨论】:

  • 重新阅读我的问题后,听起来确实具有误导性。我已经编辑过了。你能再看看吗?写入changelog0.xml 总是成功的,当我登录 Jenkins master 并查看文件时,内容总是相同的。所以问题是,当我删除 docker 容器调用而不是其他方式时,为什么 Jenkins 会在作业更改日志(在 Web 前端)中显示更改?根据 Jenkins 文档,changelog0.xml 是构建结构的一部分。我必须明确存档吗?
  • 您的问题现在更有意义了,但我的建议仍然适用:) 文档可能会引用 builds 文件夹下的 changelog.xml,但您不应该自己编写此文件。尤其不是纯文本。它应该是 XML。无法存档文件以使其显示在更改中。但是,您可以使用 Jenkins API 将 Changeset 对象添加到 currentBuild.rawBuild 对象。
  • 当 GitSCM 插件自己构建变更日志时,这也不是 XML。它使用一些格式化参数调用git whatchanged 并将结果转储到那里。至少 3.0.1 是这样。我已经阅读了插件开发的变更日志,因为我没有看到它在某处提到他们已经切换到 XML。
  • 通过自己迭代git log 的结果来填充currentBuild.rawBuild.changeSets 似乎是一个相当复杂的过程。某处必须有一个解析方法。但我没有找到任何使用它的例子。
  • 对不起,你确实是对的。我很惊讶更改日志(显然)在显示时被解析——通常像这样的元数据被解析成数据结构并序列化为 XML。 GitChangeSet 是解析它的代码。
【解决方案2】:

如果完成所有必要的脚本批准,则以下管道脚本应向更改日志添加 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)
  }
}

【讨论】:

  • 对于 Git,删除 import hudson.scm.SubversionSCM,将 import hudson.scm.SubversionChangeLogParser 替换为 hudson.plugins.git.GitChangeLogParser 并将 new SubversionChangeLogParser 替换为 new GitChangeLogParser。以下 Git 命令似乎产生了GitChangeLogParser 所需的正确输出:git --no-pager log --raw --no-abbrev --format=raw,尽管格式不是 XML。您只需添加参数即可定义所需的修订范围。
【解决方案3】:

我一直在寻找类似的解决方案,终于得到了这个:-

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

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

 currentBuild.getChangeSet().clear()

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

现在您可以像往常一样使用 $CHANGES 变量进一步使用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-16
    • 2022-10-25
    • 2022-09-26
    • 1970-01-01
    • 1970-01-01
    • 2019-10-16
    • 1970-01-01
    • 2020-12-17
    相关资源
    最近更新 更多