|
| 1 | +# Workflow `lint` |
| 2 | + |
| 3 | +🌍 🇫🇷 Français (ce fichier) · 🇬🇧 [English](lint.en.md) |
| 4 | + |
| 5 | +> Documentation mainteneur — fait partie de la [référence des workflows](README.fr.md). |
| 6 | +> Ne fait pas partie de la documentation utilisateur sous `doc/`. |
| 7 | +
|
| 8 | +**Fichier du workflow :** [`.github/workflows/lint.yml`](../../../../.github/workflows/lint.yml) |
| 9 | + |
| 10 | +## À quoi il sert |
| 11 | + |
| 12 | +Il analyse statiquement les fichiers que le compilateur C# ne voit jamais : les |
| 13 | +scripts shell POSIX sous `tools/` et `.claude/hooks/`, et les définitions de |
| 14 | +workflow de `.github/workflows/` elles-mêmes. |
| 15 | + |
| 16 | +Toute autre analyse de ce dépôt tourne **dans une compilation** — les analyseurs |
| 17 | +Roslyn, la règle du type explicite redite dans `.editorconfig` par l'ADR-0055, le |
| 18 | +ratchet de warnings de `Directory.Build.props` — si bien qu'un contributeur la |
| 19 | +rencontre au moment où il écrit le code. Le shell et le YAML n'avaient pas ce |
| 20 | +moment. La seule chose qui les lisait était l'analyse [`sonar`](sonar.fr.md), qui |
| 21 | +rapporte **après** le merge et n'applique rien : son job est vert dès que |
| 22 | +l'analyse est téléversée, quoi que dise le Quality Gate. Deux constats typés |
| 23 | +VULNERABILITY ont atteint `main` par ce chemin, et 21 constats shell s'y sont |
| 24 | +accumulés sans être vus. |
| 25 | + |
| 26 | +Ce workflow referme ce trou avec des outils qui tournent sur nos propres |
| 27 | +*runners* : le signal arrive avant le merge et ne dépend pas de la disponibilité |
| 28 | +d'un service tiers. |
| 29 | + |
| 30 | +## Quand il tourne |
| 31 | + |
| 32 | +- À chaque **push sur `main`**. |
| 33 | +- À chaque **pull request visant `main`**. |
| 34 | +- À la demande via **`workflow_dispatch`**. |
| 35 | + |
| 36 | +## Comment il tourne |
| 37 | + |
| 38 | +Un job, `Lint scripts and workflows`, sous Linux : |
| 39 | + |
| 40 | +1. **shellcheck** sur chaque `*.sh` du dépôt. Il est préinstallé sur l'image du |
| 41 | + *runner* : rien à télécharger, aucune action tierce dans la chaîne |
| 42 | + d'approvisionnement. |
| 43 | +2. **actionlint** sur `.github/workflows/`. Il vérifie ce que le YAML seul ne |
| 44 | + peut pas : le typage des expressions `${{ }}`, les entrées d'actions face au |
| 45 | + schéma de chaque action, les références `needs` et matrice, la syntaxe cron |
| 46 | + et — via un shellcheck embarqué — le shell de chaque bloc `run:`. |
| 47 | + |
| 48 | +## Permissions & sécurité |
| 49 | + |
| 50 | +`contents: read`, déclaré **sur le job** plutôt qu'au niveau du workflow, pour |
| 51 | +qu'un job ajouté plus tard n'hérite de rien qu'il n'ait demandé (c'est la règle |
| 52 | +Sonar `githubactions:S8264`, et la raison pour laquelle les deux workflows de |
| 53 | +mutation ont été modifiés de la même façon). |
| 54 | + |
| 55 | +actionlint est récupéré comme **archive de version épinglée et vérifiée par |
| 56 | +SHA-256**, et non exécuté via une action tierce : une action non épinglée est |
| 57 | +précisément ce que le contrôle Pinned-Dependencies d'OpenSSF Scorecard retient |
| 58 | +contre ce dépôt. La version et l'empreinte se suivent dans le workflow et se |
| 59 | +mettent à jour ensemble. |
| 60 | + |
| 61 | +## À manier avec précaution |
| 62 | + |
| 63 | +- **La barre est à zéro constat, `info` compris.** L'arbre est propre à cette |
| 64 | + barre : tout nouveau constat est donc réellement nouveau. Une barre plus basse |
| 65 | + laisserait les `info` s'accumuler exactement comme dans le rapport Sonar — ce |
| 66 | + que ce workflow existe pour empêcher, non pour reproduire. |
| 67 | +- **Les faux positifs sont annotés sur place, jamais désactivés globalement.** |
| 68 | + Trois motifs sont tus par un `# shellcheck disable=` en ligne portant sa |
| 69 | + raison : `SC2016` là où un format `printf` contient des *backticks* Markdown |
| 70 | + (lus comme une substitution de commande), et `SC2317` sur les deux fonctions de |
| 71 | + *hook* atteintes par la répartition `"rule_${rule}"` que shellcheck ne sait pas |
| 72 | + suivre. Un `.shellcheckrc` à l'échelle du dépôt aveuglerait ces règles partout, |
| 73 | + y compris là où elles ont raison. |
| 74 | +- **Les scripts sont en `#!/bin/sh`, et shellcheck applique le dialecte POSIX.** |
| 75 | + C'est délibéré : `local`, les tableaux et `[[` ne sont pas disponibles sur les |
| 76 | + shells qui les exécutent, et les règles POSIX auxquelles ces scripts sont tenus |
| 77 | + sont une décision consignée (ADR-0060). |
| 78 | +- **actionlint audite la correction, pas la posture de sécurité.** Il ne signale |
| 79 | + ni permissions trop larges, ni vérification d'acteur usurpable, ni déclencheur |
| 80 | + dangereux — la classe même qui a produit les deux constats VULNERABILITY de ce |
| 81 | + dépôt. Un auditeur dédié (`zizmor`) couvre cela et relève d'une décision à |
| 82 | + part, que ce workflow ne fournit pas en douce. |
| 83 | +- **Ce contrôle ne sert que s'il est requis.** Comme les autres contrôles de |
| 84 | + qualité, il ne bloque un merge que si la protection de branche de `main` le |
| 85 | + marque **required**. |
| 86 | + |
| 87 | +## Voir aussi |
| 88 | + |
| 89 | +- [`sonar`](sonar.fr.md) — l'analyse que ce workflow ramène en amont. Elle reste |
| 90 | + la vue de rapport et de couverture ; elle n'est pas, et n'a jamais été, un |
| 91 | + garde-fou. |
| 92 | +- [`ci`](ci.fr.md) — là où le ratchet de warnings applique la barre équivalente |
| 93 | + côté C#. |
0 commit comments