Benoît Courtine



    Navigation
     » Accueil
     » A propos
     » Mentions légales
     » XML Feed

    Vers Gitlab Pages en douceur

    30 Nov 2020 (MAJ le 02/12/2020 à 09:00) » perso, jekyll, script

    À l’origine

    Dans cet article, j’expliquais comment ce blog est déployé automatiquement lors d’un git push via un script Gitlab CI.

    Et puis je suis tombé sur ce tuto de Philippe Charrière, où il explique comment déployer un blog statique sur Gitlab Pages. Bon…​ c’était juste avant de migrer vers un blog à base de tickets Gilab. Et même si je trouve le concept génial, je ne suis pas tout à fait près à franchir le pas.

    En revanche, le tuto m’a bien donné envie d’essayer de publier sur Gitlab Pages, et ce d’autant plus que les sources sont déjà hébergées sur Gitlab. À terme, cela pourrait me permettre de me passer de la Dedibox que j’utilise actuellement pour l’hébergement.

    Mise en œuvre

    Par rapport au tuto, deux différences qui semblent faciles à contourner :

    • le blog n’est pas directement constitué de pages, mais il est construit avec Jekyll ;

    • il doit être déployé simultanément sur la Dedibox actuelle, et sur Gilab Pages (au moins dans un premier temps).

    Le premier essai naïf

    Il semble y avoir très peu de choses à modifier par rapport à l’ancienne version, et il s’agit d’ailleurs exclusivement de renommage :

    • l’étape de construction doit s’appeler pages (et non build ou autre chose) ;

    • le site doit être construit dans le répertoire public.

    Divulgâchis : ne vous précipitez pas sur cette première version…​ elle ne fonctionne pas comme prévu.
    Premier essai de configuration ".gitlab-ci.yml"
    image: ruby:2.6
    
    stages:
      - pages
      - deploy
    
    variables:
      JEKYLL_ENV: production
      LC_ALL: C.UTF-8
    
    cache:
      paths:
        - /vendor
    
    before_script:
      - gem install bundler
      - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    
    pages:
      stage: pages
      script:
        - bundle install --path=/vendor
        - bundle exec jekyll build -d public
      artifacts:
        paths:
          - public
      only:
        - master
    
    deploy:
      stage: deploy
      script:
        - eval $(ssh-agent -s)
        - echo "$SSH_PRIVATE_KEY" | ssh-add -
        - "scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -r public [email protected]$BLOG_SERVER:~/blog/"
      dependencies:
        - pages
      only:
      - master

    Le problème

    Techniquement, ça se déploie bien. En revanche, tous les liens du site sur Gitlab Pages sont cassés, et le résultat est inutilisable.

    Celà vient du fait que les pages sont déployées à l’adresse https://bcourtine.gitlab.io/blog/, alors que le site autohébergé est servi à l’adresse https://blog.courtine.org/ sans préfixe. Et je ne sais pas s’il est possible de modifier facilement ce point pour héberger directement à l’adresse https://bcourtine.gitlab.io/.

    Pour y remédier, nous allons donc jouer avec les templates Jekyll :

    • on ajoute au fichier _config.yml une propriété baseurl (si elle n’existe pas encore) ;

    • on n’oublie pas de la prendre en compte également dans les variables Asciidoc du fichier ;

    • on vérifie que les liens dans les templates Jekyll sont tous bien préfixés par cette variable (par exemple {{ post.url | prepend: site.baseurl }}).

    Extrait de _config.yml
    # ...
    
    baseurl: '' # '/blog' pour Gitlab Pages
    url: 'https://blog.courtine.org'
    
    permalink: '/:year/:month/:day/:title/'
    
    jsdir: '/js' (1)
    stylesdir: '/css' (2)
    imagesdir: '/images' (2)
    
    asciidoctor:
      base_dir: :docdir
      attributes:
        imagesdir: '{site.baseurl}/images'
        iconsdir: '{site.imagesdir}/icons'
        stylesdir: '{site.baseurl}/css'
        # ...
    1 À utiliser dans les templates sous la forme {{ site.jsdir | prepend: site.baseurl }}.
    2 Idem.

    Comme ces variables sont évaluées au moment de la construction du site par Jekyll, on n’a pas le choix de construire deux fois le blog, en modifiant les variables entre les deux constructions. Un simple sed fait l’affaire pour ça.

    Voici donc la configuration Gitlab qui marche pour mon cas d’utilisation.

    Configuration ".gitlab-ci.yml" fonctionnelle
    image: ruby:2.6
    
    stages:
      - pages
      - deploy
    
    variables:
      JEKYLL_ENV: production
      LC_ALL: C.UTF-8
    
    cache:
      paths:
        - /vendor
    
    before_script:
      - gem install bundler
      - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    
    pages:
      stage: pages
      script:
        - bundle install --path=/vendor
    
        # Build for https://blog.courtine.org/
        - bundle exec jekyll build -d _site
    
        # Replace url and build for Gitlab Pages
        - "sed -i \"s|^url:.*|url: 'https://bcourtine.gitlab.io'|\" _config.yml"
        - "sed -i \"s|^baseurl:.*|baseurl: '/blog'|\" _config.yml"
        - bundle exec jekyll build -d public
      artifacts:
        paths:
          - _site
          - public
      only:
        - master
    
    deploy:
      stage: deploy
      script:
        - eval $(ssh-agent -s)
        - echo "$SSH_PRIVATE_KEY" | ssh-add -
        - "scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -r _site [email protected]$BLOG_SERVER:~/blog/"
      dependencies:
        - pages
      only:
      - master
    Il faut bien penser à mettre à jour la visibilité des pages pour rendre le site public si le dépôt est privé (les pages sont également privées par défaut dans ce cas).

    Google analytics

    J’utilise Google Analytics pour connaître la fréquentation (ridicule) du blog, et les articles les plus consultés. Or, avec ce double déploiement, les pages /article et /blog/article sont référencées de manière distincte, là où je voudrais un comptage unique des consultations.

    Mais Google Analytics a une manière élégante de résoudre ce problème. Dans Admin > All Filters, il est possible d’ajouter des filtres. Nous créons donc un filtre de type Custom > Search and Replace : sur le champ Request URI, on remplace /blog/ par / et le tour est joué.

    Conclusion

    Avec finalement peu d’efforts, tout marche comme on veut : merci Philippe !

    Lors de cette opération, j’ai fait un passage en revue des templates (j’avais parfois été fainéant en omettant le filtre prepend). J’en ai profité pour nettoyer un peu et ne garder que le minimum :

    • Suppression de Disqus, qui était très peu utilisé ;

    • Suppression des liens de partage sur les réseaux sociaux, pour la même raison ;

    Je n’ai conservé qu’un Google Analytics (anonymisé)…​ mais je le consulte tellement peu que je songe à le supprimer également.