Aller au contenu

Pages⚓︎

J’utilise de plus en plus Gitlab Pages (et ses dérivés, par exemple Framagit). C’est moins intuitif que ce que j’ai pu expérimenter avec Microsoft Github Pages, aussi voici quelques configurations de base et astuces collectées/expérimentées ici et là car je me perds régulièrement dans la documentation officielle.

Servir un dossier qui contient du HTML⚓︎

🐣 2022-11

Il faut commencer par créer un dépôt puis par mettre tous les fichiers HTML (et autres !) dans un dossier public/. Ensuite, on ajoute le fichier .gitlab-ci.yml à la racine du dépôt.

Warning

Il faut bien un point . au début du nom du fichier !

.gitlab-ci.yml
1
2
3
4
5
6
7
8
pages:
  stage: deploy
  script: echo "Youpi"
  artifacts:
    paths:
      - public  # (1)!
  rules:
    - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH  # (2)!
  1. Vous pouvez changer cette ligne si vous ne mettez pas tous vos fichiers dans le dossier public/.
  2. Ici on restreint le déploiement à la branche principale (en général master ou main).

Une fois tout cela commité/pushé sur le dépôt, vous devriez pouvoir accéder à :

https://NOM-DU-COMPTE.gitlab.io/NOM-DU-DEPOT/

Si vous ne voyez rien apparaître au bout de quelques secondes/minutes, vous pouvez aller voir le détail des erreurs directement au niveau du dépôt dans CI/CD → Pipelines.

Améliorer les performances avec gzip⚓︎

🐣 2022-11

Je découvre grâce à Magentix que les fichiers statiques ne sont pas servis par défaut en étant gzipés.

Je dois avouer que je n’ai pas trop regardé les performances sur ces environnements car en général je m’en sers uniquement pour des prototypes.

Il est possible de convertir les fichiers statiques lors du déploiement avec l’ajout du script suivant :

.gitlab-ci.yml
1
2
3
4
pages:
  # Tout le reste.
  script:
    - find public -type f -regex '.*\.\(html\|js\|css\)$' -exec gzip -f -k {} \;

Info

Notez que vous pouvez adapter la liste des extensions concernées dans la commande (ici le .html, .js et .css).

Générer les pages avec Python⚓︎

🐣 2022-11

Bien souvent on ne veut pas commiter directement les pages en HTML mais plutôt se servir de l’intégration continue pour les générer.

La configuration ci-dessous utilise un générateur de site statique en Python pour générer les pages HTML à partir de fichiers markdown qui sont eux ajoutés au dépôt. On peut imaginer pas mal d’autres usages, ce n’est qu’un exemple.

.gitlab-ci.yml
# Inspired from
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/↩
# lib/gitlab/ci/templates/Python.gitlab-ci.yml
image: python:latest

# Change pip's cache directory to be inside the project directory since we can
# only cache local items.
variables:
  PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"

# Pip's cache doesn't store the python packages
# https://pip.pypa.io/en/stable/reference/pip_install/#caching
cache:
  paths:
    - .cache/pip

# The locale part is important for dates rendering (Jinja2).
before_script:
  - apt-get update --quiet --yes
  - apt-get install --yes apt-utils
  - apt-get install --yes locales locales-all

pages:
  stage: deploy
  script:
    - python -m pip install \
      --disable-pip-version-check --quiet \
      --requirement requirements.txt  # (1)!
    - make build  # (2)!
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH  # (3)!
  1. On installe les dépendances avec pip (ou tout autre système)
  2. On lance la commande de build qui est gérée dans un Makefile et qui produit les fichiers HTML dans le dossier public/ (ou modifier la ligne en-dessous)
  3. On ne déploie que la branche principale (main en général de nos jours)

On utilise un cache pour pip afin de rendre les futurs déploiements plus rapides.

Déployer une version du site par branche⚓︎

🐣 2023-02

C’est la suite de la configuration ci-dessus, parfois on veut pouvoir déployer une branche pour des tests tout en gardant la branche principale/de production à la racine de nos Gitlab Pages.

Ce script de déploiement va déployer la nouvelle branche poussée (et les futurs commits) sur :

https://<username>.gitlab.io/<repository>/<branch-name>/

