Comment puis-je tester localement une modification apportée au fichier Jenkins?


210

Lors de l'écriture de pipelines jenkins, il semble très gênant de valider chaque nouvelle modification afin de voir si cela fonctionne.

Existe-t-il un moyen de les exécuter localement sans valider le code?

Réponses:


139

Vous ne pouvez pas exécuter le script Pipeline localement, car son objectif est de scripter Jenkins. (C'est une des raisons pour lesquelles il est préférable de conserver votre Jenkinsfilecode court et limité au traitement des fonctionnalités de Jenkins; votre logique de génération réelle doit être gérée avec des processus externes ou des outils de génération que vous invoquez via une ligne shou une batétape.)

Si vous voulez tester une modification pour la Jenkinsfilevivre mais sans la valider , utilisez la fonction Replay ajoutée dans 1.14

JENKINS-33925 suit les souhaits pour un cadre de test automatisé.


Le billet de blog indique qu'il y a un bouton de «relecture». Une idée où? Je n'arrive pas à le localiser.
BoltzmannBrain

8
@BoltzmannBrain, accédez à la page Jenkins de votre travail de génération. Sur le côté gauche, vous devriez voir la liste des exécutions de build précédentes. Lorsque vous survolez un ID d'exécution de build (par exemple "# 123") ou une date d'exécution de build, une petite flèche vers le bas apparaît. Cliquer dessus fait apparaître un menu contextuel qui a l'option "Rejouer". L'option est également disponible sur la page d'une exécution de build.
Good Night Nerd Pride

2
Concourse vous permet d'exécuter vos scripts locaux sur un serveur de build cible, vous pouvez donc valider qu'il fonctionnera également sur le serveur distant avant de valider vos modifications. concourse.ci/fly-cli.html . La fonctionnalité de relecture de Jenkins est quelque peu analogue à cela, sauf qu'elle a des limites et que vous devez d'abord créer une build pour la rejouer.
mdo123

2
Vous pourriez jeter un œil à ce projet qui vise à fournir ce que vous recherchez.
Romain

1
Jetez un œil à JenkinsPipelineUnit ( github.com/jenkinsci/JenkinsPipelineUnit )
user864279

79

J'ai une solution qui fonctionne bien pour moi. Il se compose d'un jenkins local exécuté dans docker et d'un hook web git pour déclencher le pipeline dans les jenkins locaux à chaque validation. Vous n'avez plus besoin de pousser vers votre dépôt github ou bitbucket pour tester le pipeline.

Cela n'a été testé que dans un environnement Linux.

Il est assez simple de faire ce travail bien que cette instruction soit un peu longue. La plupart des étapes sont là.

Voilà ce dont vous avez besoin

  • Docker installé et fonctionnel. Cela ne fait pas partie de cette instruction.
  • Un Jenkins fonctionnant dans docker localement. Expliqué comment ci-dessous.
    • Les droits appropriés (clé d'accès ssh) pour que votre utilisateur local Docker Jenkins puisse retirer de votre dépôt git local. Expliqué comment ci-dessous.
    • Un projet de pipeline Jenkins qui tire de votre référentiel git local. Expliqué ci-dessous.
    • Un utilisateur git dans votre Jenkins local avec des droits minimaux. Expliqué ci-dessous.
  • Un projet git avec un hook web post-commit qui déclenche le projet de pipeline. Expliqué ci-dessous.

Voici comment vous le faites

Jenkins Docker

Créez un fichier appelé Dockerfile à la place de votre choix. Je le place en le /opt/docker/jenkins/Dockerfileremplissant avec ceci:

FROM jenkins/jenkins:lts
USER root
RUN apt-get -y update && apt-get -y upgrade
# Your needed installations goes here
USER jenkins

Construisez l'image local_jenkins

Vous ne devrez le faire qu'une seule fois ou après avoir ajouté quelque chose au Dockerfile.

$ docker build -t local_jenkins /opt/docker/jenkins/

Démarrer et redémarrer local_jenkins

De temps en temps, vous souhaitez démarrer et redémarrer facilement jenkins. Par exemple, après un redémarrage de votre machine. Pour cela, j'ai créé un alias que j'ai mis .bash_aliasesdans mon dossier personnel.

$ echo "alias localjenkinsrestart='docker stop jenkins;docker rm jenkins;docker run --name jenkins -i -d -p 8787:8080 -p 50000:50000 -v /opt/docker/jenkins/jenkins_home:/var/jenkins_home:rw local_jenkins'" >> ~/.bash_aliases
$ source .bash_aliases  # To make it work

Assurez-vous que le /opt/docker/jenkins/jenkins_homedossier existe et que vous disposez des droits de lecture et d'écriture de l'utilisateur.

Pour démarrer ou redémarrer votre jenkins, tapez simplement:

$ localjenkinsrestart

Tout ce que vous faites dans votre jenkins local sera stocké dans le dossier / opt / docker / jenkins / jenkins_home et conservé entre les redémarrages.

Créez une clé d'accès SSH dans votre Docker Jenkins

C'est une partie très importante pour que cela fonctionne. D'abord, nous démarrons le conteneur docker et créons un shell bash:

$ localjenkinsrestart
$ docker exec -it jenkins /bin/bash

Vous êtes maintenant entré dans le conteneur Docker, ce que vous pouvez voir par quelque chose comme jenkins@e7b23bad10aa:/$dans votre terminal. Le hachage après le @ sera certainement différent.

Créez la clé

jenkins@e7b23bad10aa:/$ ssh-keygen

Appuyez sur Entrée pour toutes les questions jusqu'à ce que vous receviez l'invite

Copiez la clé sur votre ordinateur. De l'intérieur du conteneur Docker, votre ordinateur est 172.17.0.1 si vous vous demandez.

jenkins@e7b23bad10aa:/$ ssh-copy-id user@172.17.0.1

user = votre nom d'utilisateur et 172.17.0.1 est l'adresse IP de votre ordinateur depuis le conteneur Docker.

Vous devrez saisir votre mot de passe à ce stade.

Essayons maintenant de terminer la boucle en effectuant une connexion ssh à votre ordinateur depuis le conteneur Docker.

jenkins@e7b23bad10aa:/$ ssh user@172.17.0.1

Cette fois, vous ne devriez pas avoir à saisir votre mot de passe. Si vous le faites, quelque chose s'est mal passé et vous devez réessayer.

Vous serez maintenant dans le dossier de départ de votre ordinateur. Essayez lset regardez.

Ne vous arrêtez pas ici car nous avons une chaîne de coquilles ssh dont nous devons sortir.

$ exit
jenkins@e7b23bad10aa:/$ exit

Droite! Nous sommes maintenant de retour et prêts à continuer.

Installez votre Jenkins

Vous trouverez votre Jenkins local dans votre navigateur à http: // localhost: 8787 .

La première fois que vous pointez votre navigateur vers votre Jenkins local, vous serez doté d'un assistant d'installation. Les valeurs par défaut sont correctes, assurez-vous toutefois d'installer le plugin de pipeline pendant la configuration.

Configurez vos jenkins

Il est très important d'activer la sécurité basée sur la matrice sur http: // localhost: 8787 / configureSecurity et de vous accorder tous les droits en vous ajoutant à la matrice et en cochant toutes les cases. (Il y a une icône de coche à l'extrême droite)

  • Sélectionnez Jenkins’ own user databasecomme domaine de sécurité
  • Sélectionnez Matrix-based securitydans la section Autorisation
  • Écrivez votre nom d'utilisateur dans le champ User/group to add:et cliquez sur le [ Add ]bouton
  • Dans le tableau ci-dessus, votre nom d'utilisateur devrait apparaître avec une icône de personne à côté de lui. S'il est barré, vous avez mal saisi votre nom d'utilisateur.
  • Allez à l'extrême droite du tableau et cliquez sur le bouton tout cocher ou cochez manuellement toutes les cases de votre ligne.
  • Veuillez vérifier que la case Prevent Cross Site Request Forgery exploitsn'est pas cochée. (Étant donné que ce Jenkins n'est accessible que depuis votre ordinateur, ce n'est pas si grave)
  • Cliquez sur [ Save ]et déconnectez-vous de Jenkins et reconnectez-vous juste pour vous assurer que cela fonctionne. Si ce n'est pas le cas, vous devez recommencer depuis le début et vider le /opt/docker/jenkins/jenkins_homedossier avant de redémarrer

Ajouter l'utilisateur git

Nous devons autoriser notre hook git à se connecter à notre Jenkins local avec des droits minimaux. Il suffit de voir et de créer des emplois. Par conséquent, nous créons un utilisateur appelé gitavec mot de passe login.

Dirigez votre navigateur vers http: // localhost: 8787 / securityRealm / addUser et ajoutez gitcomme nom d'utilisateur et loginmot de passe. Cliquez sur [ Create User ].

Ajoutez les droits à l'utilisateur git

Accédez à la page http: // localhost: 8787 / configureSecurity dans votre navigateur. Ajoutez l'utilisateur git à la matrice:

  • Écrivez gitdans le champ User/group to add:et cliquez sur[ Add ]

Il est maintenant temps de cocher les cases pour les droits minimaux pour l'utilisateur git. Seuls ceux-ci sont nécessaires:

  • global: lire
  • travail: construire
  • métier: découvrir
  • travail: lire

Assurez-vous que la Prevent Cross Site Request Forgery exploitscase n'est pas cochée et cliquez sur[ Save ]

Créer le projet de pipeline

Nous supposons que nous avons le nom d'utilisateur useret que notre projet compatible avec git Jenkinsfileest appelé projectet se trouve à/home/user/projects/project

Dans votre http: // localhost: 8787 Jenkins ajoutez un nouveau projet de pipeline. Je l'ai nommé hookpipeline pour référence.

  • Cliquez sur New Itemdans le menu Jenkins
  • Nommez le projet hookpipeline
  • Cliquez sur Pipeline
  • Cliquez sur [ OK ]
  • Cochez la case Poll SCMdans la section Build Triggers. Laissez le programme vide.
  • Dans la section Pipeline:
    • sélectionner Pipeline script from SCM
    • dans le Repository URLchamp entrezuser@172.17.0.1:projects/project/.git
    • dans le Script Pathchamp entrezJenkinsfile
  • Enregistrez le projet hookpipeline
  • Générez manuellement le hookpipeline une fois, cela est nécessaire pour que Poll SCM commence à fonctionner.

Créer le crochet git

Accédez au /home/user/projects/project/.git/hooksdossier et créez un fichier appelé post-commitqui contient ceci:

#!/bin/sh
BRANCHNAME=$(git rev-parse --abbrev-ref HEAD)
MASTERBRANCH='master'

curl -XPOST -u git:login http://localhost:8787/job/hookpipeline/build
echo "Build triggered successfully on branch: $BRANCHNAME"

Rendez ce fichier exécutable:

$ chmod +x /home/user/projects/project/.git/hooks/post-commit

Testez le hook post-commit:

$ /home/user/projects/project/.git/hooks/post-commit

Vérifiez dans Jenkins si votre projet de raccordement a été déclenché.

Enfin, apportez des modifications arbitraires à votre projet, ajoutez les modifications et effectuez une validation. Cela va maintenant déclencher le pipeline dans votre Jenkins local.

Jours heureux!


Je devais remplacer docker build -t local_jenkins /opt/docker/jenkins/Dockerfilepar docker build -t local_jenkins /opt/docker/jenkinsparce que Docker se plaignait de "incapable de préparer le contexte: le contexte doit être un répertoire".
Etienne Neveu

1
Je reçois cette erreur sur Mac. Quelqu'un peut-il m'aider à ce sujet? >> ERREUR: ssh: connexion à l'hôte 172.17.0.1 port 22: connexion refusée -
Manoj Shrestha

@ManojShrestha: L'IP 172.17.0.1 est l'IP par défaut de la machine qui exécute les conteneurs Docker. Vous pouvez utiliser l'IP de vos machines (MAC: s) à la place.
javabeangrinder

@ManojShrestha: Vous pouvez également essayer de trouver l'IP de passerelle de votre configuration comme ceci: $ docker inspect jenkins | grep Gateway
javabeangrinder

2
Si votre hôte docker est installé sur macOS et que vous souhaitez vous y connecter à partir du conteneur docker, vous devriez ssh user@docker.for.mac.localhost au lieu d'utiliser l'adresse IP. Assurez-vous également que vous avez activé la fonction de connexion à distance dans les préférences système de macOs -> menu Dossier partagé
Paolo Angioletti

61

TL; DR

La version longue des
tests Jenkins Pipeline devient de plus en plus pénible. Contrairement à l' approche de configuration de travail déclarative classique où l'utilisateur était limité à ce que l'interface utilisateur a exposé, le nouveau pipeline Jenkins est un langage de programmation à part entière pour le processus de construction où vous mélangez la partie déclarative avec votre propre code. En tant que bons développeurs, nous voulons également avoir des tests unitaires pour ce type de code.

Vous devez suivre trois étapes lors du développement de Jenkins Pipelines. L' étape 1. devrait couvrir 80% des cas d'utilisation.

  1. Faites autant que possible dans les scripts de construction (par exemple. Maven, Gradle, Gulp, etc.). Ensuite, dans vos scripts de pipeline, il suffit d'appeler les tâches de génération dans le bon ordre. Le pipeline de build orchestre et exécute simplement les tâches de build mais n'a pas de logique majeure nécessitant un test spécial.
  2. Si la règle précédente ne peut pas être entièrement appliquée, passez aux bibliothèques partagées de pipeline où vous pouvez développer et tester la logique personnalisée seule et les intégrer dans le pipeline.
  3. Si tout ce qui précède vous échoue, vous pouvez essayer l'une de ces bibliothèques récemment apparues (mars 2017). Framework de test Jenkins Pipeline Unit ou pipelineUnit (exemples). Depuis 2018, il existe également Jenkinsfile Runner , un package pour exécuter les pipelines Jenkins à partir d'un outil en ligne de commande.

Exemples

Le dépôt pipelineUnit GitHub contient des exemples Spock sur la façon d'utiliser le framework de test Jenkins Pipeline Unit


1
Pouvez-vous également inclure une brève comparaison de ces deux bibliothèques?
sorin

24

Jenkins possède une fonction de «relecture», qui vous permet de rejouer rapidement un travail sans mettre à jour les sources:

Fonction de relecture


1
Notez qu'il apparaît sur la page de génération, pas sur la page de projet ou de branche.
ArtOfWarfare

17

Au moment de l'écriture (fin juillet 2017) avec le plugin Blue Ocean, vous pouvez vérifier la syntaxe d'un pipeline déclaratif directement dans l' éditeur de pipeline visuel . L'éditeur fonctionne à partir de l'interface utilisateur de Blue Ocean lorsque vous cliquez sur "configurer" uniquement pour les projets github (c'est un problème connu et ils travaillent pour le faire fonctionner également sur git, etc.).

