Skip to main content

Extension VS Code : créer une CI/CD automatisée avec GitHub Actions

Écrit par
Headshot of Shai Mendel

Shai Mendel

6 avril 2020

0 minutes de lecture

Voyons comment créer un pipeline CI/CD complet pour une extension VS Code avec GitHub Actions.

Mon exigence de départ était de mettre en place une CI/CD automatisée qui me permette d’effectuer les opérations suivantes à chaque envoi d’un nouveau commit sur la branche master :

  • Tester : exécuter les tests sur Mac, Windows et Linux.

  • Publier une release : créer une nouvelle release GitHub avec des notes de version générées automatiquement selon les conventions de messages de commit Angular.

  • Publier : publier la nouvelle version sur la marketplace Visual Studio.

Dernier point : je voulais tout faire uniquement avec GitHub Actions :) Je n’ai donc besoin que du dépôt GitHub pour tout configurer et exécuter.

Motivation

Tout a commencé lorsque j’ai voulu écrire une petite extension VS Code qui me permettrait de cliquer avec le bouton droit sur un fichier YAML pour l’appliquer à mon cluster Kubernetes local ou l’en supprimer.

Très vite, j’ai compris que la documentation de VS Code sur la création d’extensions était vraiment de bonne qualité. J’ai rapidement écrit et débogué localement ma nouvelle extension TypeScript, puis je me suis rendu compte que le processus CI/CD complet recommandé par Microsoft dans sa documentation était un peu insuffisant :

Tests

Cette partie est plutôt bien couverte dans la documentation officielle : elle mentionne notamment une Action GitHub qui exécute les tests sur Mac, Windows et Linux, que j’ai bien sûr utilisée.

Release et publication

L’ensemble du processus de release et de publication repose sur l’outil vsce. Pour commencer, suivez la documentation sur la publication et effectuez notamment les opérations suivantes :

Une fois ces étapes effectuées, vous pouvez empaqueter, publier et dépublier votre extension avec vsce. Ce sont des opérations manuelles à effectuer, ce qui est loin d’être idéal !

De plus, la définition de la version de l’extension au moment de la publication présente aussi une lacune. Il existe plusieurs façons de procéder :

  • modifier le champ version dans package.json et exécuter vsce publish

  • utiliser par exemple vsce publish minor (ou major/patch, selon le cas) pour incrémenter automatiquement la version

  • utiliser vsce publish 2.0.1 pour spécifier une version précise

Ce n’est vraiment pas pratique. Je veux que la version soit définie automatiquement selon mes conventions de commit, et que les notes de version soient générées automatiquement. Petit aparté : je vais utiliser semantic-release pour cela. :)

C’est parti ! Je vais reprendre les étapes que j’ai suivies et nous allons créer notre pipeline CI/CD étape par étape.

Créer une extension

J’ai suivi la documentation officielle et créé assez facilement un nouveau dépôt contenant mon extension TypeScript générée à partir d’un modèle. J’ai ensuite modifié son fonctionnement pour qu’un clic droit sur un fichier YAML permette de l’appliquer à mon cluster Kubernetes local ou de l’en supprimer. Très pratique et utile pour moi !

Créer un workflow GitHub Actions vide

Créez un fichier YAML vide à l’emplacement .github/workflows/<workflow name>.yaml. Je l’ai appelé ci.yaml.

Indiquer que le workflow doit s’exécuter à chaque push sur master

Modifiez votre workflow YAML comme suit :

on:
  push:
    branches:
      - master

jobs:
< to be filled with jobs>

Le paragraphe du haut indique à GitHub d’exécuter cette action lors d’un push sur master. La partie du bas correspond aux tâches à exécuter (nous allons bientôt les compléter).

Tests automatisés

