-
1. Inicio - Sobre el Control de Versiones
-
2. Fundamentos de Git
-
3. Ramificaciones en Git
-
4. Git en el Servidor
- 4.1 Los Protocolos
- 4.2 Configurando Git en un servidor
- 4.3 Generando tu clave pública SSH
- 4.4 Configurando el servidor
- 4.5 El demonio Git
- 4.6 HTTP Inteligente
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Git en un alojamiento externo
- 4.10 Resumen
-
5. Git en entornos distribuidos
-
6. GitHub
-
7. Herramientas de Git
- 7.1 Revisión por selección
- 7.2 Organización interactiva
- 7.3 Guardado rápido y Limpieza
- 7.4 Firmando tu trabajo
- 7.5 Buscando
- 7.6 Reescribiendo la Historia
- 7.7 Reiniciar Desmitificado
- 7.8 Fusión Avanzada
- 7.9 Rerere
- 7.10 Haciendo debug con Git
- 7.11 Submódulos
- 7.12 Agrupaciones
- 7.13 Replace
- 7.14 Almacenamiento de credenciales
- 7.15 Resumen
-
8. Personalización de Git
-
9. Git y Otros Sistemas
- 9.1 Git como Cliente
- 9.2 Migración a Git
- 9.3 Resumen
-
10. Los entresijos internos de Git
-
A1. Apéndice A: Git en otros entornos
- A1.1 Interfaces gráficas
- A1.2 Git en Visual Studio
- A1.3 Git en Eclipse
- A1.4 Git con Bash
- A1.5 Git en Zsh
- A1.6 Git en Powershell
- A1.7 Resumen
-
A2. Apéndice B: Integrando Git en tus Aplicaciones
- A2.1 Git mediante Línea de Comandos
- A2.2 Libgit2
- A2.3 JGit
-
A3. Apéndice C: Comandos de Git
- A3.1 Configuración
- A3.2 Obtener y Crear Proyectos
- A3.3 Seguimiento Básico
- A3.4 Ramificar y Fusionar
- A3.5 Compartir y Actualizar Proyectos
- A3.6 Inspección y Comparación
- A3.7 Depuración
- A3.8 Parcheo
- A3.9 Correo Electrónico
- A3.10 Sistemas Externos
- A3.11 Administración
- A3.12 Comandos de Fontanería
6.5 GitHub - Scripting en GitHub
Scripting en GitHub
Ya conocemos casi todas las características y modos de trabajo de GitHub. Sin embargo, cualquier grupo o proyecto medianamente grande necesitará personalizar o integrar GitHub con servicios externos.
Por suerte para nosotros, GitHub es bastante hackeable en muchos sentidos. En esta sección veremos cómo se usan los enganches (hooks) de GitHub y las API para conseguir hacer lo que queremos.
Enganches
Las secciones Hooks y Services, de la página de administración del repositorio en Github, es la forma más simple de hacer que GitHub interactúe con sistemas externos.
Servicios
En primer lugar, echaremos un ojo a los Servicios. Ambos, enganches y servicios, pueden configurarse desde la sección Settings del repositorio, el mismo sitio donde vimos que podíamos añadir colaboradores al proyecto o cambiar la rama predeterminada. Bajo la opción “Webhooks and Services” veremos algo similar a Sección Services and Hooks..
Hay docenas de servicios que podemos elegir, muchos de ellos para integrarse en otros sistemas de código abierto o comerciales. Muchos son servicios de integración continua, gestores de incidencias y fallos, salas de charla y sistemas de documentación. Veremos cómo levantar un servicio sencillo: el enganche con el correo electrónico. Si elegimos “email” en la opción “Add Service” veremos una pantalla de configuración similar a Configuración de servicio de correo..
En este caso, si pulsamos en el botón “Add service”, la dirección de correo especificada recibirá un correo cada vez que alguien envía cambios (push) al repositorio. Los servicios pueden dispararse con muchos otros tipos de eventos, aunque la mayoría sólo se usan para los eventos de envío de cambios (push) y hacer algo con los datos del mismo.
Si quieres integrar algún sistema concreto con GitHub, debes mirar si hay algún servicio de integración ya creado. Por ejemplo, si usas Jenkins para ejecutar pruebas de tu código, puedes activar el servicio de integración de Jenkins que lo disparará cada vez que alguien altera el repositorio.
Hooks (enganches)
Si necesitas algo más concreto o quieres integrarlo con un servicio o sitio no incluido en la lista, puedes usar el sistema de enganches más genérico. Los enganches de GitHub son bastante simples. Indicas una URL y GitHub enviará una petición HTTP a dicha URL cada vez que suceda el evento que quieras.
Normalmente, esto funcionará si puedes configurar un pequeño servicio web para escuchar las peticiones de GitHub y luego hacer algo con los datos que son enviados.
Para activar un enganche, pulsa en el botón “Add webhook” de Sección Services and Hooks.. Esto mostrará una página como Configuración de enganches web..
La configuración de un enganche web es bastante simple. Casi siempre
basta con incluir una URL y una clave secreta, y pulsar en “Add webhook”.
Hay algunas opciones sobre qué eventos quieres que disparen el envío de
datos (de forma predeterminada el único evento considerado es el evento
push
, que se dispara cuando alguien sube algo a cualquier rama del repositorio).
Veamos un pequeño ejemplo de servicio web para manejar un enganche web. Usaremos el entorno Sinatra de Ruby, puesto que es conciso y podrás entender con facilidad qué estamos haciendo.
Pongamos que queremos recibir un correo cada vez que alguien sube algo a una rama concreta del repositorio, modificando un archivo en particular. Podríamos hacerlo con un código similar a este:
require 'sinatra'
require 'json'
require 'mail'
post '/payload' do
push = JSON.parse(request.body.read) # parse the JSON
# gather the data we're looking for
pusher = push["pusher"]["name"]
branch = push["ref"]
# get a list of all the files touched
files = push["commits"].map do |commit|
commit['added'] + commit['modified'] + commit['removed']
end
files = files.flatten.uniq
# check for our criteria
if pusher == 'schacon' &&
branch == 'ref/heads/special-branch' &&
files.include?('special-file.txt')
Mail.deliver do
from 'tchacon@example.com'
to 'tchacon@example.com'
subject 'Scott Changed the File'
body "ALARM"
end
end
end
Aquí estamos tomando el bloque JSON que GitHub entrega y mirando quién hizo el envío, qué rama se envió y qué archivos se modificaron en cada “commit” realizado en este push. Entonces, comprobamos si se cumple nuestro criterio y enviamos un correo si es así.
Para poder probar algo como esto, tienes una consola de desarrollador en la misma pantalla donde configuraste el enganche, donde se pueden ver las últimas veces que GitHub ha intentado ejecutar el enganche. Para cada uno, puedes mirar qué información se ha enviado y si fué recibido correctamente, junto con las cabeceras correspondientes de la petición y de la respuesta. Esto facilita mucho las pruebas de tus enganches.
Otra cosa muy interesante es que puedes repetir el envío de cualquier petición para probar el servicio con facilidad.
Para más información sobre cómo escribir webhooks (enganches) y los diferentes tipos de eventos que puedes tratar, puedes ir a la documentación del desarrollador de GitHub, en: https://developer.github.com/webhooks/
La API de GitHub
Servicios y enganches nos sirven para recibir notificaciones “push” sobre eventos que suceden en tus repositorios. Pero, ¿qué pasa si necesitas más información acerca de estos eventos?, ¿y si necesitas automatizar algo como añadir colaboradores o etiquetar incidencias?
Aquí es donde entra en juego la API de GitHub. GitHub tiene montones de llamadas de API para hacer casi cualquier cosa que puedes hacer vía web, de forma automatizada. En esta sección aprenderemos cómo autentificar y conectar a la API, cómo comentar una incidencia y cómo cambiar el estado de un Pull Request mediante la API.
Uso Básico
Lo más básico que podemos hacer es una petición GET a una llamada que no necesite autentificación. Por ejemplo, información de solo lectura de un proyecto de código abierto. Por ejemplo, si queremos conocer información acerca del usuario “schacon”, podemos ejecutar algo como:
$ curl https://api.github.com/users/schacon
{
"login": "schacon",
"id": 70,
"avatar_url": "https://avatars.githubusercontent.com/u/70",
# …
"name": "Scott Chacon",
"company": "GitHub",
"following": 19,
"created_at": "2008-01-27T17:19:28Z",
"updated_at": "2014-06-10T02:37:23Z"
}
Hay muchísimas llamadas como esta para obtener información sobre
organizaciones, proyectos, incidencias, commits, es decir, todo lo que
podemos ver públicamente en la web de GitHub. Se puede usar la API para
otras cosas como ver un archivo Markdown cualquiera o encontrar una
plantilla de .gitignore
.
$ curl https://api.github.com/gitignore/templates/Java
{
"name": "Java",
"source": "*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
"
}
Comentarios en una incidencia
Sin embargo, si lo que quieres es realizar una acción como comentar una incidencia o un Pull Request, o si quieres ver o interactuar con un contenido privado, necesitas identificarte.
Hay varias formas de hacerlo. Puedes usar la autentificación básica, con tu usuario y tu contraseña, aunque generalmente es mejor usar un token de acceso personal. Puedes generarlo en la opción “Applications” de tu página de ajustes personales.
Te preguntará acerca del ámbito que quieres para el token y una descripción. Asegúrate de usar una buena descripción para que te resulte fácil localizar aquellos token que ya no necesitas.
GitHub te permitirá ver el token una vez, por lo que tienes que copiarlo en ese momento. Ahora podrás identificarte en el script con el token, en lugar del usuario y la contraseña. Esto está bien porque puedes limitar el ámbito de lo que se quiere hacer y porque el token se puede anular.
También tiene la ventaja de incrementar la tasa de accesos. Sin la autentificación podrás hacer 60 peticiones a la hora. Con una identificación el número de accesos permitidos sube a 5,000 por hora.
Realicemos entonces un comentario en una de nuestras incidencias. Por ejemplo,
queremos dejar un comentario en la incidencia #6. Para ello, hacemos una
petición HTTP POST a repos/<usuario>/<repo>/issues/<num>/comments
con el
token que acabamos de generar como cabecera Authorization.
$ curl -H "Content-Type: application/json" \
-H "Authorization: token TOKEN" \
--data '{"body":"A new comment, :+1:"}' \
https://api.github.com/repos/schacon/blink/issues/6/comments
{
"id": 58322100,
"html_url": "https://github.com/schacon/blink/issues/6#issuecomment-58322100",
...
"user": {
"login": "tonychacon",
"id": 7874698,
"avatar_url": "https://avatars.githubusercontent.com/u/7874698?v=2",
"type": "User",
},
"created_at": "2014-10-08T07:48:19Z",
"updated_at": "2014-10-08T07:48:19Z",
"body": "A new comment, :+1:"
}
Ahora, si vas a la incidencia, verás el comentario que acabas de enviar tal como en Comentario enviado desde la API de GitHub..
Puedes usar la API para hacer todo lo que harías en el sitio web: crear y ajustar hitos, asignar gente a incidencias o Pull Requests, crear y cambiar etiquetas, acceder a datos de “commit”, crear nuevos commits y ramas, abrir, cerrar o fusionar Pull Requests, crear y editar equipos, comentar líneas de cambio en Pull Requests, buscar en el sitio y mucho más.
Cambio de estado de un Pull Request
Un ejemplo final que veremos es realmente útil si trabajas con Pull Requests. Cada “commit” tiene uno o más estados asociados con él, y hay una API para alterar y consultar ese estado.
Los servicios de integración continua y pruebas hacen uso de esta API para actuar cuando alguien envía código al repositorio, probando el mismo y devolviendo como resultado si el “commit” pasó todas las pruebas. Además, se podría comprobar si el mensaje del “commit” tiene un formato adecuado, si el autor siguió todas las recomendaciones para autores, si fue firmado, etc.
Supongamos que tenemos un enganche web en el repositorio que llama a un servicio
web que comprueba si en el mensaje del “commit” aparece la cadena Signed-off-by
.
require 'httparty'
require 'sinatra'
require 'json'
post '/payload' do
push = JSON.parse(request.body.read) # parse the JSON
repo_name = push['repository']['full_name']
# look through each commit message
push["commits"].each do |commit|
# look for a Signed-off-by string
if /Signed-off-by/.match commit['message']
state = 'success'
description = 'Successfully signed off!'
else
state = 'failure'
description = 'No signoff found.'
end
# post status to GitHub
sha = commit["id"]
status_url = "https://api.github.com/repos/#{repo_name}/statuses/#{sha}"
status = {
"state" => state,
"description" => description,
"target_url" => "http://example.com/how-to-signoff",
"context" => "validate/signoff"
}
HTTParty.post(status_url,
:body => status.to_json,
:headers => {
'Content-Type' => 'application/json',
'User-Agent' => 'tonychacon/signoff',
'Authorization' => "token #{ENV['TOKEN']}" }
)
end
end
Creemos que esto es fácil de seguir. En este controlador del enganche, miramos
en cada “commit” enviado, y buscamos la cadena Signed-off-by en el mensaje de
“commit”, y finalmente hacemos un HTTP POST al servicio de API
/repos/<user>/<repo>/statuses/<commit_sha>
con el resultado.
En este caso, puedes enviar un estado (success, failure, error), una descripción de qué ocurrió, una URL objetivo donde el usuario puede ir a buscar más información y un “contexto” en caso de que haya múltiples estados para un “commit”. Por ejemplo, un servicio de test puede dar un estado, y un servicio de validación puede dar por su parte su propio estado; el campo “context” serviría para diferenciarlos.
Si alguien abre un nuevo Pull Request en GitHub y este enganche está configurado, verías algo como Estado del commit mediante API..
Podrás ver entonces una pequeña marca de color verde, que nos indica que el “commit” tiene la cadena “Signed-off-by” en el mensaje y un aspa roja en aquellos donde el autor olvidase hacer esa firma. También verías que el Pull Request toma el estado del último “commit” en la rama y te avisa de si es un fallo. Esto es realmente útil si usas la API para pruebas, y así evitar hacer una fusión accidental de unos commits que han fallado las pruebas.
Octokit
Hasta ahora hemos hecho casi todas las pruebas con curl
y peticiones HTTP
simples, pero en GitHub hay diferentes bibliotecas de código abierto que hacen
más fácil el manejo de la API, agrupadas bajo el nombre de Octokit. En el
momento de escribir esto, están soportados lenguajes como Go, Objective-C, Ruby
y .NET. Se puede ir a https://github.com/octokit para más información sobre
esto, que te ayudarán a manejar peticiones y respuestas a la API de GitHub.
Con suerte estas utilidades te ayudarán a personalizar y modificar GitHub para integrarlo mejor con tu forma concreta de trabajar. Para una documentación completa de la API así como ayudas para realizar tareas comunes, puedes consultar en https://developer.github.com.