Tout d’abord, aussi bien au niveau des dépôts que des paquets YunoHost, il faut savoir qu’il y a trois composants (unstable
, testing
et stable
) :
-
unstable
correspondent à la dernière version du dépôt git sur la brancheunstable
, et sont reconstruits de façon automatisée toutes les nuits s’il y a eu une modification sur la cette branche. -
testing
permet de mettre en place une nouvelle version d’un paquet qui sera ensuite testée. -
stable
contient la version de production.
Le terme composant vient de la façon dont les dépôts sont configurés. Afin de se rapprocher de la façon dont les dépôts sont structurés dans Debian, l’entrée à ajouter dans les sources APT se construit ainsi :
deb http://repo.yunohost.org/debian/ nom_de_code composant [composant...]
Avec nom_de_code la « version » de Debian installée sur l’hôte (ex. : jessie
). Pour les composants, il est nécessaire de spécifier au moins stable
, puis les différents intermédiaires. Par exemple, sur un système sous Debian Jessie, voici les différentes possibilités :
# composant stable
deb http://repo.yunohost.org/debian/ jessie stable
# composant testing
deb http://repo.yunohost.org/debian/ jessie stable testing
# composant unstable
deb http://repo.yunohost.org/debian/ jessie stable testing unstable
Le but du workflow est d’éviter toute intervention manuelle (lancement d’un script, etc.) sur le serveur, et de maîtriser la gestion des paquets via GitHub uniquement.
Ainsi, les dépôts de chaque paquet yunohost possèdent trois branches correspondant aux trois composants (unstable
, testing
et stable
). Le serveur de build construit et déploie automatiquement les paquets sources et binaires Debian correspondant à l’état de ces trois branches sur GitHub.
Aucun commit dans la branche unstable ne modifie le fichier debian/changelog
car celui-ci est modifié automatiquement lors du build quotidien, avec une version correspondant à la date/heure de construction.
Tout commit modifiant fonctionnellement les paquets doit se faire d’abord dans cette branche unstable
.
TODO ajouter un pre-commit hook pour éviter les erreurs ?
Aucun commit fonctionnel n’est effectué directement dans ces branches. On ne fait que des merges (merge de unstable
dans testing
et merge de testing
dans stable
).
Les seules modifications spécifiques à ces dépôts sont les changements de versions (modification de debian/changelog
, puis tag).
Des outils à destination des mainteneurs de paquets sont disponibles sur le dépôt yunohost-debhelper
git clone https://github.com/YunoHost/yunohost-debhelper
yunohost-debhelper/setup_git_alias.sh
Ceci va configurer un nouvel alias git nommé yunobump
, global (stocké dans ~/.gitconfig
et donc accessible depuis n’importe quel dépôt git local).
- Rendez-vous dans le repo du paquet que vous voulez builder
- Assurez-vous que la branche
unstable
contient toutes les modifications que vous voulez intégrer dans votre build - Récupérez le numéro de version actuel :
head debian/changelog
- Rendez-vous sur la branche
testing
oustable
- Mergez ou cherry-pickez les commits que vous voulez intégrer à la version depuis la branche
unstable
- Modifiez le
debian/changelog
en intégrant les messages de commits correspondant aux modifications que vous avez intégrées (ou utilisezgit-dch
pour le faire automatiquement) - Taguez la branche actuelle (
testing
oustable
) du numéro de version juste supérieur à l’actuel - Pushez vos modifications ainsi que vos tags sur le repo GitHub
- Retournez sur la branche
unstable
- Mergez le changelog mis à jour précédemment
- Pushez la branche
unstable
# You Only Clone Once
$ git clone [email protected]:YunoHost/yunohost.git
$ cd yunohost
# Be sure to be up-to-date, and don't forget to get the tags !
$ git fetch --tags
# Checkout your branch : stable or testing
$ git checkout testing
# Do your 'functional' modifications: either merge unstable in testing, or merge testing in stable
$ git pull origin unstable
# Or just
$ git merge unstable
# What is the current version number in test ?
$ dpkg-parsechangelog | grep "^Version" | cut -d ' ' -f 2
# Or just
$ head debian/changelog
# Update changelog and do a proper tag (explained below)
$ git yunobump x.y.z-p
# Push the branch state AND the tags to the remote repository
$ git push origin --tags testing:testing
# Merge changelog modifications to the `unstable` branch
$ git checkout unstable
$ git merge testing
$ git push origin unstable
TODO politique sur les formats de tag, actuellement $branch/$version pour autoriser la même version dans deux branches différentes. Est-ce vraiment souhaitable ?
TODO normalement à chaque push sur test ou stable, le dernier commit est un commit de changelog et il est tagué proprement. On doit pouvoir implémenter un hook git de pre-push qui empêche de pousser des trucs à moitié faits (une erreur dans git yunobump, un git tag -d, un commit à la main...)
Il peut arriver, de façon exceptionnelle, qu’on ait besoin de faire un hotfix (de sécurité par exemple) sur les paquets en stable
ou en test
, pour lequel le merge de la branche daily n’est pas acceptable (car trop de nouvelles fonctionnalités en développement sur daily).
Cette situation doit rester exceptionnelle
Pour faire un hotfix, il faut donc travailler sur la branche stable
directement. Une fois la correction effectuée et commitée, il faut immédiatement créer la release stable avec l'outil yunobump (Voir les sections XX et "Numéros de version").
Ensuite, il faut appliquer ce hotfix aux branches testing
et unstable
. Il est fortement conseillé de l'appliquer immédiatement après avoir créer la release stable.
Pour cela, passer sur la branche testing
et merger la branche stable
; Un "commit de merge" doit etre réalisé. L'historique de la branche testing
doit donc ressembler à :
456def Merge branch 'stable' into testing
123abc Hotfix commit message.
Puis passer dans la branche unstable
et merger la branche testing
. Un nouveau commit de merge est réalisé, l'historique de la branche unstable ressemble donc à :
789ghi Merge branch 'testing' into unstable
456def Merge branch 'stable' into testing
123abc Hotfix commit message.
TODO dev un helper 'git yunohotfix...' qui commit dans stable et cherry-pick tout de suite dans daily ? ou l’inverse ?
Pour l'instant, on passe par une release via GitHub pour déclencher le build du paquet.
Aller sur https://github.com/YunoHost/{moulinette, yunohost, yunohost-admin, ssowat}/releases/new
1/ Choisir la branche cible en premier (testing ou stable). Ex: "target: Testing"
2/ Choisir le tag concerné, généralement le dernier Ex: "debian/2.4.1"
3/ Release title: "v2.4.1" ("v" + le numéro de version)
4/ Commentaire
Reprendre le changelog depuis debian/changelog
. Remercier les contributeurs/traducteurs
( Pour voir le dernier commit : git show HEAD
)
Pour les paquets « non-YunoHost » (par exemple rspamd
) le paquet ne passe pas par le composant unstable
, mais uniquement testing
et stable
une fois les tests effectués sur ce paquet.
La version d’un paquet YunoHost est sous la forme : X.x.y[.z]
.
La première partie, X
, correspond à la version majeure de YunoHost, actuellement 2.
La deuxième partie, x
, s’incrémente lors d’un changement fonctionnel important : ajout d’une nouvelle fonctionnalité, modification d’une façon de fonctionner... Les chiffres pairs correspondent à une version stable
(ex. : 2.4.x), tandis que les chiffres impairs à une version testing
.
La troisième partie, y
, s’incrémente quasi-arbitrairement, lors d’un lot de bugfixes ou d’un changement fonctionnel mineur. On peut trouver par exemple des paquets en 2.1.3 ou 2.1.5.
Enfin, une quatrième partie, z
, est réservée dans les cas exceptionnels de bugfix. Dans ce cas, on veut faire passer un changement unique, généralement directement dans la branche stable
(voir la partie s’y rapportant). Cela donne, par exemple, 2.1.3.1.
Note : les paquets de YunoHost étant natif pour Debian (dans le sens où nous gérons directement le packaging Debian avec le paquet), il n’y a pas de révision Debian dans le numéro de version (caractérisé par -debian_revision). Pour plus de détails sur les numéros de version, voir le Debian Policy Manual.
Les principaux logiciels utilisés pour la gestion et construction des paquets sont les suivants :
- reprepro : gérer localement un dépôt de paquets Debian
- rebuildd : reconstruire des paquets Debian, avec un historique, une interface Web,...
Pour plus de flexibilité, rebuildd délègue la construction du paquet à pbuilder. Ce dernier permet notamment d’avoir différents environnements, architectures...
Enfin, pour gérer au mieux ces outils, deux scripts ont été développés, stockés dans /usr/local/bin
:
daily_build
: construire un ou tous les paquets YunoHost dans le composant unstable uniquementbuild_deb
: construire un paquet Debian depuis un répertoire, dans un composant et un nom de code donné
À noter également que d’autres scripts ont été faits pour rebuildd et reprepro, afin notamment de faire le pont entre les deux. Ils se trouvent dans /usr/local/bin/{rebuildd,reprepro}
.
Tout est déclenché par reprepro, configuré (voir /var/www/repo/debian/conf/distribution
) pour exécuter le script /usr/local/bin/repo/process-include
chaque fois qu’un paquet est inclus dans un dépôt (plus précisément, qu’un fichier .changes
est inclus, via la commande reprepro include
). Ce dernier va vérifier un certain nombre de choses, dont le fait qu’il s’agit bien d’un paquet source, puis va ajouter une nouvelle tâche pour rebuildd, afin que le paquet soit créé.
Lorsque la tâche est reçue par rebuildd, si le paquet correspond bien à une distribution et architecture supportée (voir /etc/rebuildd/rebuilddrc
), trois scripts seront exécutés les uns après les autres, si aucune erreur n’intervient :
/usr/local/bin/rebuildd/get-sources
: récupération des sources depuis le dépôt local pour le paquet et la version demandée/usr/local/bin/rebuildd/build-binaries
: construction du paquet via pbuilder et l’environnement correspondant à la distribution et l’architecture/usr/local/bin/rebuildd/upload-binaries
: ajout du paquet binaire précédemment créé à reprepro dans le bon dépôt et composant
Un cron défini pour l’utilisateur pbuilder
se lance tous les jours à 01:00, qui exécute le script daily_build
. Pour chaque paquet (ssowat
, moulinette
, yunohost
et yunohost-admin
), le script met d’abord à jour le dépôt git correspondant depuis la branche unstable. Si de nouveaux commits ont été faits depuis la veille, une nouvelle version du paquet sera construite.
Plus précisément, une nouvelle entrée dans le changelog sera d’abord ajoutée, avec une version sous la forme YYYY.MM.DD+HHMM. Un paquet source sera ensuite construit, avant de passer le relais au script /usr/local/bin/repo/include-changes
. Ce dernier va exécuter les bonnes commandes pour reprepro afin d’inclure dans le bon dépôt et composant le paquet source fraîchement créé.
Il est possible de relancer manuellement le build d’un paquet :
$ daily_build -p <nom_du_paquet>
Il est aussi possible d’utiliser une branche autre que unstable :
$ daily_build -p <nom_du_paquet> -b <branch>
*Notez bien que ce script permet uniquement de construire des paquets dans le composant unstable ! *
Ce script permet de construire un paquet Debian quelconque, et de l’inclure dans un dépôt donné. Il est notamment utilisé pour construire les paquets rspamd
et rmilter
. Une fois le paquet source récupéré et extrait, il suffit de lancer la commande suivante :
$ build_deb -c distribution -d <composant> /chemin/du/paquet/source
$ reprepro -V -b /var/www/repo/debian -C <composant> list <nom_de_code>
$ reprepro -V -b /var/www/repo/debian -C <composant> remove <nom_de_code> nom_du_paquet
Pour la gestion des paquets venant du dépôt backport, il est possible de les intégrer rapidement dans le dépôt de yunohost.
Pour ce faire il faut ajouter le nom du paquet dans le fichier /var/www/repo/debian/conf/<nom_de_code>-<composant>.list
, puis exécuter la commande :
$ reprepro -V -b /var/www/repo/debian -C <composant> update <nom_de_code>