【问题标题】:Jenkins Groovy Postbuild use static file instead of scriptJenkins Groovy Postbuild 使用静态文件而不是脚本
【发布时间】:2014-02-18 18:46:05
【问题描述】:

是否可以将外部 groovy 脚本加载到 groovy 后期构建插件中,而不是将脚本内容粘贴到每个作业中?我们有大约 200 个工作,因此全部更新它们相当耗时。我知道我可以编写一个脚本来直接更新配置文件(如在这篇文章中:Add Jenkins Groovy Postbuild step to all jobs),但这些作业运行 24x7,因此当我可以重新启动 Jenkins 或重新加载配置时找到一个窗口是有问题的。

谢谢!

【问题讨论】:

    标签: groovy jenkins jenkins-plugins


    【解决方案1】:

    只需将以下内容放在“Groovy 脚本:”字段中:

    evaluate(new File("... groovy 脚本文件名..."));

    此外,您可能还想走得更远。 如果脚本名称或路径发生变化怎么办? 使用Template plugin,您可以创建一个“模板”作业,在其中定义对 groovy 脚本(上面一行)的调用,并在所有需要它的作业中添加名为“使用来自另一个项目的发布者”的构建后操作,并引用此模板项目.

    【讨论】:

    • 例如工作区中的脚本:evaluate(new File(manager.build.workspace.toString() + "/dirinworkspace/scriptname.groovy"))
    【解决方案2】:

    更新:这才是真正为我解决的问题:https://issues.jenkins-ci.org/browse/JENKINS-21480

    “我可以通过执行以下操作来做到这一点。在“Groovy 脚本”框中输入这些行来代替脚本:“

    // Delegate to an external script
    // The filename must match the class name
    import JenkinsPostBuild
    def postBuild = new JenkinsPostBuild(manager)
    postBuild.run()
    

    “然后在“Additional groovy classpath”框中输入该文件的路径。”

    【讨论】:

      【解决方案3】:

      我们按照以下方式进行。

      我们有一个文件c:\somepath\MyScriptLibClass.groovy(Jenkins 可以访问),其中包含一个 groovy 类 MyScriptLibClass 的代码。该类包含许多旨在充当静态方法的函数(稍后将混合使用)。

      我们在系统 groovy 和 postbuild groovy 步骤的开头包含以下语句:

      [ // include lib scripts
          'MyScriptLibClass'
      ].each{ this.metaClass.mixin(new GroovyScriptEngine('c:\\somepath').loadScriptByName(it+'.groovy')) }
      

      这可能看起来有点难看,但您只需要为脚本编写一次。您可以包含多个脚本,也可以在库类之间使用继承。

      在这里您可以看到库类中的所有方法都混合在当前脚本中。所以如果你的班级看起来像:

      class MyScriptLibClass {
          def setBuildName( String str ){
              binding?.variables['manager'].build.displayName = str
          }
      }
      

      在 Groovy Postbuild 中,您可以只写:

      [ // include lib scripts
          'MyScriptLibClass'
      ].each{ this.metaClass.mixin(new GroovyScriptEngine('c:\\somepath').loadScriptByName(it+'.groovy')) }
      
      setBuildName( 'My Greatest Build' )
      

      它会更改您当前构建的名称。

      还有其他加载外部 groovy 类的方法,不需要使用混入。例如你可以看看这里Compiling and using Groovy classes from Java at runtime?

      【讨论】:

        【解决方案4】:

        我是如何解决这个问题的:

        使用以下内容创建文件 $JENKINS_HOME/scripts/PostbuildActions.groovy:

        public class PostbuildActions {
          void setBuildName(Object manager, String str ){
            binding?.variables['manager'].build.displayName = str
          }
        }
        

        在这种情况下,您可以在 Groovy Postbuild 中编写:

        File script = new File("${manager.envVars['JENKINS_HOME']}/scripts/PostbuildActions.groovy")
        Object actions = new GroovyClassLoader(getClass().getClassLoader()).parseClass(script).newInstance();
        
        actions.setBuildName(manager, 'My Greatest Build');
        

        【讨论】:

        • manager.envVars 在 groovy postbuild 中为我抛出异常。必须做build = Thread.currentThread().executable 后跟build.getEnvVars()["JENKINS_HOME"]
        【解决方案5】:

        如果您希望将 Groovy 脚本放在代码存储库中,并加载到工作区中的 Build / Test Slave 上,那么您需要注意 Groovy Postbuild 在 Master 上运行。

        对我们来说,主服务器是 Unix 服务器,而构建/测试从服务器是本地网络上的 Windows PC。因此,在使用脚本之前,我们必须打开一个从 master 到 Slave 的通道,并使用FilePath 到文件。

        以下对我们有用:

        // Get an Instance of the Build object, and from there
        // the channel from the Master to the Workspace
        build = Thread.currentThread().executable
        channel = build.workspace.channel;
        
        // Open a FilePath to the script
        fp = new FilePath(channel, build.workspace.toString() + "<relative path to the script in Unix notation>")
        
        // Some have suggested that the "Not NULL" check is redundant
        // I've kept it for completeness
        if(fp != null)
        {
            // 'Evaluate' requires a string, so read the file contents to a String
            script = fp.readToString();
            // Execute the script
            evaluate(script);
        } 
        

        【讨论】:

          【解决方案6】:

          我刚刚面临同样的任务并尝试使用@Blaskovicz 方法。 不幸的是它对我不起作用,但我发现升级代码here (Zach Auclair)

          在此处发布,稍作改动:

          构建后任务

          //imports
          import hudson.model.*
          import groovy.lang.GroovyClassLoader;
          import groovy.lang.GroovyObject;
          import java.io.File;
          
          // define git file
          def postBuildFile = manager.build.getEnvVars()["WORKSPACE"] + "/Jenkins/SimpleTaskPostBuildReporter.GROOVY"
          def file = new File(postBuildFile)
          // load custom class from file
          Class groovy = this.class.classLoader.parseClass(file);
          // create custom object
          GroovyObject groovyObj = (GroovyObject) groovy.newInstance(manager);
          // do report
          groovyObj.report();
          

          git repo 中的 postbuild 类文件 (SimpleTaskPostBuildReporter.GROOVY)

          class SimpleTaskPostBuildReporter {
            def manager
          
            public SimpleTaskPostBuildReporter(Object manager){
              if(manager == null) {
                throw new RuntimeException("Manager object can't be null")
              }
              this.manager = manager
            }
          
            public def report() {
              // do work with manager object
            }
          }
          

          【讨论】:

            【解决方案7】:

            我还没有完全尝试过。

            您可以尝试Jenkins Job DSL plugin,它允许您使用 Groovy DSL 从 jenkins 中重建作业,并支持直接从 wiki 进行后期构建 groovy 步骤

            Groovy 后期构建

            在构建后执行 Groovy 脚本。

            groovyPostBuild(字符串脚本,行为行为 = Behavior.DoNothing) 参数:

            script 在构建之后执行的 Groovy 脚本。查看插件的 有关可以做什么的详细信息页面。行为可选。如果脚本 失败,允许您将构建标记为失败、不稳定或执行 没有什么。行为参数使用一个枚举,目前有三个 值:DoNothing、MarkUnstable 和 MarkFailed。

            例子:

            这个例子将运行一个 groovy 脚本,打印 hello、world 和 if 失败,它不会影响构建的状态:

            groovyPostBuild('println "hello, world"') This example will run a 
                    groovy script, and if that fails will mark the build as failed:
            
            groovyPostBuild('// some groovy script', Behavior.MarkFailed) This example 
                    will run a groovy script, and if that fails will mark the
            

            构建为不稳定的:

            groovyPostBuild('// some groovy script', Behavior.MarkUnstable) (Since 1.19)
            

            有一个工具可以使用模板作业(这是我没有尝试过的部分),它可能是作业本身,因此您只需要添加后期构建步骤。如果您不使用模板,则需要重新编码整个项目。

            我的方法是使用脚本从头开始重新生成或创建所有作业,这样我就不必多次应用相同的升级。重新生成的作业会保留其构建历史

            【讨论】:

              【解决方案8】:

              我能够得到以下工作(我还发布了on this jira issue)。

              在我的后期构建任务中

              this.class.classLoader.parseClass("/home/jenkins/GitlabPostbuildReporter.groovy")
              GitlabPostbuildReporter.newInstance(manager).report()
              

              在我的磁盘文件中/home/jenkins/GitlabPostbuildReporter.groovy

              class GitlabPostbuildReporter {
                def manager
                public GitlabPostbuildReporter(manager){
                  if(manager == null) {
                    throw new RuntimeException("Manager object musn't be null")
                  }
                  this.manager = manager
                }
                public def report() {
                  // do work with manager object
                }
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-08-15
                • 2015-04-03
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多