web-dev-qa-db-fra.com

Stage parallèle jenkinsfile scripté

J'essaie d'écrire un Jenkinsfile scripté en utilisant le DSL groovy qui comportera des étapes parallèles au sein d'un ensemble d'étapes.

Voici mon jenkinsfile:

node {   
stage('Build') {
    sh 'echo "Build stage"'
}

stage('API Integration Tests') {
    parallel Database1APIIntegrationTest: {
        try {
            sh 'echo "Build Database1APIIntegrationTest parallel stage"'
        }
        finally {
            sh 'echo "Finished this stage"'
        }               

    }, Database2APIIntegrationTest: {
        try {
            sh 'echo "Build Database2APIIntegrationTest parallel stage"'
        }
        finally {
            sh 'echo "Finished this stage"'
        }

    }, Database3APIIntegrationTest: {
        try {
            sh 'echo "Build Database3APIIntegrationTest parallel stage"'
        }
        finally {
            sh 'echo "Finished this stage"'
        }
    }
}

stage('System Tests') {
    parallel Database1APIIntegrationTest: {
        try {
            sh 'echo "Build Database1APIIntegrationTest parallel stage"'
        }
        finally {
            sh 'echo "Finished this stage"'
        }               

    }, Database2APIIntegrationTest: {
        try {
            sh 'echo "Build Database2APIIntegrationTest parallel stage"'
        }
        finally {
            sh 'echo "Finished this stage"'
        }

    }, Database3APIIntegrationTest: {
        try {
            sh 'echo "Build Database3APIIntegrationTest parallel stage"'
        }
        finally {
            sh 'echo "Finished this stage"'
        }
    }
}
}

Je veux avoir 3 étapes: Construire; Tests d'intégration et tests système . Au cours des deux étapes de test, je souhaite que 3 jeux de tests soient exécutés en parallèle, chacun sur une base de données différente.

J'ai 3 exécuteurs disponibles. Un sur le maître, et 2 agents et moi voulons que chaque étape parallèle s'exécute sur n'importe quel exécuteur disponible.

Ce que j'ai remarqué, c'est qu'après avoir exécuté mon pipeline, je ne vois que les 3 étapes, chacune marquée en vert. Je ne souhaite pas avoir à consulter les journaux de cette étape pour déterminer si l'une des étapes parallèles de cette étape a réussi/instable/a échoué.

Je souhaite voir les 3 étapes de mes étapes de test, marquées en vert, en jaune ou en rouge (succès, instable ou échoué).

J'ai envisagé d'étendre les tests à leurs propres étapes, mais je me suis rendu compte que les étapes parallèles ne sont pas prises en charge (est-ce que quelqu'un sait si cela sera jamais pris en charge?), Je ne peux donc pas le faire car le pipeline prend beaucoup trop de temps .

Toute idée serait très appréciée, merci

7
Ryan Jones

Dans le pipeline scripté Jenkins, parallèle (...) prend une carte décrivant chaque étape à construire. Par conséquent, vous pouvez construire par programmation vos étapes de construction en amont, modèle qui permet une commutation série/parallèle flexible.
J'ai utilisé un code similaire à celui-ci, où prepareBuildStages renvoie une liste de cartes, chaque élément de la liste est exécuté en séquence, tandis que la carte décrit les étapes parallèles à cet endroit.

// main script block
// could use eg. params.parallel build parameter to choose parallel/serial 
def runParallel = true
def buildStages

node('master') {
  stage('Initialise') {
    // Set up List<Map<String,Closure>> describing the builds
    buildStages = prepareBuildStages()
    println("Initialised pipeline.")
  }

  for (builds in buildStages) {
    if (runParallel) {
      parallel(builds)
    } else {
      // run serially (nb. Map is unordered! )
      for (build in builds.values()) {
        build.call()
      }
    }
  }

  stage('Finish') {
      println('Build complete.')
  }
}

// Create List of build stages to suit
def prepareBuildStages() {
  def buildList = []

  for (i=1; i<5; i++) {
    def buildStages = [:]
    for (name in [ 'one', 'two', 'three' ] ) {
      def n = "${name} ${i}"
      buildStages.put(n, prepareOneBuildStage(n))
    }
    buildList.add(buildStages)
  }
  return buildList
}

def prepareOneBuildStage(String name) {
  return {
    stage("Build stage:${name}") {
      println("Building ${name}")
      sh(script:'sleep 5', returnStatus:true)
    }
  }
}

Le pipeline résultant apparaît comme suit:  Jenkins Blue Ocean parallel pipeline

Il existe certaines restrictions sur ce qui peut être imbriqué dans un bloc parallèle. Pour plus de détails, reportez-vous à la documentation du pipeline . Malheureusement, une grande partie de la référence semble biaisée vers le pipeline déclaratif, bien qu’il soit plutôt moins flexible que le script (IMHO). Le exemples de pipeline page s’est avéré le plus utile. 

4
Ed Randall

Voici un exemple tiré de leurs docs :

Exécution parallèle

L'exemple de la section ci-dessus exécute des tests sur deux plates-formes différentes d'une série linéaire. En pratique, si l'exécution du contrôle de vérification prend 30 minutes, l'étape "Test" prend désormais 60 minutes!

Heureusement, Pipeline dispose d'une fonctionnalité intégrée pour exécuter des parties de Scripted Pipeline en parallèle, implémentée dans l'étape parallèle portant le nom approprié.

Refactoriser l'exemple ci-dessus pour utiliser l'étape parallèle:

// Jenkinsfile (Scripted Pipeline)


stage('Build') {
    /* .. snip .. */
}

stage('Test') {
    parallel linux: {
        node('linux') {
            checkout scm
            try {
                unstash 'app'
                sh 'make check'
            }
            finally {
                junit '**/target/*.xml'
            }
        }
    },
    windows: {
        node('windows') {
            /* .. snip .. */
        }
    }
}
4
Behrang

J'essayais également des étapes similaires pour exécuter des étapes parallèles et les afficher toutes dans une vue d'étape. Vous devez écrire une étape dans une étape parallèle, comme indiqué dans le bloc de code suivant.

// Jenkinsfile (Scripted Pipeline)

stage('Build') {
    /* .. Your code/scripts .. */
}

stage('Test') {
    parallel 'linux': {
        stage('Linux') {
            /* .. Your code/scripts .. */
        }
    }, 'windows': {
        stage('Windows') {
            /* .. Your code/scripts .. */
        }
    }
}
0
Harshit

J'ai utilisé stage{} dans des blocs parallèles plusieurs fois. Ensuite, chaque étape apparaît dans la vue Stage. L'étape parente qui contient parallel n'inclut pas la synchronisation de toutes les étapes parallèles, mais chaque étape parallèle apparaît dans la vue de l'étape. 

En océan bleu, les stades parallèles apparaissent séparément au lieu des stades affichés. S'il existe un stade parent, il apparaît en tant que parent des stades parallèles. 

Si vous ne possédez pas la même expérience, une mise à niveau du plug-in est peut-être nécessaire. 

0
Rob Hales