Comme je l’ai indiqué plus haut, je souhaite que les tests s’exécutent sur Mac, Windows et Linux. La documentation mentionne justement une action que je vais utiliser en ajoutant une tâche dédiée :

  test:
    name: Test
    strategy:
      matrix:
        os: [macos-latest, ubuntu-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Setup Node.js
        uses: actions/setup-node@v1
        with:
          node-version: 12
      - name: Install dependencies
        run: npm install
      - name: Run headless test
        uses: GabrielBB/xvfb-action@v1.0
        with:
          run: npm test

Comme vous pouvez le constater, cela ajoute une tâche appelée Test, qui s’exécutera sur Mac, Windows et Ubuntu. Cette tâche comprend 4 étapes :

  • Récupération du code : utiliser l’action intégrée pour récupérer le dépôt

  • Configuration de Node.js : utiliser l’action intégrée pour installer Node 12

  • Installation des dépendances : exécuter npm install

  • Exécution des tests sans interface graphique : exécuter les tests avec l’action GabrielBB/xvfb-action@v1.0, comme le recommande la documentation officielle (avec quelques améliorations)

Après cette étape, j’ai vu ceci dans l’onglet Actions :

Workflow GitHub Actions pour ci.yaml déclenché lors d’un push, affichant des tests réussis sur macOS, Ubuntu et Windows.

chaque test comportait les étapes suivantes :

Liste des étapes du workflow : configurer le job, récupérer le code, configurer Node.js, installer les dépendances, exécuter les tests sans interface graphique, effectuer les opérations post-récupération et terminer le job

Publication et release

Ajoutons une nouvelle étape, qui se présente comme suit :

  publish:
    name: Release and publish
    needs: test
    runs-on: ubuntu-18.04
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Setup Node.js
        uses: actions/setup-node@v1
        with:
          node-version: 12
      - name: Install dependencies
        run: npm install
      - name: Release
        env:
          GITHUB_TOKEN: ${{ secrets.PERSONAL_GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
        run: npx semantic-release
      - name: Vscode release plugin
        uses: JCofman/vscodeaction@master
        env:
          PUBLISHER_TOKEN: ${{ secrets.PUBLISHER_TOKEN }}
        with:
          args: publish -p $PUBLISHER_TOKEN 

Nous allons la parcourir tranquillement, ne vous inquiétez pas !

Nous commençons donc par les étapes précédentes : récupérer le code, configurer Node 12 et exécuter npm install. Les deux étapes suivantes sont les plus importantes et méritent chacune leur propre section.

Release

L’objectif est ici de créer et publier une nouvelle release GitHub avec des notes de version adaptées. Pour cela, j’exécute simplement semantic-release :) Cette action analyse les messages de commit, génère les notes de version et crée une nouvelle release GitHub avec une version semver correspondant aux commits que j’ai ajoutés. Elle définit également cette version dans package.json, ce qui sera utile à l’étape suivante.

Pour configurer correctement semantic-release, vous devez :

  • transmettre la variable d’environnement GITHUB_TOKEN (en tant que secret GitHub) : votre jeton GitHub personnel, avec le minimum d’autorisations repo

    Liste des autorisations du dépôt présentant les options d’accès aux dépôts privés, aux statuts de commit, aux déploiements, aux dépôts publics et aux invitations.

  • transmettre la variable d’environnement NPM_TOKEN (en tant que secret GitHub) : votre jeton npm pour publier votre paquet npm. Dans mon cas, je ne voulais pas publier de paquet npm. Pour cela, vous devez configurer "private": true dans votre package.json. Vous n’aurez alors plus besoin de transmettre cette variable d’environnement (j’ai trouvé cette information ici)

  • installer @semantic-release/github comme dépendance de développement

  • ajouter la configuration suivante dans votre package.json :

    "release": {"branches": "master","verifyConditions": ,"publish": ,"success": ,"fail": },

Une fois cette étape terminée, j’ai commencé à voir apparaître de véritables releases GitHub :

Page de publication affichant la version 1.1.1, datée du 03/04/2020, avec une liste de corrections de bugs et des liens vers les commits.

Publication

L’objectif est ici de téléverser une nouvelle version de l’extension sur la marketplace VS Code, avec le bon numéro de version. L’un des avantages de la section Release précédente, c’est que package.json contient désormais la bonne version du paquet. Il ne reste plus qu’à exécuter vsce publish -p <my token>.

J’ai trouvé une action GitHub existante pour publier une extension : JCofman/vscodeaction. Il vous suffit de transmettre votre PUBLISHER_TOKEN en tant que variable d’environnement (là encore, avec les secrets GitHub).

Après cette étape, vous verrez une nouvelle tâche Release and publish dans l’onglet Actions, qui contient

Workflow GitHub Actions affichant la réussite d’une tâche « Release and publish », avec les étapes de compilation, de publication de la version et de déploiement terminées

Résultat

Page de l’extension VS Code pour Kubernetes Apply, présentant des options permettant d’appliquer et de supprimer des fichiers de ressources YAML avec kubectl.

Vous pouvez maintenant trouver ma nouvelle extension sur la marketplace et dans la recherche d’extensions de VS Code !

Mon dépôt est disponible à l’adresse https://github.com/shaimendel/vscode-plugin-cicd-github-actions, avec le workflow configuré dans [ci.yaml].

Résumé

Nous venons de créer une CI/CD entièrement automatisée pour une nouvelle extension VS Code. Chaque fois qu’une nouvelle PR est fusionnée dans master, nous :

  • testons le code sur plusieurs systèmes d’exploitation

  • publions une nouvelle release GitHub avec des notes de version très soignées

  • publions une nouvelle extension sur la marketplace

Et nous avons tout fait uniquement avec GitHub Actions ! Pari réussi. : )

Page GitHub Actions montrant que toutes les vérifications ont réussi, avec des tests réussis sur macOS, Ubuntu et Windows, ainsi qu’un workflow de publication d’une version.

Lancez-vous dans les compétitions Capture The Flag

Apprenez à résoudre des défis Capture The Flag en regardant à la demande notre atelier virtuel d’initiation.

Publié dans: