Créer une action GitHub personnalisée

Effectué

GitHub Actions est une fonctionnalité puissante qui vous aide à aller du code au cloud, le tout avec le confort et le côté pratique de votre propre dépôt. Ici, vous allez découvrir les différents types d’actions GitHub, ainsi que les métadonnées, la syntaxe et les commandes de workflow pour créer des actions GitHub personnalisées.

Types d’actions GitHub

Diagramme montrant les trois types d’actions GitHub ; actions Docker, actions JavaScript et actions d’étape d’exécution composites.

Les actions sont des tâches individuelles que vous pouvez utiliser pour personnaliser vos workflows de développement. Vous pouvez créer vos propres actions en écrivant du code personnalisé qui interagit avec votre dépôt pour effectuer des tâches personnalisées ou en utilisant des actions partagées par la communauté GitHub. En parcourant les différentes actions, vous pouvez noter qu’il existe trois types d’actions : les actions de conteneur Docker, les actions JavaScriptet les actions d’étape exécution composites. Examinons de plus près chaque type d’action :

Actions de conteneur Docker

Les conteneurs Docker empaquettent l’environnement avec le code GitHub Actions. Cela signifie que l’action s’exécute dans un environnement cohérent et fiable, car toutes ses dépendances se trouvent dans ce conteneur. Si l’action doit s’exécuter dans une configuration d’environnement spécifique, les conteneurs Docker sont un bon moyen de le faire, car vous pouvez personnaliser le système d’exploitation et les outils. L’inconvénient est que, étant donné que le travail doit créer et récupérer le conteneur, les actions du conteneur Docker sont souvent plus lentes que les actions JavaScript.

Avant de créer une action de conteneur Docker, vous devez avoir des connaissances de base sur la façon d’utiliser les variables d’environnement et le système de fichiers du conteneur Docker. Les étapes à suivre pour créer une action de conteneur Docker sont alors minimales et simples :

  1. Créez un Dockerfile pour définir les commandes permettant d’assembler l’image Docker.
  2. Créez un fichier de métadonnées action.yml pour définir les entrées et les sorties de l’action. Définissez la valeur de runs: using: sur docker et la valeur de runs: image: sur Dockerfile dans le fichier.
  3. Créez un fichier entrypoint.sh pour décrire l’image docker.
  4. Commitez et poussez (push) votre action dans GitHub avec les fichiers suivants : action.yml, entrypoint.sh, Dockerfile et README.md.

Actions JavaScript

Les actions JavaScript peuvent s’exécuter directement sur la machine de l’exécuteur et séparer le code de l’action de l’environnement qui est utilisé pour exécuter l’action. Pour cette raison, le code d’action est simplifié et peut s’exécuter plus rapidement que les actions au sein d’un conteneur Docker.

Comme prérequis à la création et à l’utilisation d’actions JavaScript empaquetées, vous devez télécharger Node.js, qui inclut npm. À titre d’étape facultative (mais que nous recommandons), vous pouvez utiliser GitHub Actions Toolkit Node.js, une collection de packages Node.js qui vous permet de créer rapidement des actions JavaScript avec davantage de cohérence.

Les étapes à suivre pour créer une action JavaScript sont alors minimales et simples :

  1. Créez un fichier de métadonnées action.yml pour définir les entrées et les sorties de l’action, et indiquez à l’exécuteur de l’action comment démarrer l’exécution de cette action JavaScript.
  2. Créez un fichier index.js avec les informations de contexte sur les packages Toolkit, le routage et d’autres fonctions de l’action.
  3. Commitez et poussez votre action dans GitHub avec les fichiers suivants : action.yml, index.js, node_modules, package.json, package-lock.json et README.md.

Actions d’étapes d’exécution composites

