Publier une version¶
Le CLI est distribué depuis un index public que nous hébergeons, conforme à la PEP 503. Rien qu'un site statique : ni serveur, ni base, ni authentification.
https://pkg.prod.aim.dyneco.io
Installer, côté utilisateur¶
Une seule URL, rien à configurer. Les dépendances se résolvent depuis PyPI.
La commande installée s'appelle aim dans tous les cas.
Pourquoi dyneco-aim et pas aim ?
aim est déjà pris sur PyPI par un outil de suivi d'expériences ML. Deux index
proposant le même nom feraient silencieusement gagner la version la plus haute
— la sienne, en 3.x, contre la nôtre en 0.x. C'est le schéma exact d'une
dependency confusion.
Le nom de distribution et le nom de la commande sont deux décisions séparées : seul le premier change. Personne ne tape jamais le nom de distribution après l'installation.
Si tu utilises aussi l'outil ML, installe avec un suffixe :
pipx install dyneco-aim --suffix=-ctx donne la commande aim-ctx.
Publier, côté mainteneur¶
- Incrémente
versiondanspyproject.toml. C'est la seule déclaration : le code lit la version depuis les métadonnées du paquet installé. - Commite et pousse.
- Lance le pipeline
publier-paquetdans Azure DevOps.
Le déclenchement est manuel, jamais automatique sur commit : publier une version est une décision, et une version publiée est immuable.
Ce que fait le pipeline¶
flowchart LR
A[Tests] --> B[Construire la roue]
B --> C[Récupérer l'index publié]
C --> D[Fusionner]
D --> E[Déployer]
E --> F[Installer et vérifier]
L'étape de fusion est celle qui compte. Un déploiement statique remplace
l'intégralité du site : régénérer l'index depuis le seul dist/ local effacerait
toutes les versions antérieures et casserait les installations épinglées. Le script
lit donc l'index en ligne, rapatrie les roues existantes, et republie l'ensemble.
Il refuse par ailleurs de republier une version existante sous une empreinte différente — un fichier dont le contenu change sous le même nom est précisément ce qu'un index ne doit jamais faire.
La dernière étape installe réellement le paquet depuis l'index publié et vérifie
que aim version renvoie la version attendue. Sans elle, un index cassé passerait
pour un succès.
Répétition générale¶
Le pipeline accepte un paramètre « Construire et vérifier sans publier » : il va jusqu'à la construction de l'index et affiche ce qui aurait été déployé.
En local¶
uv build --wheel
uv run python scripts/build_index.py \
--dist dist --out site-pkg \
--base-url https://pkg.prod.aim.dyneco.io
python3 -m http.server 8765 --directory site-pkg
Ce que le pipeline ne fait pas¶
Il ne pose pas d'étiquette git. À faire à la main si tu veux retrouver le code d'une version publiée :
Il ne publie pas sur PyPI public. Cela n'aura de sens que le jour où le serveur
sera auto-hébergeable par un tiers : aujourd'hui, un pip install depuis PyPI
donnerait une commande sans plateforme à contacter.
Il ne publie que la roue. Le paquet est du Python pur ; l'archive source n'apporterait rien et exposerait publiquement l'infrastructure et les scripts de déploiement.
Limite assumée¶
L'index publié fait office de stockage des versions antérieures. Si le site était effacé, l'historique des roues le serait aussi — elles restent reconstructibles depuis les étiquettes git, mais pas au bit près.
Un compte de stockage servant de source de vérité corrigerait cela ; ce n'est pas justifié pour un paquet de 80 kio.
Coût¶
0 €. Le palier gratuit de Static Web Apps inclut 100 Go de bande passante par mois, les domaines personnalisés et les certificats. Le pipeline consomme le quota gratuit d'agents hébergés (1 800 minutes par mois) ; une publication en prend environ trois.