Guide · SaaS & dev

GitHub Actions pour un SaaS : CI et secrets

Workflow Node.js officiel, secrets et environnements. Versions d’actions lues le 2026-10-18, à recopier si la page a bougé. Runs non rejoués.

Un workflow GitHub Actions pour un SaaS, dans la doc relue le 2026-10-18, est un fichier YAML sous .github/workflows. Il construit et teste. Il ne déploie vers un hébergeur précis que si vous ajoutez un job que cette page ne fournit pas. Les guides officiels couvrent le modèle Node.js, les secrets, et les environnements. Aucun de ces workflows n’a été lancé ici. Les commandes n’ont pas été rejouées le 2026-10-18. Il n’y a pas de capture : les pages d’aide en ont, cet article non.

Créer le workflow Node.js

Source : Building and testing Node.js.

La page demande de connaître Node.js, YAML, et la création d’un fichier de workflow. Le raccourci est le modèle, pas un YAML écrit de mémoire.

  1. Ouvrez la page principale du dépôt.
  2. Onglet Actions.
  3. S’il existe déjà un workflow, New workflow.
  4. Cherchez Node.js.
  5. Filtrez par Continuous integration.
  6. Sur le workflow Node.js, Configure.
  7. Modifiez, par exemple les versions de Node.
  8. Commit changes.

Le fichier ajouté s’appelle node.js.yml, dans .github/workflows. La page relue ne donne pas de texte de secours si le modèle est absent. Ne collez pas un YAML d’un vieux miroir Enterprise à la place.

Versions vues le 2026-10-18

L’exemple à une seule version, sur la page extraite ce jour-là, enchaîne actions/checkout@v6, actions/setup-node@v4, Node 20.x, npm ci, npm run build --if-present, npm test. Les autres blocs YAML de cette même extraction utilisaient aussi setup-node@v4. Ouvrez la page et copiez les versions qu’elle affiche le jour où vous commitez. Celles ci-dessous sont celles de l’extrait du 2026-10-18.

name: Node.js CI
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: Use Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20.x'
      - run: npm ci
      - run: npm run build --if-present
      - run: npm test

setup-node met le binaire sur le PATH pour le reste du job. Sur un runner auto-hébergé, la page dit d’installer Node vous-même et de l’ajouter au PATH. Le x de 20.x est un joker vers le dernier correctif de cette majeure. Sans version, GitHub prend le Node par défaut de l’image. La page renvoie à la liste des logiciels des runners hébergés pour ce défaut. Nous ne l’avons pas rouverte.

Résultat attendu : après le commit, un push déclenche le workflow, parce que l’exemple est on: [push]. La page décrit un graphe de run et des journaux. Elle ne donne pas une ligne de log à chercher. Nous n’avons pas poussé ce fichier le 2026-10-18, donc aucun crochet vert n’est affirmé ici.

Erreur fréquente : npm ci sans package-lock.json ni npm-shrinkwrap.json. La page dit que npm ci installe ces fichiers de gel et refuse de les modifier. npm install installe depuis package.json et peut faire bouger le gel. Pour un SaaS, gardez la commande qui correspond au gel commité.

Le même tutoriel a un exemple Yarn (yarn --frozen-lockfile) et un exemple pnpm. L’exemple pnpm relu épinglait pnpm/action-setup sur le commit 0609f0983b7a228f052f81ef4c3d6510cae254ad, version 6.10.0, et prévenait que l’action n’est pas certifiée par GitHub. Ne recopiez pas cette épingle depuis cet article. Si le dépôt a un pnpm-lock.yaml, retournez sur la page et prenez l’exemple pnpm du jour. Ne mélangez pas npm ci avec ce gel.

Secrets

Source : Using secrets in GitHub Actions.

Pour créer un secret de dépôt : accès write si le dépôt est dans une organisation, collaborateur si c’est un compte personnel.

  1. Page principale du dépôt.
  2. Settings. Si l’onglet est caché, menu puis Settings.
  3. Security, Secrets and variables, Actions.
  4. Onglet Secrets.
  5. New repository secret.
  6. Name, Secret, Add secret.

En ligne de commande, la page donne :

gh secret set SECRET_NAME

La CLI demande la valeur. Depuis un fichier : gh secret set SECRET_NAME < secret.txt. Liste : gh secret list. Nous n’avons pas exécuté gh le 2026-10-18. Ne redirigez pas un fichier qui contient autre chose que la valeur.

Dans le workflow, le contexte est secrets. La page montre un input super_secret: ${{ secrets.SuperSecret }} ou la même expression dans env. Un secret absent devient une chaîne vide. On ne peut pas le tester directement dans un if:. La page dit de le poser en variable d’environnement du job, puis de tester cette variable.

Les secrets ne sont pas passés au runner quand le workflow part d’une fourche, sauf GITHUB_TOKEN. Ils ne sont pas injectés tout seuls dans un workflow réutilisable. Ils ne sont pas disponibles pour les événements Dependabot. La page le dit et renvoie vers les dépannages correspondants.

