Créer une chaîne de publication d’e-book(s) avec GitLab, GitLab-CI, Vagrant & AsciiDoctor
Il y a quelques semaines j’ai pris la décision d’écrire un e-book sur VueJS (dont nous ne parlerons pas aujourd’hui) pour voir si j’arrivais à financer mes 🍺🍺🍺. Rapidement, j’ai été amené à me poser quelques questions: quel format ? (markdown, AsciiDoc, …), comment je vais générer mon pdf ?, comment je vais m’organiser ? (outils en ligne, éditeur de texte, …) etc. …
De quoi allons nous parler ?
- Mes choix & pourquoi
- Setup de la chaîne de publication (installation de GitLab, préparation d’un runner avec AsciiDoctor)
- Paramétrages de votre projet d’e-book (mise en page, …)
- Utilisation de la chaîne de publication
Mes choix
👋 Vous pouvez passer directement au paragraphe suivant si vous n’avez pas besoin d’être convaincus du choix des outils.
AsciiDoc & AsciiDoctor
Je n’en suis pas à mon 1er essai d’écriture d’e-book: ce sera la 4ème fois. Les 3 fois précédentes, j’ai utilisé le format markdown qui est parfait pour des billets de blogs, mais dès que votre article devient très technique, vous vous apercevez que markdown a des limites, et notamment lorsque vous souhaitez “expliquer” du code:
Ensuite, la génération du pdf comme livrable final a aussi pesé fortement dans mes choix techniques. L’outil AsciiDoctor propose un projet compagnon, AsciiDoctor-Pdf qui permet un contrôle fin sur la génération et la mise en page de votre pdf.
Dernier argument de poids (qui en fait a initié les 2 précédents): en cherchant plus d’informations sur AsciiDoc, je suis forcément “tombé” sur la présentation de mon camarade Hubert Sablonnière (et maintenant collègue de boulot 😃) “Document as Code (expliqué à mon père)” (cela devrait finir de vous décider)
GitLab & GitLab-CI
Pourquoi utiliser un gestionnaire de code source comme GitLab (ou GitHub) pour écrire un livre? Alors il y a de nombreuses raisons, en voici quelques unes:
- écrire du texte, c’est comme écrire du code: la notion de feature branch se prête parfaitement à la rédaction de chapitres (et donc à l’écriture de plusieurs chapitres en parallèle)
- il y a un rendu d’AsciiDoc directement dans GitLab (avec GitHub aussi). Cela sera différent du rendu final en pdf, mais c’est bien pratique
- lorsque j’ai une “idée”, quelque chose à noter, … je peux utiliser les issues qui font des brouillons et post-its parfaits
- mon e-book est technique, il y a du code, et ce code est lui aussi géré dans GitLab, je peux donc sauter des codes sources au projet d’e-book et vice et versa facilement dans la même IHM
- et bien sûr, si vous voulez écrire à plusieurs, faire relire votre prose, … ce type d’outil étant par définition collaboratif, il devient incontournable
- etc. …
Mais quel est l’intérêt d’utiliser GitLab-CI ?
Utiliser GitLab-CI me permet d’installer un runner avec les outils nécessaires pour faire “tourner” AsciiDoctor et AsciiDoctor-Pdf, qui sera appelé simplement à partir de mon projet d’e-book GitLab pour générer automatiquement le pdf à chaque fois que je le demande, ou à chaque fois que je merge un chapitre sur la branche master
par exemple, et tout cela toujours au sein de la même IHM tout en bénéficiant du rendu pdf directement dans l’outil.
Et que vient faire Vagrant là dedans?
Alors, je pouvais très bien utiliser mon compte sur GitLab.com et déployer un runner sur Clever Cloud (j’explique ici comment faire: “Déployer un runner GitLab sur Clever Cloud”), mais je me déplace pas mal, et j’ai besoin de l’ensemble de la chaîne en mode offline (notamment pour les issues et la génération du pdf). Du coup j’ai décidé de virtualiser ma chaîne d’édition avec du VirtualBox et j’utilise Vagrant pour reproduire facilement mes setups de VM, bien sûr tout ce que je vais expliquer plus loin peut s’exécuter dans du Docker, du VMWare, en ligne, etc. …
Maintenant que je vies de vous présenter mes choix, nous allons pouvoir passer à l’installation.
Installation de GitLab & du runner GitLab
⚠️ Vous aurez besoin d’avoir installé VirtualBox et Vagrant (si vous utilisez d’autres outils je vous laisse adapter)
Préparation du projet Vagrant
Créez un répertoire pour votre projet, et dans ce répertoire créez un fichier Vagrantfile
avec le contenu suivant:
Vous remarquez que j’ai fixé les IPs de mes VM. Avant de démarrer, dans le fichier hosts de votre ordinateur, ajoutez une référence à votre instance GitLab, par exemple:
Remarque: je suis sous OSX et j’utilise pour ça un outil très pratique: GAS MASK
Maintenant, allez dans votre répertoire, et dans un terminal, tapez la commande vagrant up
qui va vous construire vos 2 VMs. Patientez un peu et vous devriez obtenir 2 VMs VirtualBox:
Paramétrez GitLab et votre projet
- allez sur votre nouvelle instance GitLab
- créez un user admin
- créez un user pour vous
- ajoutez votre clé ssh à votre profil (cf. adding your ssh key to gitlab)
- créez un nouveau projet, par exemple “hello-world-book”
Maintenant allez dans les settings CI/CD de votre projet:
Cliquez sur le bouton Expand de la rubrique Runners Settings:
Pour paramétrer le runner, vous allez avoir besoin de 2 informations:
- l’url de votre instance GitLab
- un token qui permettra au runner d’être reconnu par l’instance GitLab
Paramétrez votre runner
Toujours dans le répertoire de votre projet Vagrant, dans un terminal, tapez la commande vagrant ssh book-runner
( book-runner
est le nom que j’ai donné à ma VM runner dans le fichier Vagrantfile
) qui vous permet d’accéder en ssh à votre VM runner et suivez la procédure ci-dessous. Tout commence avec la commande gitlab-runner register
:
Retournez sur votre instance GitLab et rafraîchissez la page de settings de la partie CI/CD, vous allez pouvoir vérifier que votre runner est bien enregistré:
Paramétrez votre projet AsciiDoctor
⚠️ vous pouvez faire tout ce qui va suivre directement dans l’interface de GitLab, ou faites un
git clone
de votre projet, et vous ferez ungit push
à la fin.
Il va vous falloir des polices de caractère
Pour cela créez un répertoire /fonts
dans votre projet et copiez les polices dont vous avez besoin dans ce répertoire. En ce qui me concerne, j’ai choisi (vous adapterez):
- OpenSans pour tout ce qui est texte, explications, blabla, …
- SourceCodePro pour l’affichage du code source
- EmojiOne.ttf pour les emojis (ce n’est pas obligatoire, c’est juste mon addiction aux emojis qui est en cause)
- mplus1mn-regular-ascii-conums.ttf pour le support des callouts (http://www.methods.co.nz/asciidoc/chunked/ch20.html) dans AsciiDoctor
J’ai trouvé ces polices ici:
OpenSans: http://www.1001fonts.com/open-sans-font.html
SourceCodePro: http://www.1001fonts.com/source-code-pro-font.html
EmojiOne: https://github.com/GuangchuangYu/emojifont/blob/master/inst/emoji_fonts/EmojiOne.ttf
mplus1mn-regular-ascii-conums: https://github.com/asciidoctor/asciidoctor-pdf/blob/master/data/fonts/mplus1mn-regular-ascii-conums.ttf
Configurez votre projet
Vous allez devoir décrire dans un fichier yaml les éléments de mise en page de votre e-book, ce qui va avoir un impact pour la génération de votre pdf. Pour cela, créez à la racine de votre projet un fichier book.yml
, voici ci-dessous, celui que j’utilise. Il y a eu pas mal de tâtonnements et de recherches avant d’y arriver, donc commencez avec le mien et adaptez ensuite:
Préparez vos 1ères pages et la structure de votre e-book
J’ai décidé de faire une arborescence par chapitre, avec mon fichier descriptif de l’e-book index.adoc
à la racine du projet. Ce fichier permettra de définir le titre du projet, faire la 1ère page, avoir une table des matières, …
Et chaque répertoire correspondra à un chapitre, contenant dans mon cas le fichier asciiDoc du chapitre concerné:
Contenu de index.adoc
Je précise donc dans l’index de mon e-book que je vais utiliser coderay
pour la coloration syntaxique (j’ai installé la gem correspondante dans le runner, cf. le Vagrantfile
), que le titre de mon document est my document
, que je veux une table des matière ( :toc:
), et ensuite je précise le lien vers mes différents chapitres:
Contenu des chapitres
Voici ci dessous, mon 1er chapitre
- J’ajoute un titre principal:
== Chapitre 1: 1er contact
- J’ajoute une note de début de chapitre avec
NOTE
- Je veux mettre un saut de page après ma note, avec
<<<
- J’ajoute du code source que je commente
- …
Mon 2ème chapitre:
Voilà, maintenant que nous avons un peu de contenu, nous allons mettre en place la mécanique de génération du pdf.
Paramétrage de l’intégration continue pour générer le pdf
Nous allons décrire, là aussi dans un fichier yaml, toutes les commandes à envoyer au runner pour générer notre pdf.
Lorsque vous créez un fichier .gitlab-ci.yml
dans un projet GitLab, et que vous l’avez spécifié correctement dans les settings CI/CD de votre projet, vous activez ainsi le mode CI (intégration continue) de votre projet:
Contenu du fichier .gitlab-ci.yml
Je voudrais pouvoir générer manuellement une preview pdf lorsque je suis sur une feature branch (== la rédaction dun chapitre) (c’est ce que je décris dans la section pdf_preview
du fichier .gitlab-ci.yml
) et je voudrais que mon e-book pdf soit généré automatiquement lorsque je merge mon chapitre sur la branche principale master
(c’est ce que je décris dans la section pdf_publication
du fichier .gitlab-ci.yml
):
A partir de maintenant je vais pouvoir commencer à rédiger mon e-book et à le générer en pdf.
Utilisation (en images)
Commencez par créer un nouveau répertoire en lui donnant le nom de votre chapitre, faites de même avec la “Target Branch”, cela permettra de créer une merge request lorsque vous cliquerez sur “Create directory”:
Vous venez donc de créer une merge request, vous pouvez changer son titre, ajouter une description, …
… puis cliquez sur “Submit merge request”:
Maintenant vous êtes dans le tableau de bord de votre merge request. Cliquez sur le lien chapter_03 correspondant à votre nouvelle branche:
Cela vous permet de revenir à l’arborescence de votre projet, mais dans la branche chapter_03:
Ajoutez un nouveau répertoire chapter_03 puis créez un nouveau fichier dans ce répertoire:
Nommez ce fichier chapter_03.adoc
et saisissez du contenu dans ce fichier:
“Commitez” votre fichier, puis retournez à la racine du projet (mais toujours dans la branche chapter_03) et ajoutez la référence à votre chapitre dans le fichier index.adoc
:
“Commitez” votre code et retournez à votre merge request, les commits de code ont créé un pipeline dont vous voyez le numéro d’identifiant (sous forme de lien) dans le tableau de bord de votre merge request. Cliquez sur le lien:
… Et vous arrivez sur la description (simple)de votre pipeline. Cliquez sur la flèche noire de pdf_preview pour déclencher la génération du pdf par le runner:
… Ce qui vous amène sur un nouvel écran qui vous affiche la console de sortie du runner, et vous propose à droite un bouton “Browse”, cliquez sur ce bouton:
… Vous pouvez maintenant voir le fichier pdf généré:
Si vous cliquez sur le fichier, vous allez passer en mode aperçu, et vous pouvez noter que votre table des matières a été mise à jour:
Et vous pouvez admirer votre nouveau chapitre:
Si vous acceptez votre merge request, la branche chapter_03 sera mergée sur la branche master, et dans ce cas là, la génération du pdf par le runner sera déclenchée automatiquement (nous faisons de la “publication continue” 😉).
Maintenant, il ne me reste plus qu’à écrire mon livre. J’espère que cet article vous sera utile.
⚠️ Pour éteindre proprement vos VMs, toujours dans le répertoire, dans un terminal tapez la commande
vagrant halt
(et pour relancervagrant up
)