Skip to content

CI/CD su github

Sviluppo · Qualità del codice

CI/CD per plugin WordPress: appunti di chi sta ancora imparando

Perché ho iniziato ad affidare i controlli a una pipeline invece che alla mia memoria, e cosa ho scoperto sul mio stesso codice.

Davide Bertolino · Ottobre 2026

Parto da una confessione. Negli ultimi tempi ho ampliato la suite di test di DB Cookie Manager, un plugin che uso, mantengo e che consideravo ragionevolmente solido. Risultato: parecchi bug minori, in punti dove ero convinto che tutto funzionasse. Niente di drammatico, ma abbastanza per farmi una domanda scomoda: quanti altri ne sono rimasti lì, semplicemente perché nessuno li ha mai cercati?

Questo articolo non è una guida scritta da chi ha capito tutto. È il diario di un programmatore che prova a lavorare meglio, e che ha trovato nella CI/CD uno strumento utile soprattutto per difendersi da se stesso.

CI e CD, senza giri di parole

Continuous Integration significa che ogni modifica al codice, a ogni push o pull request, viene verificata automaticamente: sintassi, standard di scrittura, analisi statica, test. Se qualcosa non va, lo scopri subito, non quando un utente apre una segnalazione.

Continuous Delivery (o Deployment) è il passo successivo: quando il codice supera i controlli, il pacchetto di rilascio viene costruito in modo automatico e ripetibile. Niente più zip fatti a mano dimenticando un file o includendo la cartella dei test.

Il punto vero

La pipeline non mi rende un programmatore migliore per magia. Mi toglie la possibilità di saltare i controlli quando ho fretta, che è esattamente il momento in cui sbaglio di più.

Perché proprio per un plugin WordPress

Chi sviluppa plugin WordPress, spesso da solo, si trova in una situazione particolare. Il codice gira su installazioni che non controlli, con versioni di PHP e di WordPress diverse, accanto a decine di altri plugin. Non c’è un reparto QA. Ci sei tu, il tuo ambiente di sviluppo e la speranza che “da me funziona” valga anche altrove.

Alcuni problemi tipici che una pipeline intercetta bene:

  • una sintassi valida in PHP 8 che rompe tutto su un hosting ancora fermo a PHP 7.4;
  • output non sanificato o nonce dimenticati, che i WordPress Coding Standards segnalano puntualmente;
  • chiamate a funzioni con tipi sbagliati o variabili possibilmente nulle, che l’analisi statica scova prima dell’esecuzione;
  • regressioni: una correzione in un punto che rompe silenziosamente un comportamento altrove.

Una pipeline minima, da cui partire

Non serve costruire tutto in un giorno. Questi sono gli strumenti che trovo più utili, in ordine di costo d’ingresso crescente.

php -l

Controllo di sintassi su più versioni di PHP. Costo zero, utilità immediata.

PHPCS + WPCS

WordPress Coding Standards: stile, ma soprattutto escaping, sanificazione e nonce.

PHPStan

Analisi statica dei tipi, con l’estensione per WordPress. Si parte da un livello basso e si sale.

PHPUnit

I test veri e propri. Il più impegnativo da introdurre, quello che restituisce di più.

Il workflow di Continuous Integration

Con GitHub Actions basta un file in .github/workflows/ci.yml. Questo esempio assume che PHPCS, WPCS, PHPStan e PHPUnit siano dichiarati come dipendenze di sviluppo in composer.json.

name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  syntax:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        php: ['7.4', '8.1', '8.3']
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php }}
      - name: Lint PHP
        run: find . -name "*.php" -not -path "./vendor/*" -print0 | xargs -0 -n1 php -l

  quality:
    runs-on: ubuntu-latest
    needs: syntax
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'
          tools: composer
      - run: composer install --no-progress --prefer-dist
      - name: WordPress Coding Standards
        run: vendor/bin/phpcs
      - name: Analisi statica
        run: vendor/bin/phpstan analyse --memory-limit=1G
      - name: Test
        run: vendor/bin/phpunit

Per i test che richiedono un WordPress funzionante, @wordpress/env permette di avviare un’istanza completa in Docker direttamente nel runner. Richiede un po’ di configurazione in più, ma è il modo più vicino alla realtà per verificare hook, opzioni e interazioni con il core.

Il workflow di rilascio

Il secondo file si attiva solo quando creo un tag di versione, e produce lo zip da allegare alla release:

name: Release

on:
  push:
    tags: ['v*']

permissions:
  contents: write

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Crea pacchetto
        run: git archive --prefix=nome-plugin/ -o nome-plugin.zip HEAD
      - uses: softprops/action-gh-release@v2
        with:
          files: nome-plugin.zip

Il trucco sta nel file .gitattributes: con export-ignore si escludono dallo zip test, configurazioni e workflow. Il pacchetto che arriva all’utente contiene solo ciò che serve, ogni volta, senza che io debba ricordarmelo.

/tests            export-ignore
/.github          export-ignore
phpunit.xml.dist  export-ignore
phpcs.xml.dist    export-ignore
phpstan.neon      export-ignore

Cosa sto imparando

Iniziare piccoli funziona meglio

Attivare PHPStan al livello massimo su un plugin esistente produce centinaia di segnalazioni e la tentazione di spegnere tutto. Molto meglio partire da un livello basso, oppure generare una baseline che congela gli errori attuali e impone solo di non introdurne di nuovi. Poi si alza l’asticella un passo alla volta.

Un test verde non è una garanzia

I bug che ho trovato in DB Cookie Manager non erano nascosti da test sbagliati: erano in parti che i test semplicemente non toccavano. La pipeline verifica quello che le chiedi di verificare. Il resto rimane responsabilità mia.

Lo standard è un insegnante paziente

Molte segnalazioni di WPCS all’inizio mi sembravano pignolerie. Leggendole con calma, parecchie riguardavano escaping e validazione dell’input: proprio le cose che, in un plugin che tratta dati personali e consenso, non possono essere lasciate al caso.

Un errore da evitare

Disattivare una regola perché “dà fastidio” senza capire cosa protegge. Le eccezioni hanno senso, ma vanno motivate nel codice, con un commento che spieghi il perché.

In conclusione

La CI/CD non riguarda solo i grandi team o i progetti enterprise. Per chi sviluppa da solo è forse ancora più utile: è il collega che controlla il tuo lavoro senza stancarsi e senza fare sconti.

Sto ancora sistemando le pipeline dei miei plugin, e sicuramente tra sei mesi guarderò questi file pensando a come migliorarli. Se hai esperienze, suggerimenti o critiche, il confronto è benvenuto: le issue e le pull request sui repository sono aperte, ed è proprio da lì che arrivano spesso le lezioni migliori.

Condividi