Aller au contenu principal

Développement

Vous voulez aider au développement de TiBillet? Merci! C'est grâce aux gens comme vous que l'open-source fonctionne 🙏

Premièrement, si vous n'avez pas une tâche précise en tête, allez voir les tickets ouverts sur les dépôts Github officiels.

C'est le moyen le plus simple de comprendre quels sont les problèmes à résoudre et quelles fonctionnalités sont demandées.

Les dépôts

Les dépôts épinglés ("Pinned") sur la page de l'organisation devraient suffire. Si vous avez des doutes sur les rôles respectifs de Fedow, LaBoutik ou Lespass, révisez les bases sur les trois moteurs de TiBillet.

TODO: lien doc vers les moteurs et leur rôle (une page dans présentation probablement)

Méthodes de travail

Quand on travaille avec des forges Git comme Github, il y a des façons d'aider qui rendent votre contribution plus facile à prendre en compte :

  • Si vous ne faites pas partie de l'organisation (avec les accès au dépôt), faites un fork (dédoublement) du dépôt qui vous intéresse, travaillez à partir de celui-ci et soumettez vous modifications par le biais d'une pull request (demande de fusion).
  • Si vous avez un ticket sur lequel vous souhaitez travailler, vérifiez s'il n'existe pas déjà. Si c'est le cas, rejoignez la discussion plutôt que de faire la même chose en parallèle!
  • Quand vous démarrez le travail sur un ticket, assignez-vous dessus pour informer les autres qu'un chantier est en cours.
  • Enfin, un point important: ne créez pas de demandes de fusion sans avoir fait tourner les tests ! Ça arrive aux meilleur⋅es d'entre nous. Idéalement, vous devriez les faire tourner avant chaque commit, avec l'aide d'un git hook (déclencheur automatique) par exemple.
Trouver de l'aide

Si vous avez des questions sur Git, Github, ou un aspect du développement, rejoignez-nous sur le serveur Discord ou Matrix. Nous ferons de notre mieux pour aider !

Outils et langages utilisés

TiBillet, c'est :

  • une suite d'applications Python,
  • développées avec l'aide du framework Django,
  • ses dépendances sont gérées avec Poetry,
  • le tout tournant dans des conteneurs Docker en production comme en développement.

Si vous ne vous sentez pas à l'aise avec la pile logicielle, la meilleure chose à faire est d'aller chercher des tutoriels. Avec un peu de chance on compilera notre propre liste de ressources ici un de ces jours 😅

Attention

En particulier, des connaissances de bases avec Git feront une différence. C'est assez facile de semer le chaos dans un dépôt quand on ne comprend pas comment le versionnage marche. Il y a des sécurités en place, mais vous pourriez avoir beaucoup plus de difficultés que nécessaire! Je dis ça par expérience 😑

Installation locale

Pour coder et tester votre code, vous allez avoir besoin d'une instance (à peu près) fonctionnelle de TiBillet sur votre ordinateur.

Vérifions que vous avez l'outillage requis sous la main. Vous avez besoin de :

  • Docker CLI et l'extension docker-compose,
  • git,
  • un compte Github avec une clé SSH enregistrée (pour un accès authentifié à la forge),
  • un IDE (environnement de développement). Des coupons pour PyCharm sot disponibles sur demande, mais un IDE généraliste comme VSCodium fonctionne assez bien - c'est ce que j'utilise 😉.

On va commencer en créant un dossier qui contiendra les différents dépôts requis à sa racine, dans votre dossier de travail par exemple. Ça ressemblera à :

tibillet-dev
├── Fedow
├── LaBoutik
├── Lespass
├── Test-Driven-Development
└── Traefik

Traefik

On va avoir besoin d'un proxy d'application (un outil qui va aider à rediriger le trafic des conteneurs vers des adresses locales). TiBillet fournit une configuration de base pour un conteneur Trafik + LetsEncrypt (certificats SSL), partons donc là-dessus :

tibillet-dev$
git clone git@github.com:TiBillet/Traefik-reverse-proxy.git Traefik

Pour le démarrer :

tibillet-dev$
cd Traefik
docker compose up -d

