Actualizaciones automáticas con PHP y GitHub

Hace ya un tiempo me plantee la duda de si habría alguna manera de que con un simple git push al repositorio del proyecto desde mi máquina de desarrollo se actualizaran los cambios automáticamente en el servidor de producción.

Cada repositorio en GitHub tiene la opción de comunicarse con un servidor web cada vez que se recibe un evento push, mediante los llamados Webhooks, y que puedes encontrar en Settings -> Webhooks & Services, dentro de cada repositorio. Si entras en este apartado verás que el primer dato que te solicita es el Payload URL, que no es mas que la URL del script al que llamará cada vez que se ejecute el evento push.

Visto esto decidí desarrollar un pequeño script en PHP que se encargará de atender esta llamada desde GitHub y recoger los cambios para actualizarlos en el servidor, mediante git clone o git pull. Al comenzar me encontré con algunas cuestiones:

-El usuario que ejecuta el comando git para actualizar, en este caso es apache.
-El usuario de apache necesita permisos de lectura y escritura en el repositorio del servidor.
-Hay que asegurarse de que el host de GitHub es añadido al fichero known_hosts de apache.
-Este usuario apache necesita su propias keys para comunicarse con el repositorio remoto.

Y así es como lo resolví:

En el servidor de producción:

1. El usuario de apache necesita permisos de lectura y escritura al repositorio del servidor:

2. Crear la carpeta .ssh, que es donde se almacenarán las keys:

3. Generar las keys para el usuario de apache:

4. Añadir la autenticación al fichero known_hosts, para que no pregunte al ejecutar el comando git clone:

En GitHub:

1. Añadir la key (id_rsa.pub) al repositorio en GitHub (dentro del repositorio->Settings->Deploy keys)

2. Añadir el Webhook poniendo en Payload URL la url al script de la forma: http://mydomain.com/deploy.php?token=mytoken

A partir de este momento, en cuanto hago un git push desde mi máquina de desarrollo automáticamente veo los cambios en el servidor de producción, sin tener que conectarme por ftp.

Evidentemente este script se puede mejorar utilizando dos ramas, una principal y otra de desarrollo (por ejemplo master y dev) y que solo actualice en el servidor de producción cuando haga push sobre la rama master, pero no la dev.

Puedes encontrar el código fuente en PHP en GitHub: https://github.com/vicentegarcia/autodeploy-php-github