(En plus de conserver https://<username>.gitlab.io/<repository>/ pour la branche principale.)

Warning

Chaque déploiement d’une nouvelle branche va écraser une précédente branche déployée (tout en redéployant la branche principale). Chaque commit sur votre branche principale va aussi supprimer le déploiement de la branche précédemment mise à jour. Ce n’est peut-être pas ce que vous souhaitez !

Il est possible de faire des choses plus avancées avec des patterns de noms de branches pertinentes par exemple à mettre dans la clé rules. À vous de voir ce qui est compatible avec votre fonctionnement.

.gitlab-ci.yml
# Idem au-dessus
# image: python:latest etc

pages:
  stage: deploy
  script:
    # Install and deploy the current branch to /branch-name/ path.
    - python -m pip install \
      --disable-pip-version-check --quiet \
      --requirement requirements.txt
    - dir="$CI_COMMIT_REF_SLUG/"
    - if [ "$CI_COMMIT_REF_SLUG" == "$CI_DEFAULT_BRANCH" ]; then dir=""; fi;
    - baseurl="https://<username>.gitlab.io/<repository>/$dir"
    - echo "BASE_URL='$baseurl'" > .env  # (1)!
    - dir="public/$dir"
    - make build target=$dir  # (2)!
    - echo "Branch '$CI_COMMIT_REF_SLUG' deployed to $baseurl"

    # Install and deploy the default branch at the root of the path.
    - git fetch
    - git checkout $CI_DEFAULT_BRANCH  # (3)!
    - git reset --hard origin/$CI_DEFAULT_BRANCH
    - python -m pip install \
      --disable-pip-version-check --quiet \
      --requirement requirements.txt
    - baseurl="https://<username>.gitlab.io/<repository>/"
    - echo "BASE_URL='$baseurl'" > .env
    # If it is the main branch, it is already deployed.
    - if [ "$CI_COMMIT_REF_SLUG" != "$CI_DEFAULT_BRANCH" ]; then make build; fi;
    - echo "Branch '$CI_DEFAULT_BRANCH' deployed to $baseurl"
  artifacts:
    paths:
      - public
  1. Un exemple de personnalisation de l’environnement (couplé à dotenv c’est plus propre), c’est optionnel mais c’est pour donner une idée
  2. La commande de construction doit accepter un paramètre lui indiquant où générer le site
  3. On revient maintenant sur la branche principale pour déployer à la racine

PS : mettre en cache les installations via apt-get est non trivial, j’ai passé un bon moment avant d’abandonner… la recommandation officielle étant de faire sa propre image Docker.

Générer des fichiers .webp à partir de fichiers .jpg⚓︎

🐣 2023-02

Ceci n’est pas vraiment une recette mais une inspiration, ça dépend ensuite vraiment de ce que vous voulez faire des images générées ! C’est à adapter aussi si vous avez du png, etc.

.gitlab-ci.yml
# Idem au-dessus
# image: python:latest etc

before_script:
  - apt-get install --yes cpio webp  # (1)!

pages:
  stage: deploy
  script:
    - python -m pip install --disable-pip-version-check --quiet webp-converter  # (2)!
    - find static -type f -iname "*.jpg" | \
      cpio -p --make-directories --preserve-modification-time webp/  # (3)!
    - webpc --r --quality-ratio 50 webp  # (4)!
  artifacts:
    paths:
      - public
  1. On installe les dépendances système
  2. On installe l’utilitaire Python webp-converter
  3. On crée une arborescence dans webp/ avec les fichiers jpg depuis le dossier static/
  4. On convertit sur place cette nouvelle arborescence pour avoir des fichiers webp

Il est possible de modifier le ratio de qualité en fonction de vos besoins, on peut descendre assez bas selon les cas mais ça finit par ternir les images.

C’est à vous ensuite de mettre cette arborescence là où c’est pertinent pour votre produit.

Pro-tip!

Toujours mettre des options en version étendue dans les scripts (d’intégration continue).

Bloquer le déploiement (ou les tests) avec un mot-clé⚓︎

🐣 2023-04

Vous voulez parfois ne pas exécuter l’une des commandes définies dans votre intégration continue (typo qui ne nécessite pas un redéploiement, fichier de configuration qui n’impacte pas les tests, etc).

.gitlab-ci.yml
1
2
3
4
5
6
7
8
9
pages:
  stage: deploy
  script:
    - make build
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /nopages/  # (1)!
  1. On ajoute une règle pour que le lancement ne s’effectue que lorsque le message (titre ou description) de commit ne contient pas (!~) le mot-clé « nopages ».

Lorsqu’il s’agit d’une tâche qui ne comporte pas de rules, c’est encore plus facile/explicite avec le bout de configuration suivant :

.gitlab-ci.yml
1
2
3
4
5
6
test:
  script:
    - make test
  except:
    variables:
      - $CI_COMMIT_MESSAGE =~ /notest/  # (1)!
  1. La combinaison du except et du =~ permet de ne pas lancer la tâche lorsque le message (titre ou description) de commit contient le mot-clé « notest ».

Préservation des ressources

Vous avez beau squatter les ressources matérielles des autres, ça n’en reste pas moins des CPU qui tournent de l’autre côté de la planète et qui réchauffent de l’eau (au mieux). Avoir un moyen de passer outre cette consommation continue est quand même pas mal.


Dernière mise à jour: 2023-04-19