Les actions d’étapes d’exécution composites vous permettent de réutiliser des actions en utilisant des scripts de shell. Vous pouvez même combiner plusieurs langages de shell au sein de la même action. Si vous avez un grand nombre de scripts de shell pour automatiser plusieurs tâches, vous pouvez désormais les transformer facilement en action et les réutiliser pour différents workflows. Il est parfois plus facile d’écrire simplement un script de shell que d’utiliser JavaScript ou d’encapsuler votre code dans un conteneur Docker.

Métadonnées et syntaxe nécessaires pour créer une action

Lors de la création ou du passage en revue d’une action GitHub, une première étape importante est d’examiner le fichier action.yml pour évaluer les entrées, les sorties, la description, les exécutions et d’autres informations de configuration dont l’action a besoin. Certains de ces paramètres sont obligatoires, tandis que d’autres sont facultatifs. Le fichier action.yml définit les informations suivantes pour votre action :

Paramètre Description Obligatoire
Nom Nom de votre action. Permet d’identifier visuellement l’action dans un travail. Oui
Description Résumé de ce que fait votre action. Oui
Entrées Les paramètres d’entrée vous permettent de spécifier les données que l’action s’attend à utiliser lors de l’exécution. Ces paramètres deviennent des variables d’environnement dans l’exécuteur. non
Sorties Les paramètres de sortie vous permettent de spécifier les données que les actions suivantes peuvent utiliser ultérieurement dans le workflow après l’exécution de l’action qui définit ces sorties. non
Exécutions Commande à exécuter quand l’action s’exécute. Oui
Personnalisation Icône de couleur et Feather à utiliser pour créer un badge permettant de personnaliser et de distinguer votre action dans GitHub Marketplace. non

Entrées

Les entrées sont les paramètres qui vous permettent de spécifier les données que l’action s’attend à utiliser lors de son exécution. GitHub stocke ces paramètres d’entrée en tant que variables d’environnement.

Voici un exemple de liste d’entrées pour une action. L’entrée firstNameStudent est facultative, tandis que l’entrée studentGrade est obligatoire.

inputs:
  firstNameStudent:
    description: 'First name of student'
    required: false
    default: '1'
  studentGrade:
    description: 'Grade of the student'
    required: true

Sorties

Les sorties sont les paramètres qui vous permettent de déclarer des données. Gardez à l’esprit que les actions qui s’exécutent ultérieurement dans un workflow peuvent utiliser les données de sortie qui ont été déclarées dans une action exécutée précédemment.

L’exemple suivant est une sortie simple pour déclarer le niveau moyen des étudiants :

outputs:
  average:
    description: 'The average grade of the students'

Exécutions

Comme vous l’avez découvert précédemment, votre action doit avoir une instruction runs qui définit la commande nécessaire pour exécuter votre action. Selon la façon dont vous créez votre action, que vous utilisiez un conteneur Docker, JavaScript ou des étapes d’exécution composites, la syntaxe de runs est définie différemment.

runs pour les actions Docker

Les actions de conteneur Docker nécessitent que l’instruction runs configure l’image que l’action Docker utilise avec les arguments suivants :

  • using : doit être défini sur docker pour exécuter une action de conteneur Docker
  • image : image Docker utilisée comme conteneur pour exécuter l’action
runs:
  using: 'docker'
  image: 'Dockerfile'

runs pour les actions JavaScript

Les actions JavaScript nécessitent que l’instruction runs prenne les deux arguments suivants :

  • using : application utilisée pour exécuter le code tel que défini dans main
  • main : fichier qui contient le code de l’action ; l’application définie dans using exécute ce fichier

Par exemple, voici une instruction runs pour une action JavaScript qui utilise Node.js :

runs:
  using: 'node12'
  main: 'main.js'

runs pour les actions d’étapes d’exécution composites

Les actions d’étapes d’exécution composites nécessitent que l’instruction runs prenne les trois arguments suivants :

  • using : doit être défini sur "composite" pour exécuter une étape d’exécution composite
  • steps : étapes d’exécution pour exécuter l’action
  • steps[*].run : commande que vous voulez exécuter (peut être inline ou un script dans votre dépôt d’actions)

