Intégration et déploiement continus pour Python avec les actions GitHub
La création d'un logiciel est une réussite à célébrer. Mais le logiciel n'est jamais statique. Les bogues doivent être corrigés, les fonctionnalités doivent être ajoutées et la sécurité exige des mises à jour régulières. Dans le paysage d'aujourd'hui, avec des méthodologies agiles dominantes, les systèmes DevOps robustes sont cruciaux pour gérer une base de code en évolution. C’est là que les actions GitHub brillent, permettant aux développeurs de Python d’automatiser les workflows et de garantir que leurs projets s’adaptent parfaitement à changer.
GitHub Actions pour Python permet aux développeurs d'automatiser efficacement les flux de travail. Cela permet aux équipes de maintenir la qualité des logiciels tout en s’adaptant aux changements constants.
Les systèmes d'intégration continue et de déploiement continu (CI/CD) aident à produire des logiciels bien testés et de haute qualité et à rationaliser le déploiement. GitHub Actions rend le CI/CD accessible à tous, permettant l'automatisation et la personnalisation des workflows directement dans votre référentiel. Ce service gratuit permet aux développeurs d'exécuter efficacement leurs processus de développement logiciel, améliorant ainsi la productivité et la fiabilité du code.
Dans ce didacticiel, vous apprendrez à :
- Utilisez les actions GitHub et les workflows
- Automatiser libinting, test et déploiement d'un projet Python
- Identifiants sécurisés utilisés pour l'automatisation
- Automatiser mises à jour de sécurité et de dépendance
Ce didacticiel utilisera une base de code existante, Real Python Reader, comme point de départ pour lequel vous créerez un pipeline CI/CD. Vous pouvez créer le code Real Python Reader sur GitHub pour suivre. Assurez-vous de désélectionner l'option Copier la branche master
uniquement lors du forking. Alternativement, si vous préférez, vous pouvez créer votre propre Real Python Reader à l’aide d’un didacticiel précédent.
Afin de tirer le meilleur parti de ce tutoriel, vous devriez être à l'aise avec pip
, construire des packages Python, Git et familiariser avec la syntaxe YAML.
Avant de fouiller dans les actions GitHub, il peut être utile de prendre du recul et de découvrir les avantages du CI/CD. Cela vous aidera à comprendre les types de problèmes que les actions GitHub peuvent résoudre.
Bénéficier des avantages du CI/CD
L'Intégration continue (CI) et le Déploiement continu (CD), communément appelés CI/CD, sont des pratiques essentielles dans le développement de logiciels modernes. Ces pratiques automatisent l'intégration des modifications de code, l'exécution de tests et le déploiement d'applications. Cela aide les équipes et les contributeurs open source à apporter des modifications de code plus fréquemment, de manière fiable et structurée.
De plus, lors de la publication de packages Python open source, CI/CD garantira que toutes les demandes d'extraction (PR) et contributions à votre package répondront aux besoins du projet tout en standardisant la qualité du code.
Remarque : Pour en savoir plus sur ce qu'est une pull request et comment en créer une, vous pouvez lire la documentation officielle de GitHub.
Des déploiements plus fréquents avec des modifications de code plus petites réduisent le risque de modifications brutales involontaires qui peuvent survenir avec des versions plus volumineuses et plus complexes. Par exemple, même si les développeurs peuvent formater tout le code en utilisant les mêmes outils et règles de peluchage, la politique peut automatiquement bloquer la fusion des PR si les tests du code échouent.
Dans la section suivante, vous découvrirez comment les workflows GitHub peuvent vous aider à implémenter CI/CD sur un référentiel hébergé sur GitHub.
Explorer les flux de travail GitHub
Les workflows GitHub sont une fonctionnalité puissante de GitHub Actions. Ils vous permettent de définir des workflows d'automatisation personnalisés pour vos référentiels. Que vous souhaitiez créer, tester ou déployer votre code, les workflows GitHub fournissent une solution flexible et personnalisable que tout projet sur GitHub peut utiliser gratuitement, que le référentiel soit public ou privé.
Même s'il existe de nombreux fournisseurs CI/CD, GitHub Actions est devenue la défaut parmi les projets open-source sur GitHub en raison de son écosystème, de sa flexibilité et de son coût faible ou peu élevé.
Anatomie d'un fichier de workflow
Les fichiers de flux de travail sont des fichiers YAML écrits de manière déclarative avec une structure prédéfinie qui doit être respectée pour qu'un workflow puisse fonctionner avec succès. Vos fichiers YAML Workflow sont stockés et définis dans un dossier .github/workflows/
dans le répertoire racine de votre projet.
Votre dossier de workflow peut avoir plusieurs fichiers de workflow, chacun effectuera une certaine tâche. Vous pouvez nommer ces fichiers de workflow tout ce que vous souhaitez. Cependant, par souci de simplicité et de lisibilité, il est courant de les nommer après les tâches qu'ils accomplissent, telles que test.yml
.
Chaque fichier contient quelques éléments obligatoires, mais de nombreux autres éléments facultatifs. La documentation GitHub Actions est complète et bien rédigée, alors assurez-vous de la consulter après avoir fini de lire ce didacticiel.
Il y a trois pièces principales qui composent la majeure partie d'un fichier de workflow: déclenche , emplois et étapes . Vous les couvrirez dans les sections suivantes.
Déclencheurs du flux de travail
Un déclencheur est un événement qui provoque l'exécution d'un flux de travail. Il existe de nombreux types de déclencheurs. Les plus courants sont ceux qui se produisent sur A:
- Demande de tirage
- a poussé Commit à la branche par défaut
- Tagged commit
- Déclenchement Manuel
- Demande par un autre flux de travail
- Nouveau numéro en cours d'ouverture
Vous pouvez également limiter davantage les déclencheurs en le limitant à une branche ou un ensemble de fichiers spécifiques. Voici un exemple simple de déclencheur qui exécute un workflow sur tout pousse vers la branche principale:
on:
push:
branches:
- main
Pour des informations détaillées sur les déclencheurs non couverts dans ce didacticiel, vous pouvez consulter la documentation officielle.
Maintenant que vous savez comment les événements déclenchent des workflows, il est temps d'explorer le prochain composant d'un fichier de workflow: Jobs.
Tâches de flux de travail
Chaque workflow comporte une seule section jobs
, qui est le conteneur pour la viande et les pommes de terre du workflow. Un flux de travail peut inclure une ou plusieurs tâches qu'il exécutera, et chaque tâche peut contenir une ou plusieurs étapes.
Voici un exemple de ce à quoi ressemblerait cette section sans aucune étape:
# ...
jobs:
my_first_job:
name: My first job
my_second_job:
name: My second job
Lorsque vous créez un travail, la première chose à faire est de définir le coureur que vous souhaitez utiliser pour exécuter votre travail. Un Runner
est une machine virtuelle (VM) hébergée par GitHub qui exécute vos travaux pour vous. GitHub provisionnera et dérogera la machine virtuelle afin que vous n'ayez pas à vous soucier de maintenir une infrastructure pour votre CI/CD.
Il existe plusieurs systèmes d'exploitation pris en charge disponibles. Vous pouvez trouver la liste complète des coureurs hébergés par Github dans la documentation.
Remarque : Les coureurs auto-hébergés sont également une option si les versions gratuites et illimitées ne répondent pas à vos besoins. Ce didacticiel ne couvre pas les exécuteurs auto-hébergés, mais vous pouvez trouver des informations détaillées sur l'utilisation des exécuteurs auto-hébergés dans la documentation officielle.
Définir un coureur ne nécessite qu'une seule ligne de YAML :
# ...
jobs:
my_first_job:
name: My first job
runs-on: ubuntu-latest
# ...
my_second_job:
name: My second job
runs-on: windows-latest
# ...
Dans l'exemple ci-dessus, my_first_job
s'exécutera dans une machine virtuelle Ubuntu, et my_second_job
s'exécutera dans une machine virtuelle Windows. Les deux utilisent le suffixe -LaSest
dans ce cas, mais vous pouvez également spécifier la version exacte du système d'exploitation - par exemple, ubuntu-20.24
, tant qu'il s'agit d'un support pris en charge version.
Étapes du flux de travail
Les étapes sont la partie principale d'un emploi. Comme vous l'avez probablement deviné, les étapes déclarent les actions qui doivent être effectuées lors de l'exécution du flux de travail. Cela peut inclure des tâches telles que l'installation de Python, l'exécution de tests, le libellé de votre code ou l'utilisation d'une autre action GitHub.
Tout comme votre code Python, les tâches courantes et répétables peuvent être abstraites dans des flux de travail distincts et réutilisées. Cela signifie que vous pouvez et devez utiliser les actions GitHub d'autres personnes dans vos propres flux de travail, de la même manière que vous le feriez lors de l'importation d'une bibliothèque Python, pour vous faire gagner du temps lors de la réimplémentation de cette fonctionnalité.
Dans la section suivante, vous verrez comment utiliser d’autres actions GitHub et comment les trouver.
En utilisant des actions github pour python
Même si les flux de travail font partie des actions GitHub, les flux de travail peuvent également contenir des actions GitHub. En d'autres termes, vous pouvez utiliser les actions des autres ou des organisations dans votre flux de travail. En fait, c'est une pratique courante et fortement encouragée à utiliser les actions GitHub existantes dans vos fichiers de flux de travail. Cette pratique vous fait gagner du temps et des efforts en tirant parti des fonctionnalités prédéfinies.
Si vous avez une tâche spécifique à accomplir, une action GitHub est probablement disponible pour la réaliser. Vous pouvez trouver des actions GitHub pertinentes sur le marché GitHub, que vous découvrirez ensuite.
Explorer le marché GitHub
Le GitHub Marketplace est un référentiel en ligne de toutes les actions que les gens peuvent utiliser dans leurs propres flux de travail. Github, des fournisseurs tiers et des individus construisent et maintiennent ces actions GitHub. Tout le monde peut utiliser le modèle d'action GitHub pour créer sa propre action et l'héberger sur le marché.
Cela a conduit à une vaste gamme d'actions GitHub disponibles pour presque tous les types d'automatisation de tâches imaginables. Toutes les actions du GitHub Marketplace sont open source et gratuites.
Dans la section suivante, vous examinerez deux actions GitHub que vous utiliserez pour chaque projet Python.
Inclure des actions dans les workflows
Chaque flux de travail basé sur Python que vous créez doit non seulement extraire votre référentiel actuel dans l'environnement de flux de travail, mais également installer et configurer Python. Heureusement, GitHub propose des actions GitHub officielles pour vous aider dans les deux tâches :
# ...
jobs:
my_first_job:
name: My first job
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.13"
- run: python -m pip install -r requirements.txt
Dans l'exemple ci-dessus, vous pouvez voir que la première étape de étapes
consiste à utiliser l'action officielle cacher
. Cette action vérifie le code de votre référentiel dans l'espace de travail GitHub actuel, permettant à votre flux de travail d'y accéder. Le @ 4
suivant Checkout
est un spécificateur de version, indiquant quelle version de l'action à utiliser. À l'heure actuelle, la dernière version est V4.2.2, vous pouvez donc vous y référer à l'aide de cette syntaxe pour spécifier la dernière version majeure.
La deuxième étape de cet exemple configure Python dans l'environnement. Encore une fois, cet exemple utilise l'action GitHub officielle pour ce faire en raison de son support et de son développement continus. La plupart des actions, voire la totalité, comportent des configurations supplémentaires que vous pouvez ajouter à l'étape.
La documentation de l'action Installer Python contient la liste complète des configurations. Pour l'instant, le minimum dont vous avez besoin pour installer Python dans votre environnement de workflow est de déclarer la version de Python que vous souhaitez installer.
Dans la dernière étape de l'exemple, vous utilisez la commande run
. Cette commande vous permet d'exécuter n'importe quelle commande bash
ou powershell
, selon le runner que vous utilisez pour l'étape. Dans ce cas, vous installez les dépendances du projet à partir du fichier d'exigences.
J'espère que vous pouvez voir à quel point les actions GitHub peuvent être puissantes. Avec très peu de code et d'efforts, vous avez un moyen reproductible de configurer un environnement prêt à construire, à tester et à déployer votre projet Python.
Vous avez maintenant une compréhension de base de la structure d'un fichier de workflow et comment vous pouvez créer votre premier flux de travail pour un projet. Dans la section suivante, vous ferez exactement cela avec un exemple réel.
Création de votre premier flux de travail
Il est temps de parcourir les étapes d'ajout de CI/CD à un projet réel existant, le Real Python Reader. Avant d'ajouter des flux de travail pour tester et déployer ce package, vous devez d'abord commencer par le peluchage.
Un linter est un outil qui analyse votre code et recherche des erreurs, des problèmes stylistiques et des constructions suspectes. La liaison vous permet de résoudre les problèmes et d'améliorer la qualité de votre code avant de la partager avec d'autres. En démarrant votre CI/CD avec la liaison, vous vous assurerez que votre code est propre et lisible avant de déployer le package sur PYPI.
REMARQUE: Si la libellule est un nouveau concept pour vous, alors vous pouvez en savoir plus en lisant sur Ruff, un python moderne.
Pour ce workflow, vous utiliserez Ruff pour pelucher le code Python. Mais si vous ne l'avez pas déjà fait, créez d'abord le référentiel, y compris toutes les branches, puis clonez-le. Assurez-vous de remplacer votre nom d'utilisateur par votre nom d'utilisateur GitHub :
$ git clone git@github.com:your-username/reader.git
$ cd reader/
$ git checkout github-actions-tutorial
$ mkdir -p .github/workflows/
Après avoir cloné votre référentiel à fourche et modifié votre répertoire de travail actuel, vous devrez passer à la branche préexistante nommée github-action-tutorial
. Si une telle branche n'est pas disponible, vous avez probablement oublié de décocher l'option Copiez l'option maître
seulement lors de la fourniture. Dans un tel cas, vous devez supprimer votre fourchette, revenir au référentiel d'origine, le fourrer à nouveau et vous assurer que vous incluez toutes les branches cette fois.
Une fois que vous avez réussi à basculer vers la bonne branche, créez un dossier pour stocker vos flux de travail. Ce dossier doit s'appeler workflows/
et être un sous-répertoire du dossier .github/
.
Remarque: Lorsque vous fourrez un référentiel qui a des actions GitHub existantes, vous pouvez voir une invite vous demandant de les activer après avoir cliqué sur l'onglet Actions de votre référentiel fourchu. Il s'agit d'une fonctionnalité de sécurité. En confirmant que vous souhaitez activer les actions, vous n'aurez aucun problème après le reste de ce tutoriel.
Vous êtes maintenant prêt à créer votre premier flux de travail dans lequel vous définirez vos déclencheurs, configurerez l’environnement et installerez Ruff. Pour commencer, vous pouvez définir vos déclencheurs dans le fichier lint.yml
:
name: Lint Python Code
on:
pull_request:
branches:
- master
push:
branches:
- master
workflow_dispatch:
Même si cela n'est pas nécessaire, il est considéré comme la meilleure pratique de donner à chacun de vos workflows un nom clair et lisible par l'homme. Ce nom apparaîtra dans la colonne de gauche de l'onglet Actions de votre référentiel GitHub. Il vous aide à identifier les flux de travail et à filtrer disponibles grâce à vos fonctions de workflow précédentes:
Après avoir défini le nom, vous pouvez vous concentrer sur les déclencheurs de ce flux de travail. Dans le code ci-dessus, trois déclencheurs différents sont définis qui peuvent lancer le flux de travail :
- Ouverture d'une demande de traction
- Pousser les commits locaux
- Envoi manuel du workflow
Les deux premiers déclencheront le workflow sur tout événement de demande push ou pull sur la branche master
. Cela signifie que toute modification du code déclenchera l'exécution de ce flux de travail, que vous le poussiez directement vers master
ou que vous utilisiez une pull request pour fusionner le code dans la branche master
de votre dépôt.
Remarque : Ce workflow est déclenché par des événements sur la branche master
pendant que vous travaillez sur une autre branche. Si vous souhaitez voir l'action prendre effet immédiatement après avoir transféré vos commits sur GitHub, envisagez d'ajouter github-actions-tutorial
à la liste des branches surveillées par le workflow.
Il n'est pas évident ce que fait le déclencheur final. Selon la documentation, il est couramment utilisé pour relancer un flux de travail qui a échoué pour des raisons sans rapport avec les modifications de code, telles qu'une clé API expirée. Cependant, le déclencheur workflow_dispatch
fonctionne uniquement lorsque le fichier de workflow est sur la branche par défaut.
Une fois les déclencheurs définis, il est temps de passer à l'étape suivante de la création du fichier de workflow, qui consiste à définir les tâches et à configurer l'environnement :
name: Lint Python Code
on:
pull_request:
branches:
- master
push:
branches:
- master
workflow_dispatch:
jobs:
lint: # The name of the job
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.13"
cache: "pip"
La plupart de ce code devrait vous sembler familier par rapport aux exemples précédents, mais il existe quelques petites différences. Tout d'abord, vous avez nommé le travail lint
pour décrire ce qu'il fait. Ceci est juste un nom, vous pouvez donc choisir le nom de votre choix tant qu'il respecte la syntaxe YAML. Vous avez également défini le programme d'exécution que vous utiliserez pour ce flux de travail comme étant ubuntu-latest
.
Ensuite, vous remarquerez que l'action setup-python
est désormais configurée pour mettre en cache les dépendances pip de tous les packages installés. Cela permet d'accélérer votre flux de travail lors des exécutions futures si les versions d'un package sont les mêmes. Au lieu de les extraire de PyPI, il utilisera les versions mises en cache.
Remarque: Pour en savoir plus sur la façon dont vous pouvez utiliser la mise en cache dans vos workflows, vous pouvez consulter la documentation GitHub.
Maintenant que votre workflow a un déclencheur et un coureur défini, et avec votre code de code et Python installé, il est temps d'installer Ruff et de l'exécuter pour mettre le code. Vous pouvez le faire en ajoutant deux étapes supplémentaires à votre travail peluche
:
name: Lint Python Code
on:
pull_request:
branches:
- master
push:
branches:
- master
workflow_dispatch:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.13"
cache: "pip"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install ruff
- name: Run Ruff
run: ruff check --output-format=github
Dans les deux dernières étapes du travail lint
, vous utilisez la commande Exécuter
que vous avez vu plus tôt. Dans le cadre de la syntaxe YAML, vous remarquerez un symbole de tuyau ( |
) sur la deuxième ligne. Cela désigne une chaîne multi-lignes. La commande Exécuter
interprétera les lignes suivantes comme des commandes distinctes et les exécutera en séquence.
Après avoir installé Ruff, le flux de travail se termine enfin par l'exécution de Ruff pour rechercher les erreurs de peluchage. Avec cette commande, vous pouvez spécifier que vous souhaitez que la sortie soit optimisée pour une exécution dans un workflow github
avec la balise --output-format
.
Remarque: Si vous utilisez Ruff et que vous avez vos propres configurations en dehors de la valeur par défaut, vous pouvez remplacer ces deux dernières étapes par la propre action GitHub de Ruff.
Félicitations! Vous avez terminé votre premier flux de travail. Une fois ce workflow validé dans votre référentiel et poussé, GitHub exécutera automatiquement ce workflow de peluchage lorsque la condition de déclenchement est remplie. Vous pouvez également déclencher ce workflow manuellement à tout moment sur le site Web GitHub. Pour ce faire, accédez à l'onglet Actions de votre référentiel, sélectionnez le workflow souhaité dans la partie gauche, puis cliquez sur Exécuter le workflow :
Maintenant que vous avez un flux de travail à votre actif et que vous comprenez comment fonctionnent les flux de travail, il est temps d'en créer un qui exécute la suite de tests sur Real Python Reader.
Création d'un flux de travail de test automatisé
Maintenant que vous avez découvert votre premier workflow GitHub, il est temps d'examiner ce qui sera sans doute le plus important de tous les workflows de ce package : les tests automatisés.
Le Real Python Reader utilise pytest
comme framework de test. Et compte tenu de ce que vous avez déjà appris sur les actions GitHub, vous pouvez même voir comment vous pouvez modifier le flux de travail de liaison pour le transformer en flux de travail de test. Après tout, vous allez suivre les mêmes étapes pour vous préparer à exécuter pytest
. Il est important de noter que lorsque vous testez un progiciel, vous devez le tester sur toutes les versions prises en charge de Python.
Mais d'abord, comme pour tous les flux de travail GitHub, vous devez déclarer les déclencheurs du flux de travail de test:
name: Run Tests
on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_call:
workflow_dispatch:
Une grande partie de ce qui précède est identique au workflow de peluchage précédent, mais avec une différence : il existe désormais un nouveau déclencheur, workflow_call
. Tout comme workflow_dispatch
, workflow_call
est un déclencheur prédéfini qui permet à d'autres workflows de déclencher ce workflow.
Cela signifie que si vous avez un flux de travail à l'avenir qui nécessite également que les tests passent, au lieu de répéter le code, vous pouvez demander au nouveau flux de travail d'utiliser ce flux de travail de test. Le workflow déclenchera ensuite ce flux de travail de test comme l'une de ses étapes et s'assurera qu'il passe avant de passer aux autres étapes du travail. Donc plus de répétition, et vous pouvez garder vos workflows plus courts et précis.
Bien que vous n'utilisiez pas cette méthode de réutilisation du flux de travail dans votre flux de travail test.yml
, vous y parviendrez de la même manière que vous appelez d'autres actions GitHub dans votre fichier de workflow, en utilisant le Use
mot-clé:
# Github-username/repo/path/to/workflow@version
- uses: realpython/reader/.github/workflows/test.yml@master
Ici, vous pouvez voir que vous pouvez réutiliser un workflow en passant une chaîne de type chemin à use
. Il devrait commencer par le nom d'utilisateur GitHub et le nom du référentiel, suivi du chemin vers le fichier de workflow que vous souhaitez utiliser. @master
dit au nouveau workflow que vous souhaitez utiliser la version du flux de travail de test de la branche maître
. Et maintenant, vous pouvez voir à quel point les actions GitHub peuvent être puissantes. La réutilisation des flux de travail est un énorme avantage des actions GitHub.
Maintenant que vous avez défini les déclencheurs du workflow de test, il est temps de répondre à la question : comment tester sur plusieurs versions de Python ? Dans la section suivante, vous verrez comment définir vos étapes une fois et les exécuter plusieurs fois, chaque exécution étant sur une version différente de Python.
Tests sur plusieurs versions de Python
Dans le flux de travail de liaison, vous avez utilisé l'action configuration-python
dans votre étapes
pour configurer Python 3.13 dans l'instance Ubuntu, qui ressemblait à ceci:
# ...
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.13"
cache: "pip"
# ...
# ...
Malheureusement, vous ne pouvez pas simplement ajouter une liste de versions Python à Python-Version
et être fait. Ce dont vous avez besoin est une matrice
pour tester plusieurs versions de Python.
Pour citer la documentation officielle:
Une stratégie matricielle vous permet d'utiliser des variables dans une seule définition de travail pour créer automatiquement plusieurs exécutions de travail basées sur les combinaisons des variables. Par exemple, vous pouvez utiliser une stratégie matricielle pour tester votre code dans plusieurs versions d'une langue ou sur plusieurs systèmes d'exploitation. (Source)
En bref, quelles que soient les variables que vous définissez dans votre matrice
exécutera les mêmes étapes dans le travail, mais en utilisant ces variables. Ici, vous souhaitez exécuter différentes versions de Python, mais vous pouvez également l'utiliser pour exécuter ou créer votre code sur différents systèmes d'exploitation.
Déclarer une stratégie est relativement simple. Avant de définir vos étapes mais dans le cadre de votre travail, vous pouvez définir la stratégie dont vous avez besoin :
name: Run Tests
on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_call:
workflow_dispatch:
jobs:
testing:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
Comme vous pouvez le voir, vous déclarez une variable python-version
, qui est un tableau de numéros de version. Super, c'est la première partie terminée ! La deuxième partie consiste à indiquer à l'action setup-python
que vous souhaitez utiliser ces versions en utilisant une syntaxe de variable spéciale :
name: Run Tests
on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_call:
workflow_dispatch:
jobs:
testing:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
L'étape de configuration Python du workflow a maintenant deux changements. Le premier est le nom ajouté
à l'étape. Comme vous l'avez appris plus tôt, cela n'est pas nécessaire, mais cela vous aidera à identifier la version Python a échoué en faisant référence à la version Python au nom de l'étape. Ceci est utile, étant donné que cette étape fonctionnera pour cinq versions différentes de Python.
Le deuxième changement est qu'au lieu de coder dur, le numéro de version dans le avec: Python-Version
partie de configuration-python
, vous pouvez maintenant vous référer à python- Version
définie dans la matrice.
GitHub a quelques contextes spéciaux auxquels vous pouvez accéder dans le cadre de vos workflows. La matrice en fait partie. En définissant la matrice comme faisant partie de la stratégie, python-version
est devenue une propriété du contexte matriciel. Cela signifie que vous pouvez accéder à n'importe quelle variable définie comme faisant partie de la matrice avec la syntaxe DOT (.
), par exemple, matrix.python-version
.
Bien que ce ne soit pas quelque chose qui doit être fait pour Real Python Reader, vous pouvez faire la même chose avec différentes versions du système d'exploitation. Par exemple:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
Vous pouvez ensuite utiliser la même notation de points pour accéder à la variable OS
que vous avez défini dans la matrice avec matrix.os
.
Maintenant que vous savez comment utiliser une matrice pour exécuter vos étapes de manière déclarative en utilisant une version différente de Python, il est temps de terminer le flux de travail de test dans son intégralité.
Finalisation du flux de travail de test
Il ne reste que quelques étapes supplémentaires à effectuer pour terminer le flux de travail. Maintenant que Python est installé, le workflow devra installer les dépendances du développeur, puis enfin exécuter pytest
.
Le package Real Python Reader utilise un fichier de configuration pyproject.toml
pour déclarer ses dépendances. Il comporte également des dépendances de développeur facultatives, qui incluent pytest
. Vous pouvez les installer de la même manière que vous avez installé Ruff précédemment, en utilisant la commande run
:
name: Run Tests
on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_call:
workflow_dispatch:
jobs:
testing:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install .[dev]
Cette étape est tout ce dont vous avez besoin pour installer les dépendances requises. La seule étape restante consiste à exécuter pytest
:
name: Run Tests
on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_call:
workflow_dispatch:
jobs:
testing:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install .[dev]
- name: Run Pytest
run: pytest
À ce stade, vous avez à la fois un workflow ling et test qui est déclenché chaque fois qu'un événement PR ou push se produit sur Master. Ensuite, vous tournerez votre attention vers la partie CD de CI/CD et apprendrez comment vous pouvez publier automatiquement un package à PYPI.
Publier automatiquement votre package à PYPI
Le troisième workflow complète ce que la plupart des gens considèrent comme un pipeline CI/CD minimum. Ce troisième flux de travail fournit un moyen reproductible et cohérent de créer et de publier un package. Le package Real Python Reader utilise la bibliothèque Python build
largement utilisée pour générer des fichiers de distribution Python, qui peuvent ensuite être déployés sur PyPI.
Lorsque les flux de travail deviennent un peu plus compliqués et comportent plusieurs étapes ou tâches, il est recommandé d’écrire les étapes et le flux. Cela vous aidera à suivre toutes les étapes dans le bon ordre afin que les actions GitHub que vous utilisez soient correctement configurées dès le début. Cela vous fera gagner du temps plus tard en vous aidant à éviter les bugs potentiels dans votre flux de travail de build.
Voici les étapes du workflow pour le fichier deploy.yml
:
- configurer l'environnement en installant des dépendances Python et construire
- Créez le package en plaçant des fichiers de sortie dans un dossier
dist/
- publier les fichiers de distribution à PYPI
- Créez une version GitHub si la publication a réussi
Dans la section suivante, vous aborderez les deux premiers éléments de la liste et que vous aurez une bonne partie de votre workflow écrit.
Configuration et construction du package
Comme pour les deux derniers flux de travail, la première étape consiste à définir les déclencheurs du workflow. Vous avez vu des déclencheurs communs qui tournent autour des workflows de développeur typiques, mais la libération automatique avec chaque nouveau RP ou Push to the Mais-Mraning Branch n'est pas idéal pour le vrai lecteur Python.
Il est plus logique de baisser la version du package après plusieurs demandes de traction, des corrections de bogues ou après avoir ajouté de nouvelles fonctionnalités. La façon moderne de déclencher une telle version après une version de version consiste à utiliser le meilleur ami du développeur, Git.
Git vous permet de baliser un commit pour indiquer un moment notable dans le développement du logiciel. C'est souvent l'outil de choix pour définir une nouvelle version. Les actions GitHub disposent d'une prise en charge intégrée pour l'utilisation des balises Git comme déclencheurs via le mot-clé tags
:
name: Publish to PyPI
on:
push:
tags:
- "*.*.*"
Comme vous pouvez le voir ici, les déclencheurs prennent également en charge les modèles GLOB. Ainsi, un astérisque ( *
) peut correspondre à n'importe quel caractère dans une séquence. Le modèle décrit ci-dessus correspondra à tout caractère suivi d'un point décimal (.
), un autre caractère, un autre point décimal et enfin, un autre caractère.
Cela signifie que 1.0.0 est une correspondance valide, tout comme 2.5.60. Cela correspond au versioning sémantique utilisé par Real Python Reader. Vous pouvez également utiliser v *. *. *
à la place si vous préférez. Ainsi, vos balises GIT doivent commencer par un v
, qui signifie version . Par exemple, v1.0.0 serait une balise valide.
Afin de déclencher ce flux de travail, vous marqueriez un engagement avec le nom de la version:
$ git tag -a "1.0.0" -m "1.0.0"
$ git push --tags
Pousser votre nouvelle balise vers GitHub déclenchera alors ce flux de travail. Ensuite, vous allez configurer l’environnement et installer les dépendances :
name: Publish to PyPI
on:
push:
tags:
- "*.*.*"
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.13"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install .[build]
- name: Build package
run: python -m build
Tout d'abord, vous définissez la tâche publier
et installez Python 3.13 dans une machine virtuelle Ubuntu. L'étape suivante installe les dépendances de construction de Real Python Reader. Dans la dernière étape, vous utilisez la même commande run
que vous avez utilisée auparavant, mais cette fois, au lieu d'exécuter Ruff ou pytest
, vous allez créer le Real Python Reader. emballer. Par défaut, build
placera les fichiers de distribution dans un dossier appelé dist
.
Excellent! Vous avez mis en œuvre les deux premières parties principales du plan de flux de travail. Avant de pouvoir déployer sur PyPI, vous devez savoir comment sécuriser votre jeton API PyPI.
Garder vos secrets en sécurité
Comme vous l'avez appris plus tôt, les workflows ont accès à des contextes spéciaux comme matrice
. Un autre contexte auquel tous les workflows ont accès est le contexte secrets
. En stockant des données sensibles en tant que Secointe Secret , vous pouvez vous assurer de ne jamais divulguer accidentellement des clés d'API, des mots de passe ou d'autres informations d'identification. Votre flux de travail peut accéder à ces informations d'identification sensibles à l'aide du contexte secrets
.
Vous pouvez ajouter des secrets à votre référentiel sur le site Web de GitHub. Une fois que vous les avez ajoutés, vous ne pouvez pas les voir ou les modifier. Vous ne pouvez les remplacer que par une nouvelle valeur. C'est une bonne idée de revoir la documentation GitHub pour voir comment ajouter des secrets sur le site Web de GitHub. Les documents officiels sont continuellement mis à jour avec tous les modifications de l'interface utilisateur, ce qui en fait la meilleure source pour apprendre à utiliser cette fonctionnalité GitHub.
Déploiement de votre colis
Après avoir sécurisé votre clé API en tant que secret GitHub, vous pouvez y accéder dans le workflow :
name: Publish to PyPI
on:
push:
tags:
- "*.*.*"
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.13"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install .[build]
- name: Build package
run: python -m build
- name: Test publish package
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
repository-url: https://test.pypi.org/legacy/
- name: Publish package
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
Dans cette étape, vous pouvez utiliser l'action GitHub officielle de la Python Packaging Authority (PyPA), qui gère PyPI. Cette action GitHub effectue l'essentiel du travail et n'a besoin que d'une référence à votre jeton API PyPI. Encore une fois, par défaut, il recherchera dans votre dossier dist
toute nouvelle version d'un package à télécharger.
Plutôt que d'utiliser un nom d'utilisateur et un mot de passe traditionnels pour s'authentifier auprès de PYPI, il est de la meilleure pratique d'utiliser un jeton API dans le cadre de versions automatiques.
Puisque vous utilisez un jeton API et qu'il n'y a pas de nom d'utilisateur, l'utilisation de __token__
comme nom d'utilisateur indique à l'action GitHub que l'authentification par jeton est utilisée. Tout comme avec la stratégie matricielle précédente, vous pouvez utiliser la notation par points pour accéder au contexte secret, comme dans secrets.PYPI_API_TOKEN
.
Le nom du secret stocké dans GitHub n’a pas d’importance, tant qu’il a du sens pour vous. Le secret GitHub est nommé PYPI_API_TOKEN
, vous le référencez donc dans le workflow en utilisant ce nom.
Vous avez peut-être remarqué que le flux de travail comprend une étape de test avant de publier le package à PYPI. Cette étape est presque identique à l'étape de publication, avec une différence clé: vous devrez fournir un Repository-URL
pour remplacer l'URL par défaut et pousser le package à tester.pypi.org.
L'utilisation de TestPyPi est un excellent moyen de s'assurer que votre package est construit et versé correctement. Il vous permet d'identifier et de résoudre tous les problèmes potentiels qui pourraient causer des problèmes lors de la publication du référentiel PYPI principal.
Si vous suivez votre propre fork du référentiel et avez l'intention de transférer votre version vers PyPI, vous devrez alors mettre à jour le nom du projet avec un nom unique. Si vous ne mettez pas à jour le nom du projet, vous recevrez une erreur HTTP 403 lorsque vous tenterez de le télécharger. En effet, vous n'êtes pas autorisé à publier le package realpython-reader
sur PyPI. La mise à jour du nom du projet vous permettra de publier votre propre version.
À titre d'exemple, vous pouvez ajouter votre nom d'utilisateur comme préfixe au nom du projet :
[build-system]
requires = ["setuptools>=61.0.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "username-realpython-reader"
# ...
Il y a juste une étape de plus du workflow à terminer - créant une version GitHub à promouvoir, puis partager directement la version. Avant de pouvoir le faire, vous découvrirez les variables d'environnement GitHub.
Accéder aux variables d'environnement GitHub
Afin de publier une version dans un repo GitHub, un jeton GitHub est requis. Vous les avez peut-être déjà utilisés si vous avez déjà utilisé l'API GitHub. Étant donné le risque de sécurité d'utiliser des jetons GitHub personnels dans les flux de travail, GitHub crée un jeton en lecture seule dans le contexte des secrets par défaut. Cela signifie que vous y avez toujours accès si vous en avez besoin.
De plus, chaque exécuteur GitHub inclut par défaut la CLI GitHub pratique. Cela rend l'exécution de certaines tâches, comme la création d'une version, beaucoup plus simple. La CLI GitHub propose de nombreuses façons d'authentifier l'utilisateur, dont l'une consiste à définir une variable d'environnement appelée GITHUB_TOKEN
.
Vous pouvez voir où cela va. Le jeton GitHub fourni peut être utilisé pour accéder à la CLI et finalement créer un moyen transparent de créer la version github. Voici à quoi cela ressemblerait dans le flux de travail:
name: Publish to PyPI
on:
push:
tags:
- "*.*.*"
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.13"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install .[build]
- name: Build package
run: python -m build
- name: Test publish package
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
repository-url: https://test.pypi.org/legacy/
- name: Publish package
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
- name: Create GitHub Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release create ${{ github.ref_name }} ./dist/* --generate-notes
Vous verrez que sur les lignes 39 et 40, le workflow attribue spécifiquement le jeton GitHub du contexte des secrets à une variable d'environnement appelée github_token
. Toutes les valeurs de clé définies dans Env
seront définies sous forme de variables d'environnement pour l'étape actuelle. Cela signifie que lorsque vous exécutez le GitHub CLI ( gh
), il aura accès au jeton via la variable d'environnement attribuée. Le GitHub CLI ne peut pas accéder directement au contexte des secrets lui-même.
GitHub vous permet également d'accéder à un contexte spécial appelé github
. Le workflow fait référence à l'attribut ref_name
dans le contexte github
. Ceci est défini dans les documents GitHub comme suit:
Le nom de la référence courte de la branche ou de la balise qui a déclenché l'exécution du workflow. (Source)
Ainsi, github.ref_name
sera remplacé par l'attribut qui a déclenché le workflow, qui dans ce cas est le nom de la balise GIT.
La commande gh
ci-dessus créera une version avec le même nom que la balise utilisée pour déclencher la version, téléchargera tous les fichiers depuis ./dist
et générera automatiquement des notes de version. Ces notes de version incluent tous les PR que les développeurs ont fusionnés depuis la création de la dernière version, attribuant ainsi le crédit aux auteurs avec des liens et des noms d'utilisateur pour leurs contributions.
Vous souhaiterez peut-être ajouter les détails manquants aux notes de version. N'oubliez pas que les versions peuvent être modifiées après leur création si vous devez inclure des informations supplémentaires, telles que des avis de dépréciation.
Félicitations! Vous disposez désormais d’un peluchage, de tests et d’un déploiement automatisés. Vous pouvez baliser votre dernier commit et le workflow de déploiement final devrait s'exécuter correctement :
Maintenant que Real Python Reader dispose d'un pipeline CI/CD pour garantir que toutes les futures modifications de la base de code sont robustes et utilisent un code lisible et cohérent, vous pouvez ajouter un flux de travail supplémentaire à Real Python Reader. La cerise sur le gâteau de notre CI/CD, pour ainsi dire.
Dans la section suivante, vous apprendrez comment configurer Dependabot pour automatiser les mises à jour de sécurité et de dépendances.
Automatisation des mises à jour de sécurité et de dépendances
Tout comme le code Python, vos flux de travail GitHub doivent être maintenus et mis à jour. De plus, les bibliothèques sur lesquelles s'appuie le code de Real Python Reader sont en constante évolution et mises à jour, il est donc difficile de suivre et de gérer les dépendances.
Il peut être particulièrement difficile de rester informé des mises à jour de sécurité publiées par vos dépendances si vous ne suivez pas activement le projet sur GitHub ou les médias sociaux. Heureusement, Github a un outil pratique pour aider les deux problèmes. Entrez Deladabot!
Dependabot est un outil d'automatisation qui non seulement vous informera d'une vulnérabilité de sécurité dans vos dépendances mais, s'il est configuré, créera automatiquement un PR pour mettre à jour et résoudre le problème pour vous. Tout ce que vous avez à faire est de consulter le PR automatisé et de fusionner. Avec Dependabot, garder votre package à jour et exempt de vulnérabilités de sécurité connues est simple et rapide, ce qui vous fait gagner du temps que vous pouvez utiliser pour améliorer votre code ou ajouter de nouvelles fonctionnalités.
Vous pouvez configurer Dependabot pour répondre aux besoins de votre projet. Ici, le package Real Python Reader a des exigences assez basiques. Les deux objectifs sont :
- Pour être informé lorsqu'une mise à jour de dépendance est disponible.
- Pour aider à maintenir les autres flux de travail à jour.
Ces exigences sont définies dans un fichier de configuration appelé dependabot.yml
. Contrairement aux autres workflows, le fichier dependabot.yml
se trouve dans le dossier .github
lui-même, pas dans .github/workflows
.
Étant donné que ce fichier ne dure que douze lignes et que vous êtes maintenant plus familier avec la syntaxe YAML, vous pouvez jeter un œil à la configuration finale de la dépendance:
---
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
La propriété version
est une partie obligatoire du fichier. C’est là que vous définissez la version de DependAbot à utiliser, et la version 2 est la dernière. Une autre section obligatoire est mises à jour
. C'est là que va la majeure partie de la configuration. Chaque mise à jour définit l'écosystème du package à vérifier, ainsi que des informations de base concernant le répertoire Delatebot devraient rechercher, ainsi que la fréquence.
Pour la première mise à jour, Dependabot vérifiera les fichiers courants dans lesquels les dépendances pip
sont généralement déclarées, tels que requirements.txt
, pyproject.toml
et autres. . Étant donné que Real Python Reader a un fichier pyproject.toml
dans le répertoire racine, Dependabot est invité à y regarder, comme indiqué par la barre oblique ("/"
).
À quelle fréquence vous souhaitez être informé des mises à jour de dépendance dépend de vous. Chaque projet aura ses propres exigences. Cependant, l'avoir déclaré dans Yaml signifie que si vous trouvez la cadence trop ou pas assez, c'est un changement rapide et simple à faire. Pour l'instant, vous pouvez utiliser hebdomadaire
.
Le deuxième élément de la liste des mises à jour
concerne github-actions
. C'est vrai, DepenBabot vérifiera également les actions GitHub utilisées dans n'importe quel flux de travail dans le dépôt, tel que setup-python
, pour les versions plus récentes! Cela rend la suite des dernières versions des actions GitHub automatiquement et est une chose de moins pour vous.
Remarque: Il existe de nombreux autres paramètres de configuration que vous pouvez utiliser avec DepenBabot, y compris l'option pour marquer automatiquement les utilisateurs de GitHub pour examen lorsqu'il crée un PR. Pour plus d'informations sur d'autres options de configuration, reportez-vous aux documents GitHub officiels.
Grâce à cette configuration en place, Detenabot analysera et vérifiera votre référentiel une fois par semaine pour voir s'il y a des mises à jour que vous pouvez faire pour les dépendances ou vos workflows. Il créera un PR avec un correctif automatiquement. Ces PR de DependAbot exécuteront également vos autres workflows pour vous assurer que les modifications de DelaBabot transmettent vos vérifications de liaison et de test. Double victoire!
Étapes suivantes
Il existe de nombreuses autres tâches que vous pouvez automatiser à mesure que votre référentiel augmente, tels que triage de problèmes, étiquetage, gestion de problèmes périmés, ajoutant des examinateurs à PRS , et plus encore.
Gardez également à l’esprit que GitHub Actions n’est qu’un fournisseur de CI/CD. Si votre projet est hébergé sur GitHub, GitHub Actions peut vous simplifier les choses. Si votre code se trouve sur une autre plateforme ou si vous souhaitez essayer des alternatives, voici une courte liste d'autres fournisseurs CI/CD :
- GitLab
- Pipelines Azure
- CercleCI
- Travis CI
Si vous utilisez déjà l’un de ces fournisseurs ou s’il n’est pas répertorié, n’hésitez pas à le crier dans les commentaires et à partager vos expériences.
Conclusion
Vous savez maintenant comment implémenter un pipeline CI/CD robuste pour un projet Python à l'aide de GitHub Actions. Bien que l'objectif de ce didacticiel soit d'apprendre à ajouter CI/CD à une base de code existante, j'espère que vous en savez maintenant suffisamment pour travailler avec vos propres projets et packages et créer vos propres flux de travail à partir de zéro.
Dans ce tutoriel, vous avez appris à:
- Utilisez les actions GitHub et les workflows
- Automatiser libinting, test et déploiement d'un projet Python
- Identifiants sécurisés utilisés pour l'automatisation
- Automatiser mises à jour de sécurité et de dépendance
En automatisant ces processus, vous avez considérablement amélioré la maintenabilité et la fiabilité de votre projet. Vous avez maintenant un moyen cohérent d'assurer la qualité du code, d'exécuter des tests et de déployer de nouvelles versions avec une intervention manuelle minimale.
N'oubliez pas que CI/CD est un processus itératif. À mesure que votre projet grandit et évolue, vous devrez peut-être ajuster vos flux de travail ou en ajouter de nouveaux. La flexibilité de GitHub Actions vous permet de vous adapter facilement aux exigences changeantes.
Avec ces outils et pratiques en place, vous êtes bien équipé pour gérer et faire évoluer efficacement vos projets Python.