Contribution

Les contributions sont bienvenues !

Le dépôt de code est hébergé sur gitlab.com/yaal/canaille.

Discuter

If you want to implement a feature or a bugfix, please start by discussing it with us on the bugtracker or the matrix room. If the bug is confirmed or the features fits in the roadmap, you can then open a merge request on GitLab. The test suite must pass with full coverage for your contribution to be accepted.

Environnement de développement

Vous pouvez lancer le serveur de développement localement ou bien avec Docker.

Après avoir lancé le serveur de développement, vous avec accès à plusieurs services :

Le serveur Canaille embarque quelques utilisateurs par défaut :

  • Un utilisateur de base dont l’identifiant et le mot de passe sont user ;

  • Un modérateur dont l’identifiant et le mot de passe sont moderator ;

  • Un administrateur dont l’identifiant et le mot de passe sont admin ;

  • Un nouvel utilisateur dont l’identifiant est james. Cet utilisateur n’a pas de mot de passe défini, et sa première tentative de connexion résultera en l’envoi d’un email d’initialisation de mot de pass (si un serveur SMTP est configuré).

Backends

Canaille peut se connecter à plusieurs types de bases de données :

  • une base de données très légère memory à fins de tests

  • une base de données SQL, utilsant SQLAlchemy

  • une base de données LDAP prête à l’emploi

Environnement local

Le seul outil requis pour développer localement est uv. Assurez-vous d’avoir uv installé sur votre système afin de pouvoir développer Canaille.

Initialisez votre environnement de développement avec :

  • uv sync --all-groups --all-extras si vous souhaitez avoir tout à portée de main. Notez que cela requerra peut-être de compiler certaines dépendances Python, qui nécessiterons l’installation de certaines bibliothèques sur votre système ;

  • uv sync --extra front --extra oidc pour obtenir un environnement de développement minimal. Cela vous permettra d’exécuter les tests avec uv pytest --backend memory.

  • uv sync --extra front --extra oidc --extra sqlite pour obtenir un environnement de développement minimal avec le support des bases de données SQLite. Cela vous permettra d’exécuter les tests avec uv pytest --backend sql.

  • uv sync --extra front --extra oidc --extra ldap pour obtenir un environnement de développement minimal avec le support pour les bases de données LDAP. Cela vous permettra d’exécuter les tests avec uv pytest --backend ldap. Certaines dépendances de Canaille auront peut-être besoin d’être compilées, vous voudrez probablement vérifier que GCC et cargo sont installés sur votre système.

SQL

Avec la base de données SQL, le serveur de développement chargera et enregistrera les données dans un fichier sqlite local.

Lancer l’instance de développement avec la base de données SQL
$ uv run devserver

En-mémoire

Avec la base de données en mémoire, toutes les données sont perdues lorsque Canaille s’arrête.

Lancer l’instance de développement avec la base de données en mémoire
$ uv run devserver --backend memory

LDAP

Avec LDAP, toutes les données sont perdues lorsque Canaille s’arrête.

Lancer l’instance de développement avec le support de LDAP
$ uv run devserver --backend ldap

Note

Si vous souhaitez exécuter l’instance de développement localement avec le support pour LDAP, vous devez avoir OpenLDAP installé sur votre système. OpenLDAP est généralement fourni via les paquets nommés slapd ou openldap.

Avertissement

On Debian or Ubuntu systems, the OpenLDAP slapd binary usage might be restricted by apparmor, and thus makes the tests and the development server fail. This can be mitigated by removing apparmor restrictions on slapd.

$ sudo apt install --yes apparmor-utils
$ sudo aa-complain /usr/sbin/slapd

Environnement Docker

SQL

Avec la base de données SQL, le serveur de développement chargera et enregistrera les données dans un fichier sqlite local.

Lancer l’instance de développement avec la base de données SQL
$ cd dev
$ docker compose up

En-mémoire

Avec la base de données en mémoire, toutes les données sont perdues lorsque Canaille s’arrête.

Lancer l’instance de développement avec la base de données en mémoire
$ cd dev
$ docker compose --file docker-compose-memory.yml up