Consulter le navigateur à l'adresse https://localhost devrait vous donner un avertissement de sécurité sur les certificats auto-signés (pas un problème dans ce cas précis) et une 404 page not found. Parfait !

remarque

Rappelez-vous de compose up Traefik chaque fois que vous démarrez une session de travail sur TiBillet.

Génération des clés

TODO: à simplifier ? lourd et compliqué pour aucune raison valable

Pour générer les clés nécessaires à la configuration des moteurs, à l'heure actuelle, on pull l'image Docker de la version production de Fedow, puis on lance quelques commandes dans l'environnement de Poetry.

Pour chaque moteur, on aura besoin :

  • d'une ou deux clés Fernet (pour le champ FERNET_KEY et possiblement des mots de passe),
  • d'une clé secrète Django (pour le champ SECRET_KEY).

Vous pouvez générer 30 clés uniques de chaque type en lançant les commandes :

docker run --rm tibillet/fedow poetry run python3 -c "from cryptography.fernet import Fernet; print('\n'.join([Fernet.generate_key().decode('utf-8') for i in range(0,30)]))"
docker run --rm tibillet/fedow poetry run python3 -c "from django.core.management.utils import get_random_secret_key; print('\n'.join([get_random_secret_key() for i in range(0,30)]))"

La première commande prendra quelques minutes, vu qu'elle télécharge une image Docker. Gardez les clés quelque part, on s'en servira au moment de la mise en place des moteurs.

On aura également besoin d'une clé de test Stripe pour le champ STRIPE_KEY_TEST. Stripe est actuellement la solution de paiement qui se charge de la conversion cash en cashless. Une clé de test peut être obtenue en se créant un compte gratuit, puis and allant dans le Mode test -> Clé API de test. Alternativement, demandez à l'équipe.

Fedow, Lespass, LaBoutik

Démarrons en clonant les dépôts des différents moteurs :

tibillet-dev$
git clone git@github.com:TiBillet/Fedow.git
git clone git@github.com:TiBillet/Lespass.git
git clone git@github.com:TiBillet/LaBoutik.git

À partir de là, on a besoin d'écrire un peu de configuration. Ça sera plus simple à l'avenir, prenez patience 😋

Chaque moteur a besoin de son propre fichier .env, que vous pouvez baser sur les fichiers env_example qu'on vient de cloner.

Attention

Toute variable d'environnement, doit être trouvable dans le fichier .env. Pas de suppression de variable ! Elle peut par contre suivant les cas rester vide (nullable).

Environnement Fedow

tibillet-dev$
cp Fedow/env_example Fedow/.env
NomEnvironnement cibleNullableValeur par défautNotes
SECRET_KEYTousNonUne des clés secrètes Django générées précédemment
FERNET_KEYTousNonUne des clés Fernet générées précédemment
STRIPE_KEYProductionOuiClé API de votre compte Stripe
DOMAINTousNonfedow.tibillet.localhostÀ adapter à votre nom de domaine et sous-domaine en production
STRIPE_KEY_TESTDéveloppement, TestsOuiClé API de test de votre compte Stripe
STRIPE_TESTDéveloppement, TestsNon0Passer à 1 si STRIPE_KEY_TEST est rempli
STRIPE_ENDPOINT_SECRET_TESTDéveloppement, TestsOuiAucune idée
DEBUGDéveloppementNon0Passer à 1 pour le développement
TESTTestsNon0Passer à 1 pour les tests

Environnement Lespass

