json - plugin - gitlab webhook jenkins
¿Cómo procesar una carga útil de webhook github en Jenkins? (2)
Hay algunos trucos para que esto funcione, y encontré que la
chloky.com
blog
chloky.com
(ahora desaparecida) es útil para la mayor parte.
Como parece que al menos has conseguido que el webhook se comunique con tu instancia de Jenkins, omitiré esos pasos por ahora.
Pero, si desea más detalles, simplemente avance más allá del final de mi respuesta para ver el contenido que pude rescatar de
chloky.com
. No conozco al autor original y la información puede estar desactualizada, pero la encontré servicial.
Para resumir, puede hacer lo siguiente para lidiar con la carga útil:
- Configure un parámetro de cadena llamado "carga útil" en su trabajo de Jenkins. Si planea ejecutar manualmente la compilación, puede ser una buena idea darle un documento JSON predeterminado en algún momento, pero no necesita uno en este momento. Este nombre de parámetro parece ser sensible a mayúsculas y minúsculas (estoy usando Linux, así que no es sorpresa ...)
-
Configure el webhook en github para usar el punto final buildWithParameters en lugar del punto final de compilación , es decir,
http://<<yourserver>>/job/<<yourjob>>/buildWithParameters?token=<<yourtoken>>
-
Configure su webhook para usar application / x-www-form-encoded en lugar de application / json . El primer enfoque empaqueta los datos JSON en una variable de forma llamada "carga útil", que presumiblemente es cómo Jenkins puede asignarla a una variable de entorno. El enfoque de aplicación / json simplemente envía JSON sin procesar que no parece ser asignable a nada (no pude hacerlo funcionar). Puede ver la diferencia señalando su webhook a algo como requestbin e inspeccionando los resultados.
- En este punto, debería obtener su variable de carga útil de $ cuando inicie la compilación. Para analizar el JSON, recomiendo instalar jq en su servidor Jenkins y probar here sintaxis de análisis. JQ es especialmente bueno porque es multiplataforma.
- A partir de aquí, solo analiza lo que necesitas del JSON en otras variables de entorno. En combinación con los pasos de compilación condicionales, esto podría darle mucha flexibilidad.
¡Espero que esto ayude!
EDITAR
esto es lo que podría obtener de las publicaciones originales del blog en
http://chloky.com/tag/jenkins/
, que ha estado muerto por un tiempo.
Esperemos que este contenido también sea útil para alguien.
Publicación n. ° 1: julio de 2012
Github proporciona una buena manera de disparar notificaciones a un sistema de CI como jenkins cada vez que se realiza una confirmación en un repositorio. Esto es realmente útil para iniciar trabajos de compilación en jenkins para probar las confirmaciones que se acaban de realizar en el repositorio. Simplemente debe ir a la sección de administración del repositorio, hacer clic en los ganchos de servicio a la izquierda, hacer clic en ''URL de webhook'' en la parte superior de la lista y luego ingresar la URL del webhook que espera Jenkins (mire este jenkins plugin para configurar jenkins para recibir estos ganchos de github).
Recientemente, sin embargo, estaba buscando una manera de hacer que un webhook se disparara cuando se realiza una solicitud de extracción contra un repositorio, en lugar de cuando se realiza una confirmación al repositorio. Esto es para que podamos hacer que Jenkins ejecute un montón de pruebas en la solicitud de extracción, antes de decidir si fusionar la solicitud de extracción, lo que es útil para cuando muchos desarrolladores trabajan en sus propios tenedores y envían regularmente solicitudes de extracción al principal repo.
Resulta que esto no es tan obvio como cabría esperar, y requiere un poco de desorden con la API de Github.
De manera predeterminada, cuando configura un webhook de github, se configura para que solo se active cuando se realiza una confirmación contra un repositorio. No hay una manera fácil de ver o cambiar esto en la interfaz web de github cuando configuras el webhook. Para manipular el webhook de alguna manera, debe usar la API.
Para realizar cambios en un repositorio a través de la API de github, necesitamos autorizarnos. Vamos a usar curl, así que si quisiéramos, podríamos pasar nuestro nombre de usuario y contraseña cada vez, de esta manera:
# curl https://api.github.com/users/mancdaz --user ''mancdaz''
Enter host password for user ''mancdaz'':
O bien, y esta es una opción mucho mejor si desea hacer un script de cualquiera de estas cosas, podemos tomar un token oauth y usarlo en solicitudes posteriores para evitar tener que seguir ingresando nuestra contraseña. Esto es lo que haremos en nuestro ejemplo. Primero necesitamos crear una autorización oauth y tomar el token:
curl https://api.github.com/authorizations --user "mancdaz" /
--data ''{"scopes":["repo"]}'' -X POST
Se le devolverá algo como lo siguiente:
{
"app":{
"name":"GitHub API",
"url":"http://developer.github.com/v3/oauth/#oauth-authorizations-api"
},
"token":"b2067d190ab94698a592878075d59bb13e4f5e96",
"scopes":[
"repo"
],
"created_at":"2012-07-12T12:55:26Z",
"updated_at":"2012-07-12T12:55:26Z",
"note_url":null,
"note":null,
"id":498182,
"url":"https://api.github.com/authorizations/498182"
}
Ahora podemos usar este token en solicitudes posteriores para manipular nuestra cuenta de github a través de la API. Así que consultemos nuestro repositorio y busquemos el webhook que configuramos en la interfaz web anteriormente:
# curl https://api.github.com/repos/mancdaz/mygithubrepo/hooks?access_token=b2067d190ab94698592878075d59bb13e4f5e96
[
{
"created_at": "2012-07-12T11:18:16Z",
"updated_at": "2012-07-12T11:18:16Z",
"events": [
"push"
],
"last_response": {
"status": "unused",
"message": null,
"code": null
},
"name": "web",
"config": {
"insecure_ssl": "1",
"content_type": "form",
"url": "http://jenkins-server.chloky.com/post-hook"
},
"id": 341673,
"active": true,
"url": "https://api.github.com/repos/mancdaz/mygithubrepo/hooks/341673"
}
]
Tenga en cuenta el bit importante de esa salida json:
"events": [
"push"
]
Básicamente, esto dice que este webhook solo se activará cuando se realice una confirmación (inserción) en el repositorio. La documentación de la API de github describe numerosos tipos de eventos diferentes que se pueden agregar a esta lista; para nuestros propósitos, queremos agregar pull_request, y así es como lo hacemos (tenga en cuenta que obtenemos la identificación del webhook del resultado json anterior). tiene múltiples ganchos definidos, su salida contendrá todos estos ganchos, así que asegúrese de obtener la ID correcta):
# curl https://api.github.com/repos/mancdaz/mygithubrepo/hooks/341673?access_token=b2067d190ab94698592878075d59bb13e4f5e96 -X PATCH --data ''{"events": ["push", "pull_request"]}''
{
"created_at": "2012-07-12T11:18:16Z",
"updated_at": "2012-07-12T16:03:21Z",
"last_response": {
"status": "unused",
"message": null,
"code": null
},
"events": [
"push",
"pull_request"
],
"name": "web",
"config": {
"insecure_ssl": "1",
"content_type": "form",
"url": "http://jenkins-server.chloky.com/post-hook"
},
"id": 341673,
"active": true,
"url": "https://api.github.com/repos/mancdaz/mygithubrepo/hooks/341673"
}
¡Ver!
"events": [
"push",
"pull_request"
],
Este webhook ahora se activará siempre que se realice una confirmación O una solicitud de extracción contra nuestro repositorio. Exactamente lo que haces en tu jenkins / con este webhook depende de ti. Lo usamos para iniciar un montón de pruebas de integración en jenkins para probar el parche propuesto, y luego fusionar y cerrar (nuevamente usando la API) la solicitud de extracción automáticamente. Muy dulce.
Publicación n.º 2: septiembre de 2012
En una publicación anterior, hablé sobre configurar el webhook de github para que se active en una solicitud de extracción, en lugar de solo una confirmación. Como se mencionó, hay muchos eventos que suceden en un repositorio de github, y según la documentación de github, muchos de estos se pueden usar para activar el webhook.
Independientemente de qué evento decida activar, cuando el webhook se dispara desde github, esencialmente realiza una POST a la URL configurada en el webhook, incluida una carga útil json en el cuerpo. La carga útil de json contiene varios detalles sobre el evento que provocó el disparo del webhook. Un ejemplo de carga útil que se disparó en una confirmación simple se puede ver aquí:
payload
{
"after":"c04a2b2af96a5331bbee0f11fe12965902f5f571",
"before":"78d414a69db29cdd790659924eb9b27baac67f60",
"commits":[
{
"added":[
"afile"
],
"author":{
"email":"[email protected]",
"name":"Darren Birkett",
"username":"mancdaz"
},
"committer":{
"email":"[email protected]",
"name":"Darren Birkett",
"username":"mancdaz"
},
"distinct":true,
"id":"c04a2b2af96a5331bbee0f11fe12965902f5f571",
"message":"adding afile",
"modified":[
],
"removed":[
],
"timestamp":"2012-09-03T02:35:59-07:00",
"url":"https://github.com/mancdaz/mygithubrepo/commit/c04a2b2af96a5331bbee0f11fe12965902f5f571"
}
],
"compare":"https://github.com/mancdaz/mygithubrepo/compare/78d414a69db2...c04a2b2af96a",
"created":false,
"deleted":false,
"forced":false,
"head_commit":{
"added":[
"afile"
],
"author":{
"email":"[email protected]",
"name":"Darren Birkett",
"username":"mancdaz"
},
"committer":{
"email":"[email protected]",
"name":"Darren Birkett",
"username":"mancdaz"
},
"distinct":true,
"id":"c04a2b2af96a5331bbee0f11fe12965902f5f571",
"message":"adding afile",
"modified":[
],
"removed":[
],
"timestamp":"2012-09-03T02:35:59-07:00",
"url":"https://github.com/mancdaz/mygithubrepo/commit/c04a2b2af96a5331bbee0f11fe12965902f5f571"
},
"pusher":{
"email":"[email protected]",
"name":"mancdaz"
},
"ref":"refs/heads/master",
"repository":{
"created_at":"2012-07-12T04:17:51-07:00",
"description":"",
"fork":false,
"forks":1,
"has_downloads":true,
"has_issues":true,
"has_wiki":true,
"name":"mygithubrepo",
"open_issues":0,
"owner":{
"email":"[email protected]",
"name":"mancdaz"
},
"private":false,
"pushed_at":"2012-09-03T02:36:06-07:00",
"size":124,
"stargazers":1,
"url":"https://github.com/mancdaz/mygithubrepo",
"watchers":1
}
}
Esta carga útil completa se pasa en las solicitudes POST como un parámetro único, con la
payload
título imaginativa.
Contiene una tonelada de información sobre el evento que acaba de suceder, todo o parte de lo que puede usar jenkins cuando creamos trabajos después del desencadenante.
Para usar esta carga útil en Jenkins, tenemos un par de opciones.
Discuto uno a continuación.
Obteniendo la carga útil de $
En jenkins, al crear un nuevo trabajo de compilación, tenemos la opción de especificar los nombres de los parámetros que esperamos pasar al trabajo en la POST que desencadena la compilación.
En este caso, pasaríamos una
payload
un solo parámetro, como se ve aquí:
Pasar parámetros a un trabajo de compilación jenkins
Más abajo en la configuración del trabajo, podemos especificar que nos gustaría poder activar la compilación de forma remota (es decir, que queremos permitir que Github active la compilación publicando en nuestra URL con la carga útil):
Luego, cuando configuramos el webhook en nuestro repositorio de github (como se describe en la primera publicación), le damos la URL que jenkins nos dice que:
No se puede ver todo en la captura de pantalla, pero la URL que especifiqué para el webhook fue la que me dijo Jenkins:
http://jenkins-server.chloky.com:8080/job/mytestbuild//buildWithParameters?token=asecuretoken
Ahora, cuando construí mi nuevo trabajo en jenkins, a los fines de esta prueba, simplemente le dije que repitiera el contenido del parámetro ''payload'' (que está disponible en compilaciones paramterizadas como una variable de shell del mismo nombre), usando un script simple:
#!/bin/bash
echo "the build worked! The payload is $payload"
Ahora, para probarlo todo, simplemente tenemos que comprometernos con nuestro repositorio, y luego ir a jenkins para ver el trabajo que se activó:
mancdaz@chloky$ (git::master)$ touch myfile
mancdaz@chloky$ (git::master) git add myfile
mancdaz@chloky$ (git::master) git commit -m ''added my file''
[master 4810490] added my file
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 myfile
mancdaz@chloky$ (git::master) git push
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 232 bytes, done.
Total 2 (delta 1), reused 0 (delta 0)
To [email protected]:mancdaz/mygithubrepo.git
c7ecafa..4810490 master -> master
Y en nuestro servidor jenkins, podemos ver la salida de la consola del trabajo que se activó, y he aquí que nuestra ''carga útil'' está contenida en la variable $ payload y está disponible para que la consumamos:
Genial, toda la información sobre nuestro evento github está aquí. y totalmente disponible en nuestro trabajo jenkins! Es cierto que está en una gran json blob, pero con un poco de golpe astuto, deberías estar listo.
Por supuesto, este ejemplo utilizó un compromiso simple para demostrar los principios de llegar a la carga útil dentro de jenkins. Como discutimos en la publicación anterior, un commit es uno de los muchos eventos en un repositorio que puede desencadenar un webhook. Lo que hagas dentro de jenkins una vez que lo hayas activado depende de ti, pero la verdadera diversión viene cuando comienzas a interactuar con github para tomar más medidas en el repositorio (publicar comentarios, fusionar solicitudes de extracción, rechazar confirmaciones, etc.) en función de los resultados de sus trabajos de compilación que se activaron por el evento inicial.
Esté atento a una publicación posterior en la que lo conecto todo y le muestro cómo procesar, ejecutar pruebas y finalmente fusionar una solicitud de extracción si tiene éxito, todo automáticamente dentro de jenkins. ¡La automatización es divertida!
Actualmente estoy activando mis compilaciones Jenkins a través de un webhook de GitHub. ¿Cómo analizaría la carga útil de JSON? Si trato de parametrizar mi compilación y uso la variable $ payload, el webhook de GitHub falla con el siguiente error:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<title>Error 400 This page expects a form submission</title>
</head>
<body><h2>HTTP ERROR 400</h2>
<p>Problem accessing /job/Jumph-CycleTest/build. Reason:
<pre> This page expects a form submission</pre></p><hr /><i><small>Powered by Jetty://</small></i><br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
</body>
</html>
¿Cómo puedo hacer que mi webhook de GitHub funcione con una compilación parametrizada de Jenkins, y cómo podría analizar la carga útil del webhook para usar ciertas líneas, como el nombre de usuario del committer, como condicionales en la compilación?
Hay un complemento de desencadenante de Webhook genérico que puede aportar valores del contenido de la publicación a la compilación.
Si el contenido de la publicación es:
{
"app":{
"name":"GitHub API",
"url":"http://developer.github.com/v3/oauth/#oauth-authorizations-api"
}
}
Y cuando se activa con algún contenido de publicación:
curl -v -H "Content-Type: application/json" -X POST -d ''{ "app":{ "name":"GitHub API", "url":"http://developer.github.com/v3/oauth/" }}'' http://localhost:8080/jenkins/generic-webhook-trigger/invoke?token=sometoken
Resolverá variables y las hará disponibles en el trabajo de compilación.
{
"status":"ok",
"data":{
"triggerResults":{
"free":{
"id":2,
"regexpFilterExpression":"",
"regexpFilterText":"",
"resolvedVariables":{
"app_name":"GitHub API",
"everything_app_url":"http://developer.github.com/v3/oauth/",
"everything":"{/"app/":{/"name/":/"GitHub API/",/"url/":/"http://developer.github.com/v3/oauth//"}}",
"everything_app_name":"GitHub API"
},
"searchName":"",
"searchUrl":"",
"triggered":true,
"url":"queue/item/2/"
}
}
}
}