Externalización gráfica de servidor Git propio con stagit
23 de noviembre de 2020 • fjbalon
A veces es agradable navegar por el registro del historial de git en un navegador web o en algún otro programa sin tener que mirar el repositorio local. Es además una forma de mantener un registro de los repositorios que sean públicos, a modo de currículum o expositor de código. Si además se cumple el requisito personal de cumplir con una regla o una filosofía minimalista, de web estática en este caso y libre, aún mejor.
Para ello uso el impecable stagit, que es un generador de pagínas estáticas para git desarrollado por codemadness.org. Su uso es simple. Manualmente consta de dos partes, que son la creación de directorios html (que deben ser accesibles mediante servidor web) y su enlace con el directorio del servidor git:
mkdir -p /srv/git/htmlrepo1 && cd /srv/git/htmlrepo1
stagit /git/gitrepo1
Y la formación del índice y el htmlroot:
cd /srv/git
stagit-index /git/gitrepo1 /git/gitrepo2 /git/gitrepo3 > index.html
Ejemplos de resultados son templier.es/git, codemadness.org/git o git.suckless.org.
Para automatizar la actualización del directorio en función de los cambios de push añadimos a htmlroot (
# /srv/git/create.sh
reposdir="/git"
curdir="$(pwd)"
stagit-index "${reposdir}/"*/ > "${curdir}/index.html"
for dir in "${reposdir}/"*/; do
# strip .git suffix.
r=$(basename "${dir}")
d=$(basename "${dir}" ".git")
printf "%s... " "${d}"
mkdir -p "${curdir}/${d}"
cd "${curdir}/${d}" || continue
stagit -c ".cache" -u "/git/$d/" "${reposdir}/${r}"
# symlinks
ln -sf log.html index.html
ln -sf ../style.css style.css
ln -sf ../logo.png logo.png
ln -sf ../favicon.png favicon.png
echo "done"
done
Por supuesto, el script anterior debe contar con permisos de ejecución; y el directorio htmlroot debe tener permisos adecuados para su manipulación, que siendo en este caso el usuario git el que genere de nuevo los HTML, debería éste tener permisos totales.
Además, por cada repositorio del servidor debemos añadir el hook post-receive tal que:
#!/bin/sh
# /git/code.git/hooks/post-receive
export LC_CTYPE="en_US.UTF-8"
name="$1"
if test "${name}" = ""; then
name=$(basename "$(pwd)")
fi
reposdir="/git"
dir="${reposdir}/${name}"
htmldir="/srv/git"
stagitdir="/"
destdir="${htmldir}${stagitdir}"
cachefile=".htmlcache"
if ! test -d "${dir}"; then
echo "${dir} does not exist" >&2
exit 1
fi
cd "${dir}" || exit 1
force=0
while read -r old new ref; do
test "${old}" = "0000000000000000000000000000000000000000" && continue
test "${new}" = "0000000000000000000000000000000000000000" && continue
hasrevs=$(git rev-list "${old}" "^${new}" | sed 1q)
if test -n "${hasrevs}"; then
force=1
break
fi
done
r=$(basename "${name}")
d=$(basename "${name}" ".git")
printf "[%s] stagit HTML pages... " "${d}"
mkdir -p "${destdir}/${d}"
cd "${destdir}/${d}" || exit 1
if test "${force}" = "1"; then
rm -f "${cachefile}"
rm -rf "commit"
fi
stagit-index "${reposdir}/"*/ > "${destdir}/index.html"
stagit -c "${cachefile}" -u "/git/$d/" "${reposdir}/${r}"
ln -sf log.html index.html
ln -sf ../style.css style.css
ln -sf ../logo.png logo.png
echo "done"
También debe contar con privilegios de ejecución. Lo que hará que en cada push recibido, el contenido HTML de stagit se actualice.
Para una correcta impresión de los datos, es necesario que cada directorio de repositorio tenga en su raíz los ficheros owner, description y url:
cd /git/code
echo "fjbalon" > owner
echo "Descripción del repositorio" > description
echo "git://templier.es/code.git" > url
Las imágenes por defecto empleadas son favicon.png y logo.png, que irán en la raíz de htmlroot (/srv/git). También style.css.
cp stagit/style.css /srv/git/
cp stagit/favicon.png /srv/git/
cp stagit/logo.png /srv/git/
En este ejemplo damos al hook post-receive del repositorio del sitio web la capacidad de autodesplegarse al recibir push, con el ejemplo de esta propia web estática para que, con mi propio push autenticado por SSH, automáticamente se lance como actualización al servidor Apache.
#!/bin/sh
# /git/arrakis.git/hooks/post-receive
echo "Ejecutando hook postreicive: desplegando a producción el static-site"
git --work-tree=/srv/http --git-dir=/tex/arrakis.git checkout -f master
Por supuesto, los permisos del directorio htmlroot deben tener los permisos para git.
drwxr-xr-x 3 git git 4096 Dec 14 15:53 http