Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
52 changes: 52 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,37 @@ jobs:
- name: go vet
run: go vet ./...

# Le jeu de règles de .golangci.yml est VERT, et c'est ce qui le rend
# utile ici : il n'échoue que sur ce qu'on vient d'écrire. Ce qu'il
# n'active pas est écrit dans ce fichier, avec le compte relevé et la
# raison — `make audit` le rejoue à la demande, et ne tourne pas ici.
#
# `go install` plutôt que golangci/golangci-lint-action, et c'est un choix :
# toutes les actions de ce fichier sont épinglées par SHA, et ajouter une
# action de plus voudrait dire relever puis maintenir un SHA de plus.
#
# La VERSION n'est pas écrite ici : elle est lue dans le Makefile, qui en
# est la source unique. Écrite aux deux endroits, elle finit par diverger,
# et un développeur verrait alors rouge là où la CI voit vert — ou
# l'inverse, ce qui est pire, parce que personne ne cherche la cause d'un
# vert.
#
# L'installation se fait dans un répertoire jetable pour que le module
# courant n'en garde AUCUNE trace : `make deps` compare go.mod aux deux
# tables de §17.1 dans les deux sens (ADR-039), et une dépendance de
# développement qui s'y inscrirait ouvrirait un écart permanent.
#
# Puis c'est `make lint` qui est appelé, et non la commande recopiée : si
# la cible change, la CI suit. C'est le principe que pose l'en-tête de
# make.ps1 — « le Makefile reste la référence, c'est lui que la CI
# exécute » — et une étape qui porte son nom sans l'exécuter le trahit.
- name: make lint
run: |
version=$(make -s golangci-version)
(cd "$(mktemp -d)" && go mod init lintinstall >/dev/null 2>&1 \
&& go install "github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$version")
make lint

- name: make boundary
run: go run ./tools/boundary

Expand Down Expand Up @@ -268,6 +299,27 @@ jobs:
working-directory: web
run: npm ci

# AVANT `svelte-check`, et l'ordre porte une intention : ces deux-là lisent le code
# sans rien exécuter, ils répondent en quelques secondes, et ce qu'ils reprochent se
# corrige sans réfléchir. Les faire passer en premier évite d'attendre une suite de
# mille tests pour apprendre qu'il manque une accolade de style.
#
# `npm run lint` ne double PAS `npm run check` : svelte-check ne vérifie que des
# TYPES. Une promesse qu'on oublie d'attendre, un `${}` posé sur un objet qui rendra
# « [object Object] » à un bénévole, un fichier qui enfle — rien de tout cela n'est
# une erreur de type, et rien ne le regardait avant ce jeu de règles.
- name: eslint
working-directory: web
run: npm run lint

# Prettier arrive sur un dépôt écrit à la main : les 55 fichiers qui ne suivent pas
# encore sa mise en forme sont nommés un par un dans `web/.prettierignore`, avec la
# raison. C'est un CLIQUET — tout fichier écrit à partir d'aujourd'hui est vérifié,
# et la liste se vide fichier par fichier sans qu'un lot ait à s'arrêter pour ça.
- name: prettier
working-directory: web
run: npm run format:check

- name: svelte-check
working-directory: web
run: npm run check
Expand Down
101 changes: 101 additions & 0 deletions .golangci-audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Configuration de golangci-lint pour OpenScale — cible `make audit`, NON BLOQUANTE.
#
# Elle active large et ne fait échouer personne. Sa raison d'être est de RENDRE
# VISIBLE ce que `.golangci.yml` écarte : le jeu bloquant est vert parce qu'il
# ne contient que ce qui tient aujourd'hui, et un dépôt où l'on ne verrait plus
# jamais le reste finirait par croire qu'il n'y a plus rien à faire.
#
# Elle ne tourne PAS dans l'intégration continue. Elle se lance à la main, quand
# on ouvre un lot de qualité, et son relevé sert à le dimensionner.
#
# Les raisons pour lesquelles chacun de ces linters n'est pas bloquant sont
# écrites dans `.golangci.yml`, avec le compte relevé. Ne les dupliquez pas ici :
# deux listes finissent toujours par diverger.

version: "2"

# SANS CE BLOC, LA CIBLE D'INVENTAIRE MENT — et c'est exactement ce qu'elle est
# censée éviter. golangci-lint tronque par défaut à 3 signalements identiques et
# 50 par linter : cette configuration rendait 136 signalements de production là
# où il y en a 432, et les comptes qu'on en tirait étaient faux d'un facteur 10
# sur errcheck. Une cible dont le rôle est de MONTRER la dette ne peut pas être
# celle qui la sous-estime.
issues:
max-issues-per-linter: 0
max-same-issues: 0
# golangci-lint ne rend QU'UN signalement par ligne par défaut. Quand gocognit
# et funlen visent la même fonction, un seul sort — et lequel dépend de
# l'ordre, pas du fond. Un inventaire ne peut pas se permettre ça : c'est ce
# qui faisait dire que funlen ne voyait que deux fonctions alors qu'il en voit
# neuf dès que gocognit se tait sur la même ligne.
uniq-by-line: false

run:
timeout: 15m
tests: true

linters:
default: none
enable:
# Le socle Go, que le jeu bloquant ne peut pas encore porter
- errcheck
- staticcheck
- unused

# Ce qui mesure ce qu'un corps de fonction est devenu
- gocognit
- funlen
- nestif
- cyclop

# Sécurité et exhaustivité
- gosec
- exhaustive

# Fautes probables
- bodyclose
- errorlint
- nilerr
- noctx
- errname
- predeclared

# Style et conventions
- revive
- gocritic
- goconst
- unparam
- prealloc
- unconvert
- usestdlibvars
- wastedassign
- whitespace
- copyloopvar
- ineffassign
- govet

settings:
cyclop:
max-complexity: 15
funlen:
lines: 80
statements: 50
gocognit:
min-complexity: 25
nestif:
min-complexity: 5
goconst:
min-len: 4
min-occurrences: 4

exclusions:
generated: lax
paths:
- web/node_modules

formatters:
enable:
- gofmt
exclusions:
paths:
- web/node_modules
Loading