LDAP

Avec LDAP, toutes les données sont perdues lorsque Canaille s’arrête.

Lancer l’instance de développement avec le support de LDAP
$ cd dev
$ docker compose --file docker-compose-ldap.yml up

Remplissage de la base de données

La base de donnée de développement est remplie avec des utilisateurs et des groupes générés aléatoirement. Si vous avez besoin de plus, vous pouvez générer des utilisateurs et des groupes avec la commande populate :

# If using docker:
$ docker compose exec canaille env CANAILLE__DATABASE=<backend> CANAILLE_CONFIG=conf/canaille.toml uv run canaille populate --nb 100 users  # or docker-compose

# If running in local environment
$ env CANAILLE__DATABASE=<backend> CANAILLE_CONFIG=conf/canaille.toml uv run canaille populate  --nb 100 users

Adaptez pour utiliser le fichier de configuration ldap ou sql. Notez que cela ne fonctionnera pas avec la base de données en mémoire.

Tests unitaires

Pour exécuter les tests, vous pouvez simplement lancer la commande `uv run pytest`et/ou `uv run tox`pour tester tous les environnements Python supportés. Tout doit être au vert avant que les contributions soient fusionnées.

To test a specific backend you can pass --backend memory, --backend sql or --backend ldap to pytest and tox. SQL backend supports variants: --backend sql:postgresql or --backend sql:sqlite. --backend sql tests both.

La couverture de code est de 100%, les contributions ne seront acceptées que si leur code est entièrement couvert. Vous pouvez vérifier la couverture avec ``uv run pytest –cov –cov-report=html``ou ``uv run tox -e coverage – –cov-report=html`. Vous pouvez ensuite consulter le rapport de couverture HTML dans le dossier htmlcov nouvellement créé.

Integration tests

Integration tests verify that Canaille works correctly when built and deployed as a wheel package, a PyInstaller binary, or a Docker image. To run all build modes:

$ uv run pytest integration/

To test a specific build mode, use --build=dev (source), --build=package (wheel), --build=pyinstaller (binary), or --build=docker (container). You can also test a pre-built artifact: --build=pyinstaller:/path/to/binary or --build=docker:image:tag.

Style de code

We use ruff along with other tools to format our code. Please run uv run tox -e style on your patches before submitting them. In order to perform a style check and correction at each commit you can use our prek configuration with uv run prek install.

Coding agents

The use of coding agents in contributions is allowed as long as all the other points of this document are respected, and it does not impact the software quality. Contribution authors MUST understand and be able to explain ANY line of code that has been produced, like the code they write themselves. The use of an agent must be indicated in the PR.

Interface utilisateur

L’interface utilisateur est construite avec Fomantic UI. Les parties dynamiques utilisent HTMX.

  • L’utilisation de Javascript dans l’interface est tolérée, mais l’ensemble de l’application DOIT pouvoir être utilisé par des navigateurs sans support Javascript, et sans perte de fonctionnalité.

  • À cause de Fomantic UI, Canaille a une dépendance vers jQuery, cependant les nouvelles contributions ne devraient pas utiliser jQuery. Lisez le `ticket à ce sujet<https://gitlab.com/yaal/canaille/-/issues/130>`_.

Documentation

La documentation est générée lors de l’exécution des tests :

$ tox -e doc

Vous pouvez aussi exécuter sphinx à la main, cela devrait être plus rapide puisque cela évite l’initialisation des environnements tox :

$ sphinx-build doc build/sphinx/html/en

La documentation générée se situe à build/sphinx/html/en.

Note

La documentation génère dynamiquement des captures d’écran de Canaille en utilisiant sphinxcontrib-screenshot, qui utilise Playwright. Il est nécessaire d’initialiser Playwright avec la commande suivante :

$ uv run playwright install firefox

Traduction du code

Les traductions s’effectuent sur Weblate.

Les commandes suivantes sont présentées à titre de documentation, seule l’extraction des messages est utile aux contributeurs. Toutes les autres étapes sont effectuées automatiquement par Weblate.

Extraction des messages

