Actions GitHub en tant que CI / CD pour un site sur un générateur statique et des pages GitHub


Habr était un peu surpris qu'il y ait très peu d'articles publiés sur le sujet des fonctionnalités de (beta) GitHub - Actions.


Il semblerait que cette sous-estimation puisse s'expliquer par le fait que la fonctionnalité est encore en phase de test, bien que "beta". Mais c'est une fonctionnalité bêta utile qui vous permet d'utiliser cet outil dans des référentiels privés. Il s'agit de travailler avec cette technologie que je vais aborder dans cet article.


Préhistoire


Si vous commencez dans l'ordre, vous devriez probablement mentionner le moment où, dans le processus de recherche d'une option rapide, pratique, facile et gratuite pour stocker votre site personnel "À propos de moi", j'ai dû passer plusieurs nuits et parcourir de nombreux articles.


Quelqu'un choisit l'hébergement, quelqu'un un serveur cloud et ceux qui ne veulent pas comprendre le travail, l'interaction et le paiement de tout cela - comme le téléchargement de sites statiques dans le référentiel, car maintenant cela peut être fait sur GitHub et GitLab .


Bien sûr, c'est le choix personnel de chacun.


Mon choix final était en faveur de GitHub Pages.


À propos des pages

Quiconque ne le sait pas, gh-pages est une telle option de stockage de documentation sous forme de site Web et elle est fournie gratuitement, et en plus de la documentation, il est proposé de stocker des sites personnels. Cette fonctionnalité est fournie par GitHub à tous les utilisateurs et est disponible dans les paramètres du référentiel.


Pour le référentiel de projet, la branche gh-pages est utilisée, pour le site utilisateur, un référentiel séparé appelé username.imtqy.com avec les codes source du site dans la branche principale est utilisé.


Vous pouvez voir la documentation pour plus de détails, mais je noterai seulement que GitHub avec une générosité incroyable permet à chacun de lier son propre domaine à un tel site en ajoutant simplement un fichier CNAME avec le nom de domaine et en configurant le DNS de son fournisseur de domaine sur le serveur GitHub.


Je suis sûr qu'il existe de nombreux articles sur la façon de déployer un tel site, donc ce n'est pas à ce sujet.


Occurrence d'un problème


Le problème était que lors de l'utilisation d'un générateur statique, il est nécessaire de composer des béquilles des scripts et des bibliothèques pour simplifier le processus de génération de pages et de chargement de celles-ci dans le référentiel. Simplement, si vous stockez le code source dans un référentiel privé séparé, chaque fois que vous apportez des modifications au site, il était nécessaire de déployer un environnement local pour la génération suivante de pages statiques et la publication dans le référentiel du site principal.


Il y a une abondance de générateurs statiques et ils ont tous le même problème. Ces actions prennent trop de temps et d'efforts et finissent par arrêter le travail sur le site, notamment après plusieurs migrations d'OS en OS ou des incidents avec perte de données sur les disques durs (ce fut le cas dans mon cas) .


Tout récemment, soit dans une notification pop-up sur le site, soit dans la newsletter de GitHub, un CI / CD nouvellement construit a été remarqué, ce qui a permis de réaliser ces actions avec un minimum d'effort.


À propos des générateurs de pages statiques

Je ne me concentrerai pas sur cet alinéa, mais je partagerai quelques thèses auxquelles je suis arrivé lors de la sélection et de l'utilisation de celles-ci:


1) il vaut la peine de choisir un générateur pour votre langage de programmation, ou un qui soit aussi clair que possible. Je suis arrivé à cette idée à un moment où je devais moi-même ajouter des fonctionnalités pour le site, poser des béquilles pour sa plus grande stabilité et automatisation. De plus, c'est une bonne raison d'écrire des fonctionnalités supplémentaires sous forme de plugins;


2) sur quel générateur s'appuyer est un choix personnel, mais il convient de considérer que pour l'immersion initiale dans la fonctionnalité de la fonctionnalité GitHub Pages, vous devez d'abord installer Jekyll . Heureusement, cela vous permet de générer un site à partir des sources directement dans le référentiel (je répéterai cela avec mon choix) .


Mon choix de générateur est basé sur le premier point. Pelican, qui est écrit en Python, a facilement remplacé l'étranger pour moi Jekyll (utilisé pendant près d'un an) . En conséquence, même en créant et en éditant des articles, un robot sur un site donne une expérience supplémentaire dans une langue intéressante pour moi.