tibillet-dev$
cp Lespass/env_example Lespass/.env
NomEnvironnement cibleNullableValeur par défautNotes
SECRET_KEYTousNonUne des clés secrètes Django générées précédemment
FERNET_KEYTousNonUne des clés Fernet générées précédemment
STRIPE_KEYProductionOuiClé API de votre compte Stripe
DOMAINTousNontibillet.localhostÀ adapter à votre nom de domaine en production
SUBTousNonlespassSous-domaine de l'instance, à adapter en production
METATousNonagendaSous-domaine de l'agenda fédéré, à adapter en production
FEDOW_DOMAINTousNonfedow.tibillet.localhostDomaine et sous-domaine du moteur Fedow
PUBLICTousNonTiBillet Coop.Nom de l'instance principale
TIME_ZONETousNonEurope/ParisPlage horaire TZ de l'instance
ADMIN_EMAILTousNonEmail administrateur (pour le⋅a premier⋅e admin)
POSTGRES_DBTousNonlespassÀ changer en production si nécessaire
POSTGRES_USERTousNonlespass_postgresÀ changer en production
POSTGRES_PASSWORDTousNonMot de passe fort (une des clés Fernets par exemple)
EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORDTousOuiServeur d'email, requis pour confirmer des abonné⋅es par exemple
STRIPE_KEY_TESTDéveloppement, TestsOuiClé API de test de votre compte Stripe
STRIPE_TESTDéveloppement, TestsNon0Passer à 1 si STRIPE_KEY_TEST est rempli
DEBUGDéveloppementNon0Passer à 1 pour le développement
TESTTestsNon0Passer à 1 pour les tests

Environnement LaBoutik

tibillet-dev$
cp LaBoutik/env_example LaBoutik/.env
NomEnvironnement cibleNullableValeur par défautNotes
SECRET_KEYTousNonUne des clés secrètes Django générées précédemment
FERNET_KEYTousNonUne des clés Fernet générées précédemment
DOMAINTousNonlaboutik.tibillet.localhostÀ adapter à votre nom de domaine et sous-domaine en production
FEDOW_URLTousNonhttps://fedow.tibillet.localhost/URL du moteur Fedow
LESPASS_TENANT_URLTousNonhttps://lespass.tibillet.localhost/URL de l'instance Lespass
TIME_ZONETousNonEurope/ParisPlage horaire TZ de l'instance
ADMIN_EMAILTousNonEmail administrateur (pour le⋅a premier⋅e admin)
MAIN_ASSET_NAMETousNonLe nom de votre unité de valeur cashless (Piécette, CoeurDor… comme vous voulez)
POSTGRES_DBTousNonlaboutikÀ changer en production si nécessaire
POSTGRES_USERTousNonlaboutik_userÀ changer en production
POSTGRES_PASSWORDTousNonMot de passe fort (une des clés Fernets par exemple)
EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORDTousOuiServeur d'email, requis pour confirmer des abonné⋅es par exemple
BORG_PASSPHRASETousOuiMot de passe utilisé pour la sauvegarde des données
DEBUGDéveloppementNon0Passer à 1 pour le développement
TESTTestsNon0Passer à 1 pour les tests
DEMODéveloppement, TestsNon0Passer à 1 pour une simulation de terminal de caisse
SENTRY_DNSDéveloppement, TestsOuiSentry Debug pour le back-end
SENTRY_FRONT_DNS, SENTRY_FRONT_ASSETDéveloppement, TestsOuiSentry Debug pour le front-end
DEMO_TAGID_CM, DEMO_TAGID_CLIENT1, DEMO_TAGID_CLIENT2OuiAucune idée

La configuration devrait être maintenant complète pour les trois moteurs.

Mise en place des tests

Pour une raison… une raison, l'image Docker de dev est assemblée à partir des tests. L'installation est similaire au moteurs :

tibillet-dev$
git clone git@github.com:TiBillet/Test-Driven-Development.git
cp Test-Driven-Development/env_example Test-Driven-Development/.env

C'est fait ☺️ On peut maintenant conteneuriser l'application entière depuis le dossier des tests :

Test-Driven-Development$
docker compose up -d

Vous pouvez accéder en prime aux logs avec la commande :

Test-Driven-Development$
docker compose logs -f
Attention

Ce docker-compose.yml en particulier s'appuie sur la structure décrite au début de l'installation, donc sur la structure du dossier parent aux tests, appelé pour l'exemple tibillet-dev. Contre-intuitif, mais maintenant vous savez 😉

Démarrage des moteurs

La principale différence entre les conteneurs de dev et de prod, c'est qu'en dev la commande docker compose ne démarre pas les applications Django individuelles. C'est un niveau de contrôle fin qui est utile pour le développement, mais ça veut dire que vous avez besoin de les lancer manuellement.