Par exemple, voici une instruction runs pour une action d’étapes d’exécution composites qui va exécuter le script du chemin de fichier /test/script/sh :

runs:
  using: "composite"
  steps:
    - run: ${{ github.action_path }}/test/script.sh
      shell: bash

Personnalisation

Une fonctionnalité facultative mais amusante est la possibilité de personnaliser le badge de votre action. Le badge s’affiche à côté du nom de l’action dans GitHub Marketplace. Vous pouvez utiliser une icône de couleur et Feather pour créer le badge. Pour la personnalisation, vous devez spécifier l’icône et la couleur que vous souhaitez utiliser.

branding:
  icon: 'shield'  
  color: 'blue'

Voici un exemple de badge pour l’action Checkout (Extraire) sur GitHub Marketplace :

Capture d’écran montrant la personnalisation d’une action sur GitHub Marketplace.

Commandes de workflow

La création d’un workflow est assez simple dès lors que vous pouvez trouver les actions appropriées pour vos étapes. Dans certains cas, il peut être nécessaire de créer vos propres actions pour obtenir les résultats souhaités, mais vous pouvez utiliser des commandes de workflow pour ajouter un autre niveau de personnalisation à vos workflows.

Les commandes de workflow vous permettent de communiquer avec la machine de l’exécuteur GitHub Actions en affichant des lignes de texte mises en forme sur la console. Vous pouvez utiliser ces commandes de workflow avec des commandes shell ou dans vos actions personnalisées. Les commandes de workflow sont pratiques, car elles vous permettent de partager des informations entre les étapes d’un workflow, d’afficher des messages de débogage ou d’erreur dans la console, de définir des variables d’environnement, de définir des paramètres de sortie ou de faire des ajouts au chemin système.

La plupart des commandes de workflow utilisent la commande echo dans le format spécifique ci-dessous, tandis que d’autres peuvent être appelées en écrivant dans un fichier :

echo "::workflow-command parameter1={data},parameter2={data}::{command value}"

Voici quelques exemples de journalisation des messages de base pour l’affichage d’un message de débogage, d’un message d’information, d’un message d’erreur ou d’un message d’avertissement sur la console :

- name: workflow commands logging messages
  run: |
    echo "::debug::This is a debug message"
    echo "This is an info message"
    echo "::error::This is an error message"
    echo "::warning::This is a warning message"

Vous pouvez également créer un message à enregistrer dans le journal avec un nom de fichier (file), un numéro de ligne (line) et un numéro de colonne (col) à l’endroit où l’erreur s’est produite. Les messages d’avertissement s’affichent en surbrillance jaune avec le texte « warning » (avertissement), et les messages d’erreur s’affichent en surbrillance rouge avec le texte « error » (erreur).

echo "::error file=app.js,line=10,col=15::Something went wrong"

Il est important de noter que ces commandes de workflow doivent se trouver sur une seule ligne. Les caractères qui interfèrent avec l’analyse, comme les virgules et les sauts de ligne, doivent être encodés au format URL.

Par exemple, le texte ci-dessous est un message multiligne :

This text spans
across multiple lines

Ce message doit être encodé comme ci-dessous :

This text spans%0Aacross multiple lines

En plus des commandes de workflow, vous pouvez définir des codes de sortie pour définir l’état d’une action. C’est important car, quand vous utilisez des travaux dans un workflow, un code de sortie en échec va arrêter toutes les actions simultanées et annuler toutes les actions ultérieures. Si vous créez une action JavaScript, vous pouvez utiliser le package @actions/core du kit de ressources d’actions pour consigner un message et définir un code de sortie d’échec. Si vous créez une action de conteneur Docker, vous pouvez définir un code de sortie d’échec dans votre script entrypoint.sh.