__


Énoncé du problème


La tâche principale sera d'écrire un tel script (en fait un fichier de configuration) qui générerait automatiquement des pages statiques à partir d'un référentiel privé. La solution utilisera les fonctionnalités de l'environnement virtuel. Le script lui-même ajoutera les pages terminées au référentiel public.


Outils de solution


Outils que nous utiliserons pour résoudre le problème:


  • Actions GitHub;
  • Python 3.7
  • Pelican;
  • Git
  • Pages GitHub.

Résolution de problèmes


Au total, après avoir un peu familiarisé avec la documentation et compris comment écrire des scripts pour les actions, il est devenu clair que ce mécanisme résoudra complètement le problème. Au moment d'écrire ces lignes, pour utiliser cette fonctionnalité, vous devez vous abonner aux tests bêta !



Description de la nouvelle fonctionnalité par Github


L'écriture d'un script Actions commence par la création d'un fichier nommé dans le dossier .github et ses workflows sous-dossier. Vous pouvez le faire manuellement ou à partir de l'éditeur dans l'onglet Actions de la page du référentiel.



Exemple de formulaire de script vierge


Commentez brièvement le formulaire
 name: CI #  :     Actions on: [push] # ,      jobs: # ,    build: # , .. runs-on: ubuntu-latest # ..      steps: #        - uses: actions/checkout@v1 #      - name: Run a one-line script #    1 run: echo Hello, world! #    1 (bash-    ) - name: Run a multi-line script #    2 run: | #    2 () echo Add other actions to build, echo test, and deploy your project. 

Écrivons le vôtre en fonction du modèle:


0) Le nom peut être laissé et «CI». C'est une question de goût.


1) Ensuite, vous devez sélectionner l'action / déclencheur qui conduira au lancement du script, dans notre cas, c'est la poussée habituelle d'un nouveau commit dans le référentiel.


 on: push 

2) L'image sur la base de laquelle le script sera lancé sera également laissée à titre d'exemple, car Ubuntu est assez satisfait des fonctionnalités nécessaires. En regardant les outils disponibles , il devient clair que cela peut être n'importe quelle image nécessaire ou simplement pratique (ou un conteneur docker basé sur elle).


  build: runs-on: ubuntu-latest 

3) Dans les étapes, configurez d'abord l'environnement pour préparer le travail principal.


3.1) allez à la succursale dont vous avez besoin (étape de checkout standard):


 - uses: actions/checkout@v1 

3.2) installez Python:


  - name: Set up Python uses: actions/setup-python@v1 with: python-version: 3.7 

3.3) définissez les dépendances de notre générateur:


  - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt 

3.4) créer un répertoire dans lequel les pages du site seront générées:


  - name: Make output folder run: mkdir output 

4) Pour que le travail sur le site soit cohérent, à savoir ne pas supprimer les modifications précédentes et ajouter des modifications au référentiel du site sans conflits, l'étape suivante consiste à cloner le référentiel du site à chaque fois:


  - name: Clone master branch run: git clone "https://${{ secrets.ACCESS_TOKEN }}@github.com/${GITHUB_ACTOR}/${GITHUB_ACTOR}.imtqy.com.git" --branch master --single-branch ./output 

Cette étape appelle les variables système:


  • GITHUB_ACTOR GitHub définit la variable elle-même, et c'est le nom de l'utilisateur qui a provoqué l'exécution du script;
  • secrets.ACCESS_TOKEN est un jeton généré pour contrôler Github , nous pouvons le transférer en tant que variable d'environnement en définissant les paramètres de notre référentiel dans l'onglet Secrets . Veuillez noter que lors de la génération d'un token, nous serons fournis une fois, il n'y aura plus d'accès. Ainsi que les valeurs des secrets.

5) Nous procédons à la génération de nos pages:


  - name: Generate static pages run: pelican content -o output -s publishconf.py 

Les paramètres transmis au générateur sont responsables du répertoire où les fichiers générés seront envoyés ( -o output ) et du fichier de configuration que nous utilisons pour la génération ( -s publishconf.py ; vous pouvez lire sur l'approche de partage de la configuration locale et de la configuration pour publication dans la documentation Pelican ) .


Permettez-moi de vous rappeler que le référentiel du site a déjà été cloné dans le dossier de output .


6) Configurez git et indexez nos fichiers modifiés:


  - name: Set git config and add changes run: | git config --global user.email "${GITHUB_ACTOR}@https://users.noreply.github.com/" git config --global user.name "${GITHUB_ACTOR}" git add --all working-directory: ./output 