Ne passez pas un secret en argument de ligne de commande si la variable d’environnement suffit. ps et les audits de processus peuvent voir la ligne. En bash, la page quote ainsi : example-command "$SUPER_SECRET", avec le secret dans env.

Au-delà de 48 Ko, la page décrit un contournement gpg et prévient que GitHub ne masque pas ces valeurs dans les journaux. Ce guide ne recopie pas ce contournement. Pour un SaaS, une clé de cloud longue durée est souvent le mauvais objet : la même page dit de préférer OpenID Connect quand le fournisseur le permet, et lie le guide de durcissement OIDC. Nous n’avons pas déroulé ce guide le 2026-10-18.

Les secrets d’organisation ne sont pas accessibles aux dépôts privés sur GitHub Free, dit la note. Si le SaaS est dans un dépôt privé et que le secret doit y entrer, créez-le au niveau du dépôt ou de l’environnement, ou vérifiez cette limite avant de compter sur le secret d’organisation.

Environnements

Créer un environnement : propriétaire du dépôt personnel, ou admin sur un dépôt d’organisation. Source : Managing environments for deployment.

Les comptes GitHub Free ne configurent les environnements que pour les dépôts publics, dit la note de prérequis. Passer le dépôt en privé ignore les règles de protection et les secrets d’environnement déjà posés. Si le dépôt redevient public, ces règles et ces secrets sont de nouveau disponibles. Organisations Team et comptes Pro peuvent en configurer sur un dépôt privé. La page renvoie vers la documentation des formules GitHub pour le détail de cette limite.

  1. Settings, Environments, New environment.
  2. Nom, puis Configure environment. Pas sensible à la casse. 255 caractères maximum. Unique dans le dépôt.
  3. Règles optionnelles : required reviewers (jusqu’à 6 personnes ou équipes, une seule approbation suffit), prevent self-review, wait timer en minutes, branches et tags autorisés.
  4. Environment secrets : Add Secret. Le job n’y accède qu’après les règles de protection.

Un workflow qui cite un environnement inexistant le crée, sans règles et sans secrets, sauf le cas des pages builds implicites. Toute personne qui peut éditer les workflows peut donc créer un environnement par un fichier. Seuls les admins le configurent. Un nom production tapé dans le YAML n’est pas un environnement protégé tant qu’un admin n’a pas posé les règles.

Supprimer l’environnement supprime ses secrets et ses règles. Les jobs en attente à cause de ces règles échouent.

Référence dans le job, page Deploying with GitHub Actions. Pour grouper des secrets de test sans écrire un déploiement dans l’historique :

jobs:
  test:
    runs-on: ubuntu-latest
    environment:
      name: staging
      deployment: false
    steps:
      - name: run tests
        env:
          API_KEY: ${{ secrets.API_KEY }}
        run: echo "Running tests with staging secrets"

deployment: false laisse l’accès aux secrets et aux variables, n’écrit pas d’objet deployment, et laisse passer le wait timer et les reviewers. Une règle de protection custom, via une GitHub App, fait échouer le job : ces règles ont besoin d’un objet deployment. La page dit que ces règles custom sont en préversion publique et peuvent changer.

Le echo de l’exemple n’imprime pas la clé. N’ajoutez pas un echo de API_KEY pour « vérifier ». La page sur les gros secrets montre un cat d’exemple et dit de retirer ce pas en production, parce que le contournement n’est pas masqué. Pour un secret normal, GitHub masque la valeur s’il la reconnaît. Ne comptez pas là-dessus pour un secret que vous auriez écrit vous-même dans la commande.

Un job qui référence un environnement avec reviewers reste Waiting jusqu’à approbation. Sans approbation sous 30 jours, il échoue. C’est écrit sur la page de déploiement.

Pour qu’un seul déploiement de production tourne à la fois, la même page pose concurrency: production au workflow ou au job, et environment: production. concurrency et environment ne sont pas liés : un autre workflow peut utiliser l’environnement sans être dans le groupe. cancel-in-progress: true annule le run en cours du groupe. Nous n’avons pas observé de file d’attente.

Secret limité à l’environnement, CLI :

gh secret set --env ENV_NAME SECRET_NAME

Liste : gh secret list --env ENV_NAME. Il faut que l’environnement existe. Nous ne l’avons pas créé.

Ce que ce workflow ne déploie pas

Le tutoriel Node.js s’arrête à build et test, puis pointe vers la publication de paquets si les tests passent. La page de déploiement dit que GitHub a des modèles pour plusieurs hébergeurs, et un marketplace. Elle ne choisit pas l’hébergeur du SaaS. Copier un modèle Azure parce qu’il est cité en exemple serait un autre guide. Les runners hébergés sortent d’une plage d’adresses large. Si la production n’accepte pas ce trafic, la page dit d’utiliser des runners auto-hébergés. Nous n’avons pas testé cette contrainte.

Sources et limites

Les commandes n’ont pas été rejouées le 2026-10-18. Si la page Node.js affiche d’autres numéros d’actions que v6 et v4, ce sont les siens qui comptent.