Не удается создать zip-файл в общей библиотеке для конвейера jenkins - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь создать zip-файл в общей библиотеке для конвейера jenkins с помощью AntBuilder. Можно создать простой zip-файл, но как только я пытаюсь использовать блок, он не работает. Я не получаю никаких сообщений об ошибках или исключений. Как я могу отладить Pipepeline-Script? Или как я могу решить проблему?

Мой код выглядит следующим образом (шаг zipFolder не работает, шаг zipFolder2 работает)

Jenkinsfile @Library ('utils') _

pipeline {
    agent any 
    stages {
        stage('Build') { 
            steps {
                zipFolder( )
                zipFolder2( )
            }
        }

    }
}

общая библиотека:

вары / zipFolder.groovy:

import com.example.Utilities

def call(){
  new Utilities(this).zip(pwd())
}

вары / zipFolder2.groovy

import com.example.Utilities

def call(){
  new Utilities(this).zip2(pwd())
}

SRC / COM / пример / Utilities.groovy

package com.example
import groovy.util.AntBuilder
import org.apache.tools.ant.DefaultLogger

class Utilities implements Serializable {
  def steps
  def byteStream

  Utilities(steps) {this.steps = steps}

  def zip(baseDir){
    def ant = setupAnt(baseDir)
    def destFolder = "${baseDir}/Dist"
    def destfile = "${destFolder}/test.zip"

    ant.delete dir: destFolder
    ant.mkdir(dir: destFolder)
    ant.zip(destfile: destfile, whenempty: 'create', excludes: destfile) {
      zipfileset (dir: "${baseDir}/install", includes: "test.txt",  erroronmissingdir: false)
   }

    steps.echo "Zip1"
    steps.echo "Ant-Result: " + byteStream.toString()
  }

  def zip2(baseDir){
    def ant = setupAnt(baseDir)
    def destFolder = "${baseDir}/Dist2"
    def destfile = "${destFolder}/test.zip"

    ant.delete dir: destFolder
    ant.mkdir(dir: destFolder)
    ant.zip(destfile: destfile, whenempty: 'create', excludes: destfile, basedir: baseDir)

    steps.echo "Zip2"
    steps.echo "Ant-Result: " + byteStream.toString()
  }

  def setupAnt(baseDir){
    def ant = new AntBuilder()
    byteStream = new ByteArrayOutputStream()
    def printStream = new PrintStream( byteStream )
    def project = ant.project

    project.buildListeners.each {
        if ( it instanceof DefaultLogger ) {
                it.setMessageOutputLevel(org.apache.tools.ant.Project.MSG_DEBUG)
                it.setOutputPrintStream printStream
                it.setErrorPrintStream printStream
        }
    }

    ant
  }


}

Ответы [ 2 ]

0 голосов
/ 26 января 2019

С подсказкой Joerg S Я решил проблему с помощью следующего кода:

src/com/example/Utilities.groovy

package com.example

import org.apache.tools.ant.DefaultLogger


package com.example

import org.apache.tools.ant.DefaultLogger


class Utilities implements Serializable {
  def steps
  def byteStream

  Utilities(steps) {this.steps = steps}


  def zip(baseDir, Closure callback ){
    def ant = setupAnt()
    def destFolder = "${baseDir}/Dist"
    def destfile = "${destFolder}/test.zip"

    ant.delete dir: destFolder
    ant.mkdir(dir: destFolder)

    ant.zip(destfile: destfile, whenempty: 'create', excludes: destfile, callback)

    steps.echo "Ant-Result: " + byteStream.toString()
  }


  def setupAnt(){
    def ant = new AntBuilder()
    byteStream = new ByteArrayOutputStream()
    def printStream = new PrintStream( byteStream )
    def project = ant.project

    project.buildListeners.each {
        if ( it instanceof DefaultLogger ) {
                it.setMessageOutputLevel(org.apache.tools.ant.Project.MSG_DEBUG)
                it.setOutputPrintStream printStream
                it.setErrorPrintStream printStream
        }
    }

    ant
  }


}

vars/zipFolder.groovy

import com.example.Utilities

def call(Closure callback){
  new Utilities(this).zip(pwd(), callback)
}

Jenkinsfile

@Library('utils') _

pipeline {
    agent any 
    stages {
        stage('Build') { 
            steps {
                cleanWs()
                writeFile file: 'test.txt', text: 'Sample Text'
                writeFile file: 'test2.txt', text: 'Sample Text 2'
                writeFile file: 'src/test3.txt', text: 'Sample Text 3'

                zipIt()

            }
        }

    }
}

@NonCPS
def zipIt(){
    zipFolder( ) {
        delegate.zipfileset (dir: "${pwd()}", includes: "test.txt", excludes: "src/**" , filemode: "0755", prefix: "bin/examples", erroronmissingdir: false)
        delegate.zipfileset (dir: "${pwd()}/src", includes: "*.txt",  erroronmissingdir: false)
    }
}

Важным является использование аннотации @NonCPS и delegate.zipfileset вместо простого использования zipfileset.

Редактировать: Это решение не работает на рабе.Этот код выполняется на главном сервере, даже если сборка выполняется на ведомом устройстве.

0 голосов
/ 26 января 2019

AntBuilder не Serializable. То, что мы сделали, это инкапсулировали вызов AntBuilder внутри дополнительного скрипта groovy, который создается на лету и вызывается вызовом двоичного файла groovy, например:

writeFile file:createZip.groovy text:”””
def antBuilder = new AntBuilder()
...
“””
sh ‘groovy createZip.groovy’

Вы также можете рассмотреть возможность использования шага почтового индекса Jenkins Pipeline. Смотри https://jenkins.io/doc/pipeline/steps/pipeline-utility-steps/#zip-create-zip-file

...