Ce paragraphe utilise la variable déjà connue et indique le répertoire de travail dans lequel les commandes de cette étape seront lancées. Sinon, la commande pour accéder au répertoire de travail ressemblerait à - cd output .


7) Générez un message de validation, validez les modifications et envoyez-les dans le référentiel. Pour s'assurer que la validation n'est pas gaspillée et ne produit donc pas d'erreur en bash (la sortie n'est pas 0 ), nous vérifions d'abord s'il est nécessaire de valider et de pousser quelque chose. Pour ce faire, nous utilisons la commande git diff-index --quiet --cached HEAD -- qui affichera 0 s'il n'y a aucun changement par rapport à la version précédente du site, et il y a 1 ces changements. Ensuite, nous traitons le résultat de cette commande. Ainsi, nous écrirons des informations utiles sur l'état du site à ce stade dans les informations sur l'exécution du script, au lieu de planter automatiquement et de nous envoyer un rapport sur le crash du script.


Nous réalisons également ces actions dans notre annuaire avec des pages prêtes à l'emploi.


  - name: Push and send notification run: | COMMIT_MESSAGE="Update pages on $(date +'%Y-%m-%d %H:%M:%S')" git diff-index --quiet --cached HEAD -- && echo "No changes!" && exit 0 || echo $COMMIT_MESSAGE # Only if repo have changes git commit -m "${COMMIT_MESSAGE}" git push https://${{ secrets.ACCESS_TOKEN }}@github.com/${GITHUB_ACTOR}/${GITHUB_ACTOR}.imtqy.com.git master working-directory: ./output 

Résultat


En conséquence, un tel script vous permet de ne pas penser à créer des pages statiques. En ajoutant des modifications directement au référentiel privé, que vous travailliez avec git depuis n'importe quel système ou que vous créiez un fichier via l'interface Web de GitHub, Actions le fera tout seul. En cas de baisse inattendue du script, une notification sera envoyée par mail.


Code complet

Je vais laisser ma version de travail, il a ajouté la notification que le commit a été lancé dans le référentiel principal à la dernière étape.


Les secrets décrits ci-dessus sont utilisés lorsque le jeton de bot et l'ID utilisateur auquel le message doit être envoyé sont ajoutés.


 name: Push content to the user's GitHub pages repository on: push jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: Set up Python uses: actions/setup-python@v1 with: python-version: 3.7 - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt - name: Make output folder run: mkdir output - name: Clone master branch run: git clone "https://${{ secrets.ACCESS_TOKEN }}@github.com/${GITHUB_ACTOR}/${GITHUB_ACTOR}.imtqy.com.git" --branch master --single-branch ./output - name: Generate static pages run: pelican content -o output -s publishconf.py - name: Set git config and add changes run: | git config --global user.email "${GITHUB_ACTOR}@https://users.noreply.github.com/" git config --global user.name "${GITHUB_ACTOR}" git add --all working-directory: ./output - name: Push and send notification run: | COMMIT_MESSAGE="Update pages on $(date +'%Y-%m-%d %H:%M:%S')" git diff-index --quiet --cached HEAD -- && echo "No changes!" && exit 0 || echo $COMMIT_MESSAGE git commit -m "${COMMIT_MESSAGE}" git push https://${{ secrets.ACCESS_TOKEN }}@github.com/${GITHUB_ACTOR}/${GITHUB_ACTOR}.imtqy.com.git master curl "https://api.telegram.org/bot${{ secrets.BOT_TOKEN }}/sendMessage?text=$COMMIT_MESSAGE %0ALook at ${GITHUB_ACTOR}.imtqy.com %0ARepository%3A github.com/${GITHUB_ACTOR}/${GITHUB_ACTOR}.imtqy.com&chat_id=${{ secrets.ADMIN_ID }}" working-directory: ./output 

Captures d'écran


Le résultat de l'un des lancements affiché dans l'onglet Actions du référentiel avec les sources



Message du bot à propos de l'achèvement du script


Liens utiles


Aperçu des actions
Syntaxe des actions
Liste de déclencheurs
Variantes d'environnements virtuels
Pages Github
Liste des générateurs statiques

Source: https://habr.com/ru/post/fr474668/


All Articles