Mais, comme expliqué dans cette question, vous pouvez ouvrir l'éditeur en parcourant:

[Jenkins URL]/blue/organizations/jenkins/pipeline-editor/

Cliquez ensuite au milieu de la page et appuyez sur Ctrl+S, cela ouvrira une zone de texte où vous pourrez coller un script déclaratif de pipeline. Lorsque vous cliquez sur Mettre à jour , s'il y a une erreur de syntaxe, l'éditeur vous indiquera où se trouve l'erreur de syntaxe. Comme dans cette capture d'écran:

Comme test rapide, j'ai mal tapé "stepps" au lieu de "steps"

S'il n'y a pas d'erreur de syntaxe, la zone de texte se fermera et la page visualisera votre pipeline. Ne vous inquiétez pas, cela ne sauvera rien (s'il s'agit d'un projet github, il validerait la modification du fichier Jenkins).

Je suis nouveau sur Jenkins et cela est très utile, sans cela, j'ai dû valider un fichier Jenkins plusieurs fois, jusqu'à ce qu'il fonctionne (très ennuyeux!). J'espère que cela t'aides. À votre santé.


2
C'est parce que depuis 2017, Jenkins vise toujours à résoudre les problèmes des ingénieurs logiciels pointer-cliquer;) .... Au moins Atom a un linter Groovy décent. C'est seulement Groovy mais ça aide.
sorin

