Standard di qualità¶
Questa pagina è l'asticella che una modifica deve superare per entrare, e l'elenco di ciò che la controlla al
posto della memoria di una persona. Se vuoi solo i comandi: lancia composer qa prima di aprire una pull
request; il resto della pagina spiega che cosa protegge ogni controllo e che cosa resta volutamente alla
revisione umana.
L'asticella¶
Sette regole, nell'ordine in cui di solito si infrangono.
| # | Regola | Chi la controlla |
|---|---|---|
| Q1 | La suite è verde su ogni combinazione supportata — PHP 8.3 e 8.4, Laravel 12 e 13, dipendenze più vecchie e più nuove, SQLite e MySQL | CI (tests, prefer-lowest, mysql) |
| Q2 | Una correzione porta con sé un test che senza di lei fallisce; una funzione porta il test del comportamento che promette | la revisione |
| Q3 | Zero differenze per Pint e zero errori PHPStan al livello 5, senza baseline | composer lint, CI (lint) |
| Q4 | Ogni stringa visibile è tradotta in en e in it, e non nomina mai un agente: :agent, mai «Claude» |
TranslationsTest, DocsTranslationsTest |
| Q5 | La documentazione arriva nello stesso commit, in entrambe le lingue, e le pagine di reference generate corrispondono al codice | composer docs:check, CI, DocsGenerateTest |
| Q6 | Ogni modifica ha una voce in CHANGELOG.md sotto Unreleased |
la revisione, il template di PR |
| Q7 | Nessuna dipendenza con vulnerabilità note, e nessuna dipendenza aggiunta senza una ragione scritta nella pull request | CI (security), la revisione |
Q2 e Q6 sono le due che una macchina non può giudicare: per questo sono le due che il template di pull request ti chiede di confermare a mano.
I controlli che puoi lanciare¶
composer qa # lint + test + docs:check — quello che fa la CI, nello stesso ordine
composer lint # Pint --test, poi PHPStan livello 5 su src/
composer format # applica lo stile invece di segnalarlo
composer test # la suite PHPUnit via Testbench, SQLite in memoria
composer test:coverage # la suite più il rapporto di copertura (serve pcov o xdebug)
composer docs:check # le pagine di reference generate corrispondono ancora al codice
composer docs:build # il sito bilingue, con i warning trattati come errori (serve MkDocs)
A composer qa bastano PHP e Composer, ed è per questo che è lui il cancello: la build stretta del sito è un
comando a parte perché richiede la catena Python di Costruire questo sito. Lancia la suite
dove nessuna variabile DB_* punta a un database vivo — la guida allo
sviluppo spiega la guardia che lo impedisce, e
perché esiste.
Che cosa gira su GitHub¶
Tutto quello che segue gira su ogni pull request e su ogni push su master
(tests.yml). Un'esecuzione
superata da un nuovo push sullo stesso branch viene annullata; su master non viene mai annullata, così ogni
commit del branch principale conserva il suo verdetto. Il token del workflow è di sola lettura.
| Job | Che cosa protegge | In locale |
|---|---|---|
PHP × Laravel (4 job) |
la matrice supportata, e le pagine generate | composer test, composer docs:check |
prefer-lowest |
il limite inferiore di ogni vincolo — la versione che un'applicazione prudente installa davvero | composer update --prefer-lowest --prefer-stable && composer test |
lint |
stile e analisi statica | composer lint |
mysql |
le query che SQLite perdona e MySQL 8 no | GRIGLIA_TEST_DB=mysql … composer test |
security |
vulnerabilità note nell'albero delle dipendenze | composer audit |
docs.yml pubblica il sito su
GitHub Pages a ogni push su master che tocca la documentazione. Costruisce con --strict, quindi un link
rotto fa fallire la pubblicazione invece di finire online.
Politica sull'analisi statica¶
PHPStan gira al livello 5 su src/, con Larastan, e senza baseline. Una baseline nasconde il debito
esistente dietro una spunta verde e cresce in silenzio; l'alternativa è la piccola lista di eccezioni in
phpstan-ignores.neon, ed è scomoda apposta:
- ogni voce è vincolata a un identificatore di errore e a un file, quindi non può coprire di nascosto un problema diverso da un'altra parte;
reportUnmatchedIgnoredErrorsresta attivo, quindi un'eccezione che smette di corrispondere — perché il codice è stato sistemato o il file è stato cancellato — fa fallire l'analisi invece di diventare debito permanente; le tre voci marcatereportUnmatched: falsesono l'eccezione all'eccezione: Larastan le segnala solo quando trova uno scheletro Testbench che registra già il package, quindi pretendere che corrispondano farebbe dipendere il risultato dall'ultimo comando lanciato;- ogni voce dichiara quale limite di inferenza del framework sta aggirando, nel commento sopra il suo gruppo.
Alzare il livello è benvenuto come pull request a sé, mai come effetto collaterale di una funzione.
Test¶
La suite gira con orchestra/testbench su SQLite in memoria e copre migrazioni, scoping per utente, i
componenti Livewire, i contratti di griglia:check e griglia:watch, piani e revisioni, temi, impostazioni,
notifiche, parità delle traduzioni e i file di community del repository stesso.
- Una correzione comincia da un test che fallisce. «Non è testabile» di solito vuol dire che la cucitura è nel posto sbagliato: scrivilo nella pull request e se ne discute, invece di passarci sopra.
- Il contratto dei comandi è un'API pubblica. L'output e le opzioni di
griglia:checksono ciò su cui ogni agente si appoggia: cambiarne una riga significa cambiareGrigliaCheckCommandTestapposta, mai per distrazione. - Anche i file del repository hanno i loro test.
CONTRIBUTING.md, il codice di condotta, i moduli per le issue, gli script e questo impianto di qualità: un modulo YAML rotto è silenzioso — GitHub semplicemente smette di proporlo. - Nessun test tocca un database vero.
DatabaseGuardinterrompe qualsiasi connessione che non sia SQLite o un database il cui nome contengatest.
Copertura¶
La copertura è uno strumento, non un cancello. composer test:coverage la stampa e scrive un rapporto
HTML in build/coverage, che è il modo giusto per scovare un ramo che ti sei dimenticato di testare. Serve
pcov o xdebug; mentre scriviamo la suite copre circa l'83% delle righe di src/. In CI
non c'è una percentuale minima, e non è una dimenticanza: il numero è facile da alzare senza testare niente
(un test che attraversa una classe senza asserire nulla conta lo stesso), e una soglia trasforma l'attenzione
della revisione in aritmetica. Quello che si pretende davvero è Q2 — una modifica arriva con un test che
senza di lei fallisce — cioè la proprietà di cui la percentuale è solo un indizio.
Dipendenze¶
- I vincoli di runtime restano larghi (
^12.0|^13.0): li risolve l'applicazione ospite, quindi restringerne uno è una rottura per qualcuno.prefer-lowestin CI è ciò che tiene onesto il limite inferiore. - Una nuova dipendenza di runtime richiede una ragione nella pull request; ciò che è utile ma non necessario
va in
suggest, comelaravel/aielaravel/reverb. - Dependabot apre pull request raggruppate ogni settimana per le dipendenze di sviluppo e per le GitHub Actions, e ogni mese per la catena front-end. Non tocca mai i vincoli di runtime. Le sue pull request passano dalla stessa matrice di tutte le altre.
composer auditfa fallire la build su una vulnerabilità nota. Una vulnerabilità di Griglia, invece, non è una issue: vedi Sicurezza.
Stile e convenzioni¶
- PHP: Laravel Pint, preset
laravel, nessuna deroga locale.composer formatcorregge, la CI si limita a controllare. - I commenti spiegano il perché, in inglese, e devono valere la riga che occupano: qui si preferisce un paragrafo che spiega una trappola a cinque righe che riscrivono il codice.
- Inglese nel repository, italiano solo nelle pagine
.it.mddel sito. Un test passa in rassegna i commenti disrc/,scripts/, le viste e i fogli di stile in cerca di parole italiane e fallisce alla prima (QualityStandardsTest). - Commit in inglese con prefisso convenzionale (
feat:,fix:,docs:,chore:,ci:,refactor:), una modifica logica per branch. - Nessun nome di agente nelle stringhe: la board è neutrale rispetto all'agente, e il segnaposto è
:agent.
Quando un controllo fallisce¶
| Sintomo | Di solito è |
|---|---|
fallisce docs:check |
hai cambiato un comando, una chiave di configurazione o un'impostazione: rilancia vendor/bin/testbench griglia:docs-generate e committa le pagine |
fallisce solo prefer-lowest |
hai usato qualcosa che esiste nella dipendenza più nuova ma non nella più vecchia che dichiari |
fallisce solo mysql |
strict mode, una colonna ambigua, un GROUP BY, o una lunghezza di colonna che SQLite ignora |
| fallisce una sola versione di PHP | una deprecazione legata a quella versione |
| PHPStan fallisce dopo un rebase | una voce di phpstan-ignores.neon non corrisponde più: cancellala, non alzarle il count |
Niente di tutto questo è burocrazia fine a sé stessa: ogni regola esiste perché la sua assenza è già costata tempo a qualcuno. Se una di loro ostacola una buona modifica, scrivilo nella pull request — lo standard si può spostare, saltarlo in silenzio no.
Vedi anche Contribuire, Sviluppo e Governance.