Migrar a GitLab manteniendo mirrors en GitHub

08/06/2018Por iCarto

Estos días, en iCarto, hemos terminado la migración que teníamos planificada de nuestros repositorios dispersos entre Bitbucket y GitHub a GitLab.

Las tres plataformas ofrecen funcionalidades similares para nuestros casos de uso. A nivel coste GitLab es más barata que GitHub y aunque es más cara que Bitbucket su apuesta por el Software Libre es más clara que la de los otros servicios. La posibilidad de montar la infraestructura propia en caso de tener que escapar de soluciones cloud es un punto a su favor. Además dado que su capa gratuita ofrece infinitos repositorios públicos y privados sin limitación de usuarios, hace que en la práctica puede ser usada sin coste en muchas situaciones.

Hemos decidido mantener nuestra presencia en GitHub, porqué sigue siendo la plataforma de referencia a la hora de evaluar contribuciones públicas de código y por tanto puede tener un efectivo positivo a nivel marketing.

GitLab da la opción de hacer push automático a modo de mirror a un repositorio remoto. Pero en ocasiones puede interesar hacerlo de forma manual a través de un servidor intermedio. Así es como lo estamos haciendo en iCarto.

Eliminamos los permisos de escritura a todos los repos de GitHub, excepto para el usuario «icarto».

En un servidor interno descargamos los repositorios preparados para hacer de puente entre ambos servicios. Para un conjunto de respositorios se puede usar un script como este, que descarga los repositorios en modo mirror desde gitlab y habilita como remote github:

REPOS="/home/mirrors/"
cd "${REPOS}"

HUB_USER="github_user:github_pass"
LAB_USER="gitlab_user:gitlab_pass"

DIRS=(utentes-api.git extELLE.git vial.git repo_xyz.git)

for DIR in ${DIRS[*]}; do
    echo "Procesando ${DIR}..."
    git clone --mirror https://${LAB_USER}@gitlab.com/icarto/${DIR}
    cd "${DIR}"
    git remote set-url --push origin https://${HUB_USER}@github.com/iCarto/${DIR}
    cd ..
done

Logicamente se puede usar ssh en lugar the basic auth.

Escribimos un pequeño script que haga fetch de gitlab y push a github

#!/bin/bash

# mirror_gitlab_to_github
# Don't use extension for the filename,
# or problems with cron could arise

REPOS="/home/mirrors/"

for i in `/bin/ls ${REPOS}` ; do
    DIR="${REPOS}${i}"
    cd "${DIR}"
    git fetch -p origin && git push --mirror
done

El parámetro fetch -p elimina en el repositorio local las referencias a ramas borradas en el remoto.

Y configuramos una tarea de cron que se ejecuta de forma periódico. En nuestro caso lo estamos ejecutando de forma semanal

cp mirror_gitlab_to_github /etc/cron.weekly
chmod 755 /etc/cron.weekly/mirror_gitlab_to_github

También es posible implementar un «two way mirror» pero en la mayoría de los casos no será necesario.