On va les lancer de préférence dans l'ordre :

  1. Fedow
  2. Lespass
  3. LaBoutik (qui a besoin des deux autres pour fonctionner)

Les outils dont on a besoin sont dans les conteneurs, nommés d'après leur moteur : fedow_django, lespass_django et enfin laboutik_django. Pour rentrer dans un conteneur (exemple avec Fedow) :

# on démarre un environnement bash dans le conteneur fedow_django
docker exec -ti fedow_django bash

À partir de là, on a quelques options.

La première, c'est le script flush.sh. Il initialise les données de test et démarre Django dans la foulée. C'est cette commande qu'on va utiliser au premier démarrage de notre application :

fedow_django$
./flush.sh

On l'utilisera aussi quand on veut réinitialiser les données, par exemple avant de lancer les tests automatisés qui ont besoin de ces données prévisibles.

Pour le reste des manipulation dans le conteneur, on a besoin de rentrer dans l'environnement de Poetry, car on va lancer du Python.

Pour lancer l'environnement virtuel de Poetry depuis le conteneur :

fedow_django$
 # on démarre l'environnement virtuel qui prend en charge les dépendances python
poetry shell

Django se gère avec un script appelé manage.py. Deux commandes nous intéressent à l'heure actuelle :

  • rsp (alias de ./manage.py runserver 0.0.0.0:8000) démarre Django sans réinitialiser les données. Ça nous servira quand on veut garder des données entre deux démarrages. Généralement, si on a pas besoin de lancer les tests, c'est cette commande qu'on utilise plutôt que flush.

  • Optionnellement, si on a des bugs graphiques, on peut tenter ./manage.py collectstatic. Parfois, les ressources graphiques ne sont pas correctement copiées au premier démarrage, et ça peut régler le problème.

Plus qu'à démarrer les trois moteurs de TiBillet dans l'ordre indiqué précédemment : Fedow, Lespass, puis LaBoutik !

Création d'alias

La commande Docker devient vite répétitive. Pourquoi ne pas créer un alias, ou même une petite fonction bash pour gagner du temps et soulager son canal carpien par la même occasion ? Voilà ma fonction :

~/.bashrc
function dockex {
docker exec -ti $1 bash
}

Il suffit d'ouvrir un nouveau terminal pour que la fonction s'ajoute à l'environnement. Il y a même sans doule moyen d'ajouter poetry à tout ça si vous cherchez un peu !

Ça tourne ?

Si vous avez utilisé la configuration des sous-domaines par défaut, vous avez maintenant accès :

Si tout marche comme prévu, félicitations : vous êtes prêt⋅es à vous lancer 🔧

Sinon, venez nous en parler, on est là pour aider !

Pour conclure

N'oubliez pas de docker compose down à la fois dans les tests et dans Trafik quand vous avez fini votre session de travail. Votre ordinateur aussi a besoin de faire des pauses !

Si vous avez peur de ne pas vous en souvenir, enlevez l'option -d à compose up et la commande se lancera directement dans le terminal, pas en tâche de fond. C'est pas grave, vous aurez juste besoin de plus d'onglets 😋

Cycle de vie

Mises à jour

Pour rester à jour durant le développement, télécharger l'image la plus récente :

Test-Driven-Development$
docker compose pull
docker compose up -d # démarrer ou redémarrer les conteneurs

Tests

Vous pouvez lancer les tests Python de la même façon que pour un démarrage manuel. Commencez par réinitialiser les trois app Django pour obtenir les données testables, puis lancez cette commande depuis votre conteneur Django LaBoutik :

laboutik_django> poetry shell$
./manage.py test
TODO: docs des tests end-to-end (ils existent !)

Sauvegardes

Avant de vous attaquer à un changement majeur, sauvegardez toute donnée qui a de la valeur pour votre développement. Sur votre instance Fedow, par exemple, il suffit de sauvegarder le dossier database régulièrement. Les autres moteurs peuvent être sauvegardés par l'utilitaire Borgbackup, des tâches cron et des dump de bases de données. Plus sur ce sujet à l'avenir.

TODO: explications détaillées