From 5dac7f1ecad6d561da5c889ed6e4648e902739aa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7oise=20Conil?= <francoise.conil@insa-lyon.fr>
Date: Fri, 27 Oct 2023 18:48:49 +0200
Subject: [PATCH] =?UTF-8?q?Compl=C3=A9ter=20les=20informations=20de=20publ?=
 =?UTF-8?q?ication=20(PyPi,=20Flit)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 versionner-un-code-python.qmd | 159 +++++++++++++++++++++++++++++-----
 1 file changed, 139 insertions(+), 20 deletions(-)

diff --git a/versionner-un-code-python.qmd b/versionner-un-code-python.qmd
index 7042a24..ed614ae 100644
--- a/versionner-un-code-python.qmd
+++ b/versionner-un-code-python.qmd
@@ -569,7 +569,7 @@ de [PyPI](https://pypi.org/)
 
 [PyPI](https://pypi.org/) est le dépôt officiel pour les packages Python
 
-## Documentation
+## PyPI : Documentation et tests
 
 Voici quelques sources d'information sur [PyPI](https://pypi.org/)
 
@@ -578,7 +578,17 @@ Voici quelques sources d'information sur [PyPI](https://pypi.org/)
 - [documentation admin/dev](https://warehouse.pypa.io/)
 - [Python Packaging User Guide](https://packaging.python.org/)
 
-## Authentification
+::: {.callout-warning title="LIMITATIONS"}
+Il y a des limitations sur la taille des fichiers uploadés (100 MiB) et sur la
+taille totale du projet (10 GiB) ^[On peut demander une augmentation de la
+[taille des fichiers](https://pypi.org/help/#file-size-limit) ou de la [taille
+totale du projet](https://test.pypi.org/help/#project-size-limit)]. 
+:::
+
+`PyPI` dispose d'une infrastructure sur laquelle on peut tester l'upload de ses
+packages : [TestPyPI](https://test.pypi.org/)
+
+## PyPI : Authentification
 
 Afin de sécuriser le dépôt face aux packages malveillants,
 [PyPI](https://pypi.org/) a mis en place l'authentification à 2 facteurs (2FA)
@@ -600,10 +610,73 @@ Voir la documentation sur l'utilisation d'un **périphérique de sécurité** ^[
 utfkey](https://pypi.org/help/#utfkey)] ou d'une **application d'authentification**
 ^[[Aide TOTP](https://pypi.org/help/#totp)]
 
-## Test
+## PyPI : Activation authentification 2FA
 
-`PyPI` dispose d'une infrastructure sur laquelle on peut tester l'upload de ses
-packages : [TestPyPI](https://test.pypi.org/]
+![](images/pypi-2fa-activation.png){height="550"}
+
+::: aside
+Activation de l'authentification 2FA avec une application d'authentification
+TOTP (FreeOTP)
+:::
+
+## PyPI : Jeton d'API
+
+Il est fortement recommandé de s'authentifier avec un Jeton d'API ^[[Jeton
+d'API](https://pypi.org/help/#apitoken) / API token] pour la publication d'un
+package sur `PyPI`.
+
+On peut définir un **jeton global** pour tous les projets de son compte PyPI
+(`Paramètres du compte`) ou des jetons **dont la portée est limitée à un
+projet** (`Paramètres` du projet).
+
+On peut alors configurer l'utilisation d'un jeton dans le fichier `.pypirc`
+utilisé par plusieurs outils ^[Outil de publication compte
+[twine](https://twine.readthedocs.io/) ou backend comme
+[Flit](https://flit.pypa.io/)] (voir la partie **backend**).
+
+```{.ini title=".pypirc"}
+[distutils]
+index-servers = 
+   pypi
+   testpypi
+   test_ntt
+
+[test_ntt]
+repository = https://test.pypi.org/legacy/
+username = __token__
+```
+
+## PyPI : Trusted Publisher
+
+La notion de [Trusted Publisher](https://docs.pypi.org/trusted-publishers/)
+repose sur `OpenID Connect` pour permettre de connecter un "environnement
+automatisé" de type CI ^[Continuous Integration] à `PyPI`. 
+
+:::: {.columns}
+
+::: {.column width="60%"}
+La documentation et l'interface semblent essentiellement orientées [GitHub
+Action](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
+^[[Adding a Trusted Publisher to an Existing PyPI Project](https://docs.pypi.org/trusted-publishers/adding-a-publisher/)]
+
+::: {.callout-warning}
+Je n'ai pas testé cette fonctionnalité.
+
+Lire attentivement la documentation :
+
+- [Security model and considerations](https://docs.pypi.org/trusted-publishers/security-model/)
+- [Troubleshooting](https://docs.pypi.org/trusted-publishers/troubleshooting/)
+
+car pousser automatiquement des versions pose un certain nombre de questions.
+:::
+
+:::
+
+::: {.column width="40%"}
+![](images/pypi-add-trusted-publisher.png){height="450"}
+:::
+
+::::
 
 # Quelques backend pour le build de packages
 
@@ -612,7 +685,7 @@ packages : [TestPyPI](https://test.pypi.org/]
 Les backends se sont multipliés au point qu'il est difficile de savoir lequel
 utiliser.
 
-## Flit 1/3
+## backend : Flit 1/3
 
 > [Flit](https://flit.pypa.io/en/latest/) provides a simple way to create and
 > upload pure Python packages and modules to `PyPI`. It focuses on [making the easy things easy](https://flit.pypa.io/en/latest/rationale.html) 
@@ -621,7 +694,7 @@ utiliser.
 
 `Flit` est un outil récent ^[Post [PEP 518](https://peps.python.org/pep-0518/)]
 et simple pour générer des packages pur Python : sans compilation de code C,
-intégration de JavaScript, ...
+sans intégration de JavaScript, ...
 
 `Flit` ne gère pas les dépendances.
 
@@ -629,9 +702,9 @@ intégration de JavaScript, ...
 
 `Flit` dépendrait d'un seul développeur ?
 
-## Flit 2/3
+## backend : Flit 2/3
 
-Exemple de fichier `pyproject.toml` généré par `Flit` :
+Exemple de fichier `pyproject.toml` généré par la commande `flit init` :
 
 ```{.toml}
 [build-system]
@@ -654,19 +727,65 @@ Les métadonnées `version` et `description` sont récupérées dynamiquement :
 [Flit : The pyproject.toml config file](https://flit.pypa.io/en/latest/pyproject_toml.html?highlight=dynamic#new-style-metadata)
 :::
 
-## Flit publish 3/3
+## backend : Flit publish 3/3
 
-Il est intéressant de tester l'upload de son package sur le serveur de test
+On peut tester l'upload de son package sur le serveur :
 [test.pypi.org](https://test.pypi.org/)
+^[Voir [PyPA : Using TestPyPI](https://packaging.python.org/en/latest/guides/using-testpypi/) 
+et [Flit : Controlling package uploads](https://flit.pypa.io/en/latest/upload.html)]
+
+Il est nécessaire de configurer, au préalable, l'accès au serveur
+`test.pypi.org` dans le fichier `.pypirc` ^[[Flit issue 122](https://github.com/pypa/flit/issues/122)] 
+ce que ne requiert pas pour un upload vers [pypi.org](https://pypi.org/)
+
+:::: {.columns}
+
+::: {.column width="50%"}
+
+Publication avec un `token d'API` spécifique au projet, configuré dans le
+fichier `.pypirc` :
 
-Flit requiert alors de configurer l'accès à ce serveur dans le fichier
-`.pypirc` ^[[Flit issue 122](https://github.com/pypa/flit/issues/122)] ce qu'il
-ne fait pas automatiquement contrairement aux upload vers [pypi.org](https://pypi.org/)
+```{.ini}
+[distutils]
+index-servers = 
+   pypi
+   testpypi
+   test_ntt
+
+[test_ntt]
+repository = https://test.pypi.org/legacy/
+username = __token__
+```
+
+:::
+
+::: {.column width="50%"}
+
+```{.bash}
+$ flit publish --repository test_ntt
+Found 144 files tracked in git                                          I-flit.sdist
+Built sdist: dist/ntt-0.1.1.tar.gz                                 I-flit_core.sdist
+Copying package file(s) from /tmp/tmpdgzv3ozw/ntt-0.1.1/src/ntt    I-flit_core.wheel
+Writing metadata files                                             I-flit_core.wheel
+Writing the record of files                                        I-flit_core.wheel
+Built wheel: dist/ntt-0.1.1-py3-none-any.whl                       I-flit_core.wheel
+Using repository at https://test.pypi.org/legacy/                      I-flit.upload
+Install keyring to store passwords securely                            W-flit.upload
+Server  : https://test.pypi.org/legacy/
+Username: __token__
+Password:
+Uploading dist/ntt-0.1.1-py3-none-any.whl...                           I-flit.upload
+Package is at https://test.pypi.org/project/ntt/                       I-flit.upload
+...
+Uploading dist/ntt-0.1.1.tar.gz...                                     I-flit.upload
+...
+```
+
+:::
 
-- [PyPA : Using TestPyPI](https://packaging.python.org/en/latest/guides/using-testpypi/)
-- [Flit : Controlling package uploads](https://flit.pypa.io/en/latest/upload.html)
+::::
 
-## Hatch 1/2
+## backend : Hatch 1/2
 
 > [Hatch](https://hatch.pypa.io/latest/) is a unified command-line tool meant
 > to conveniently **manage dependencies** and **environment isolation** for
@@ -686,7 +805,7 @@ Je n'ai pas vu comment `Hatch` gérait les dépendances.
 
 `Hatch` dépendrait d'un seul développeur ?
 
-## Hatch 2/2
+## backend : Hatch 2/2
 
 Le fichier `pyproject.toml` généré par `hatch new foobar` est assez conséquent
 (157 lignes) :
@@ -851,7 +970,7 @@ exclude_lines = [
 ]
 ```
 
-## Setuptools
+## backend : Setuptools
 
 > [Setuptools](https://setuptools.pypa.io/en/latest/index.html) is a collection
 > of enhancements to the Python distutils that allow you to more easily **build
@@ -872,7 +991,7 @@ pour intégrer la version git au package semblent nécessiter `setuptools`
 comme **backend de build**.
 :::
 
-## Poetry
+## backend : Poetry
 
 > [Poetry](https://python-poetry.org/) is a command-line tool to handle
 > dependency installation and isolation as well as building and packaging of
-- 
GitLab