Après avoir édité des chaînes de caractères traductibles, vous pouvez extraire les messages avec :

$ pybabel extract --mapping-file pyproject.toml --copyright-holder="Yaal Coop" --output-file canaille/translations/messages.pot canaille

Ajout de langues

Vous pouvez ajouter une nouvelle langue manuellement avec la commande suivante, cependant cela ne devrait pas être nécessaire puisque Weblate s’en occupe automatiquement :

$ pybabel init --input-file canaille/translations/messages.pot --output-dir canaille/translations --locale <LANG>

Mise à jour des catalogues

Vous pouvez mettre à jour les catalogues avec la commande suivante, cependant cela ne devrait pas être nécessaire puisque Weblate met à jour automatiquement les catalogues lorsqu’il détecte de nouvelles chaînes de caractères ou lorsque quelqu’un traduit des chaînes de caractères existantes. Weblate pousse ses modifications toutes les 24 heures.

$ pybabel update --input-file canaille/translations/messages.pot --output-dir canaille/translations --ignore-obsolete --no-fuzzy-matching --update-header-comment

Compilation des catalogues

Vous pouvez compiler les catalogues avec la commande suivante, cependant cela ne devrait pas être nécessaire puisque les catalogues sont automatiquement compilés avant le lancement des tests unitaires, avant le lancement de l’instance de démonstration et avant la compilation du paquet Python de Canaille :

$ pybabel compile --directory canaille/translations --statistics

Traduction de la documentation

Les traductions s’effectuent sur Weblate.

Les commandes suivantes sont montrées à titre de documentation, seules l’extraction de message et l’ajout de langues de traduction sont utiles aux contributeurs.

Extraction des messages

Après avoir édité des chaînes de caractères traductibles, vous pouvez extraire les messages avec :

$ sphinx-build --builder gettext doc doc/locales

Ajout de langues

Vous pouvez ajouter une nouvelle langue manuellement avec la commande suivante, cependant cela ne devrait pas être nécessaire puisque Weblate s’en occupe automatiquement :

$ sphinx-intl update --pot-dir doc/locales --locale-dir doc/locales -l fr

Construire la documentation dans une autre langue

$ sphinx-build --builder html --define language=fr doc build/sphinx/html/fr

Build packages

The CI checks that the build processes are functional with each commit.

Paquet Python

L’étape de création du paquet Python est gérée par uv :

$ uv build

Fichier exécutable

Pour construire un exécutable unique de Canaille, vous pouvez utiliser pyinstaller en installant le groupe de dépendances release :

$ uv sync --group release --all-extras --no-dev
$ uv run pyinstaller canaille.spec

Docker

$ docker build -t canaille .

Publish packages

Paquet Python

$ uv publish --publish-url https://test.pypi.org/legacy/
$ uv publish

Docker

You need to authenticate once on DockerHub.

$ docker login --username <hub docker login>

Then you can push the images.

$ export CANAILLE_VERSION=$(uv run python -c "from importlib.metadata import version; print(version('canaille'))")
$ docker tag canaille:latest "yaalcoop/canaille:latest"
$ docker tag canaille:latest "yaalcoop/canaille:${CANAILLE_VERSION}"
$ docker push yaalcoop/canaille:latest
$ docker push yaalcoop/canaille:${CANAILLE_VERSION}

Publier une nouvelle version

The package building process is took care of by the CI when a git tag is pushed. It also publishes the different packages on the different stores.

  1. Vérifiez que les dépendances sont à jour avec uv sync --all-extras --all-groups --upgrade et mettez à jour chaque dépendance dans un commit séparé ;

  2. Check that tests are still green for every supported python version, and that coverage is still at 100%, by running uv run tox. Push and check that the CI is green;

  3. Vérifiez que les development/changelog:notes de versioin sont correctement renseignées ;

  4. Incrémentez le numéro de version dans pyproject.toml ;

  5. Commitez avec git commit ;

  6. Tag the commit with git tag --annotate XX.YY.ZZ --message "Release version XX.YY.ZZ";

  7. Poussez le commit de publication avec la nouvelle étiquette avec git push --tags.