L'éditeur avec mise en évidence de la syntaxe fait également partie de l'interface utilisateur jenkins classique.
Vadimo

6

Un peu tard pour la fête, mais c'est pourquoi j'ai écrit jenny, une petite réimplémentation de quelques étapes clés du Jenkinsfile. ( https://github.com/bmustiata/jenny )


Aucune infraction, mais à moins que vous ne mettiez constamment à jour vos trucs, cela sera assez inutile car la syntaxe du pipeline est dans un état constant de flux, il semble pour le moment.
krad

Pas pris. D'après ce que j'ai vu jusqu'à présent, la syntaxe du pipeline, elle est à peu près standardisée pour les étapes de base du pipeline ( jenkins.io/doc/pipeline/steps/workflow-basic-steps ). Je l'utilise depuis environ 2 ans maintenant, sans rencontrer de changements incompatibles en arrière. Les plugins Jenkins ne doivent pas être utilisés à mon humble avis, et l'API changeante peut être abstraite à l'aide de commandes personnalisées dans des bibliothèques partagées, où vous aurez des garanties API. Si vous parlez de la syntaxe déclarative, cela pourrait être vrai. J'utilise uniquement l'API programmatique dans mes pipelines, et c'est ce que Jenny prend en charge. Solide comme un roc :)
bogdan.mustiata

5

Autant que je sache, ce plugin de pipeline est le "moteur" des nouveaux mécanismes Jenkinsfile, donc je suis assez positif que vous puissiez l'utiliser pour tester localement vos scripts.

Je ne sais pas s'il y a des étapes supplémentaires nécessaires lorsque vous le copiez dans un fichier Jenkins, mais la syntaxe, etc. devrait être exactement la même.

Edit: Trouvé la référence sur le "moteur", vérifiez cette description de fonctionnalité, dernier paragraphe, première entrée.


5

Dans ma configuration de développement - sans un éditeur Groovy approprié - beaucoup de problèmes de Jenkinsfile proviennent d' erreurs de syntaxe simples . Pour résoudre ce problème, vous pouvez valider le fichier Jenkins par rapport à votre instance Jenkins (exécutée sur $JENKINS_HTTP_URL):

curl -X POST -H $(curl '$JENKINS_HTTP_URL/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)') -F "jenkinsfile=<Jenkinsfile" $JENKINS_HTTP_URL/pipeline-model-converter/validate

La commande ci-dessus est une version légèrement modifiée de https://github.com/jenkinsci/pipeline-model-definition-plugin/wiki/Validating-(or-linting)-a-Declarative-Jenkinsfile-from-the-command-line


4
C'est exactement le genre de chose que je cherchais - malheureusement cela ne fonctionne que pour les pipelines déclaratifs et non les pipelines scriptés :(
thom_nic

2

Mis à part la fonctionnalité de relecture que d'autres ont déjà mentionnée (idem sur son utilité!), J'ai trouvé les éléments suivants également utiles:

  1. Créez un travail Pipeline de test où vous pouvez taper du code Pipeline ou pointer vers votre dépôt / branche d'un fichier Jenkins pour tester rapidement quelque chose. Pour des tests plus précis, utilisez un pipeline multibranches qui pointe vers votre propre fourche où vous pouvez rapidement apporter des modifications et vous engager sans affecter la prod. Des trucs comme BRANCH_NAME env sont uniquement disponibles dans Multibranch.
  2. Puisque Jenkinsfile est du code Groovy, invoquez-le simplement avec "groovy Jenkinsfile" pour valider la syntaxe de base.

L'utilisation de tâches distinctes que vous pouvez cacher et ne pas confondre vos utilisateurs est l'une des choses les plus importantes. J'édite les fichiers Jenkins avec IntelliJ. Il est assez bon pour montrer les défauts de syntaxe. Cependant, le bouton de réponse est l'élément clé. Je crée une branche avec le changement de base qui - cela se passe généralement un peu mal. Je modifie ensuite le fichier Jenkins et je le copie et le colle dans la fenêtre de relecture, puis je l'exécute à nouveau - je le répète jusqu'à ce qu'il fonctionne correctement, puis je valide la version de travail.
johnfo

2

Mettez votre clé SSH dans votre profil Jenkins, puis utilisez le linter déclaratif comme suit:

ssh jenkins.hostname.here declarative-linter < Jenkinsfile

Cela fera une analyse statique sur votre fichier Jenkins. Dans l'éditeur de votre choix, définissez un raccourci clavier qui exécute cette commande automatiquement. Dans Visual Studio Code, qui est ce que j'utilise, accédez à Tâches> Configurer les tâches, puis utilisez le JSON suivant pour créer une commande Valider Jenkinsfile :

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Validate Jenkinsfile",
      "type": "shell",
      "command": "ssh jenkins.hostname declarative-linter < ${file}"
    }
  ]
}

0

j'utilise replay future, pour faire une mise à jour et courir rapidement.


1
Pouvez-vous s'il vous plaît fournir plus d'informations sur la façon dont vous faites cela?
kosnik

1
J'utilise Bit-bucket comme gestionnaire de source, puis j'ai créé un projet sur Jenkins et je souhaite découvrir mon référentiel automatiquement, je recommande ce post. Après chaque pression sur mon repo Jenkins jouera automatiquement mon fichier Jenkins et s'il échoue, dans le menu de gauche il y a un bouton appelé Replay, ==> ce bouton ouvre un éditeur contenant votre fichier Jenkins, vous pouvez le modifier et rejouer le job ,
AhmedDrira

0

Avec quelques limitations et pour les pipelines scriptés, j'utilise cette solution:

  1. Travail de pipeline avec un script groovy intégré:

node('master') {
    stage('Run!') {
                def script = load('...you job file...')
    }
}

  1. Le fichier Jenkins pour les tests a la même structure que pour lesfurets:

def execute() {
 ... main job code here ...
}
execute()
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.