Publication PDF d'un document asciidoc Ă  partir de Docker dans Gitea

Publié le 17/09/2020

Sur mon temps libre, j'Ă©cris (avec l'aide d'un ami) un petit livre sur Django.

Les sources de ce livre se trouvent sur mon instance de Gitea, couplée à une instance de Drone. Mais en l'état, si je veux faire une release du livre, je passe par une conversion PDF en utilisant la gemme asciidoctor-pdf (en pre-release) et ... bah grosso-modo, ça fonctionne surtout sur mes machines GNU/Linux, mais pas sur Windows.

Du coup, je cherche Ă  coupler les deux :

  1. Continuer Ă  Ă©crire en AsciiDoc
  2. Permettre (au push) d'avoir une génération automatique du PDF
  3. Envoyer ce résultat dans la catégorie "Releases" du dépôt Gitea.

Pour ça, il me faut une instance d'AsciiDoctor dans un container (puisque c'est le seul élément que Drone comprend), qui sera ensuite envoyé vers Gitea via un deuxième container instancié.

Mais avant de pourir mon dépôt avec des tests de béotien, je dois l'installer en local, vérifier que tout fonctionne, générer mon PDF et le cibler (quand il n'y a aucune erreur).

Installation de Docker/Podman sur Debian

DĂ©jĂ , plutĂ´t que de me concentrer sur Docker, autant directement installer Podman, puisqu'il permet plus de choses que Docker, tout en restant compatible (les devs conseillent d'ailleurs d'aller Ă©crire un alias docker=podman dans un fichier .bashrc ou .zshrc).

L'installation de Podman est décrite ici. Dans mon cas (Debian Testing/11):

echo 'deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_Testing/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_Testing/Release.key | sudo apt-key add -
sudo apt-get update
sudo apt-get -y install podman

sysctl -w kernel.unprivileged_userns_clone=1
echo 'kernel.unprivileged_userns_clone=1' > /etc/sysctl.d/userns.conf

Et on fait un petit essai en mode utilisateur:

fred@aerys:~/Sources/$ podman pull alpine
Trying to pull docker.io/library/alpine...
Getting image source signatures
Copying blob df20fa9351a1 done
Copying config a24bb40132 done
Writing manifest to image destination
Storing signatures
a24bb4013296f61e89ba57005a7b3e52274d8edd3ae2077d04395f806b63d83e

Récupération du container Docker-asciidoctor

On fait pareil que ci-dessus... Juste qu'on change l'image à charger, et qu'on suit un peu la documentation pour monter le bon répertoire:

cd Sources/gwift-book
podman run -it -v .:/documents/ asciidoctor/docker-asciidoctor

On arrive en mode interactif dans le container; les fichiers du répertoire sont directement disponibles. Reste à réutiliser mon Makefile, et à démarrer la commande make pdf depuis le container.

bash-5.0# make pdf
asciidoctor-pdf -a pdf-themesdir=resources/themes -a pdf-theme=gwift-theme source/main.adoc -t -r asciidoctor-diagram
asciidoctor: WARNING: part-2-deployment/centos+debian.adoc: line 283: callout list item index: expected 1, got 2
asciidoctor: WARNING: part-2-deployment/centos+debian.adoc: line 283: no callout found for <1>
asciidoctor: WARNING: part-2-deployment/centos+debian.adoc: line 284: callout list item index: expected 2, got 3
asciidoctor: ERROR: main.adoc: line 65: include file not found: /documents/source/gwift/key-points.adoc
asciidoctor: ERROR: main.adoc: line 71: include file not found: /documents/source/gwift/console.adoc
asciidoctor: ERROR: could not locate or load the pdf theme `gwift-theme' in resources/themes; reverting to default theme
Input file: source/main.adoc
  Time to read and parse source: 0.30130
  Time to convert document: 7.97493
  Total time (read, parse and convert): 8.27623

Intégration à Drone

Ce que je veux, c'est qu'au push sur le dépôt:

  1. Le container soit instancié
  2. La commande make pdf soit démarrée (Joie ! Tous les prérequis se trouvent dans l'image).
  3. Que si aucune erreur n'est constatée (dans l'exemple ci-dessus, il y en a trois), que le fichier soit transmis vers les releases Gitea du dépôt.

A priori, le seul plugin dont on aura besoin sera Gitea-release, quand une publication sera demandée.

La configuration est disponible sur la page de documentation, ci-dessus. Le fichier .drone-ci.yml devient celui-ci:

steps:
- name: gitea_release
  image: plugins/gitea-release
  settings:
    base_url: https://your.gitea.tld
    api_key:
      from_secret: gitea_token
    files: dist/*
  when:
    event: tag

Le pipeline final ressemble du coup Ă  ceci:

kind: pipeline
name: default

steps:
  - name: build
    image: asciidoctor/docker-asciidoctor
    commands:
      - make pdf
  - name: release
    image: plugins/gitea-release
    settings:
      api_key:
        from_secret: gitea_token
      base_url: https://sources.grimbox.be
      files: source/main.pdf
      title: gwift-book
    when:
      event: [tag]

Deux-trois remarques:

  1. Obligation de lui fournir un attribut title, sans quoi l'Ă©tape de construction se vautrait lamentablement
  2. Obligation de passer par un kind: pipeline, sans quoi ... voir ci-dessus :-) Mais si on déclare simplement un pipeline accompagnés d'étapes, on ne peut visiblement pas récupérer une clé à partir du répertoire des secrets.

Et finalement, il a fallu ajouter une section [attachments] dans le fichier app.ini de Gitea, pour autoriser l'envoi de fichiers PDF (ou, du moins, ayant le mimetype application/pdf):

...

[attachment]
; Whether attachments are enabled. Defaults to `true`
ENABLED = true

; One or more allowed types, e.g. "image/jpeg|image/png". Use "*/*" for all types.
ALLOWED_TYPES = image/jpeg|image/png|application/zip|application/gzip|application/pdf

...

Et le résultat est ici: