Skip to content

Runbook: rollback di una pipeline ​

Riportare in produzione il codice di una sola pipeline a una sua versione precedente, senza rilasciare tutto l'ETL. Le regole di numerazione, il gate e il riferimento del comando stanno nella convenzione Versioni di pipeline, e qui non si ripetono.

Tre rollback, tre nomi ​

Tornare indietro in produzione si fa in tre modi diversi, e ognuno ha il suo nome. Questo runbook descrive il terzo; scegli prima quale ti serve.

RollbackCosa torna indietroCome
Rollback del deployTutto: il repo cliente e, col suo lockfile, il core.Rimetti in servizio lo SHA precedente dell'artefatto: l'immagine con quel tag, o git checkout dello SHA e pnpm install --frozen-lockfile sotto PM2. Nessuna PR.
Downgrade del coreSolo il core, per tutte le pipeline del repo, comprese le pronte.Una PR hotfix/* da main che abbassa @noeva/etl-core nel package.json. Passa dal gate; se il piano si sposta, pnpm etl versions snapshot --realign.
Rollback di pipelineSolo la cartella di una pipeline del repo. Il core e le altre pipeline restano.etl versions rollback, su hotfix/rollback-* da origin/main: il resto di questo runbook.
  • Una pipeline pronta del core non ha un rollback di pipeline in un repo cliente: la versiona il core, e il comando la rifiuta. Si torna indietro col rollback del deploy o col downgrade del core.
  • Un rollback di pipeline non torna a versioni nate prima del trasferimento della pipeline in un repo cliente: quella storia git sta nel repo del core. Lì resta il rollback del deploy.
  • Il comando lavora sul repo dell'etl.config.ts da cui lo lanci, quello del core come quello di un cliente, con la stessa mappa dei branch: dev → staging → main.

Sintesi ​

  • Quando: una versione di pipeline andata in produzione regredisce, e la correzione in avanti non è pronta. Il rollback porta su main il codice di una versione precedente con un branch di hotfix/*, così il lavoro che aspetta su dev non parte con lui.
  • Cosa cambia: solo la cartella della pipeline. Il core, i connettori, le transform e le altre pipeline restano quelli di main.
  • Cosa non cambia: i dati già scritti e lo stato di pipeline. Il comando legge lo stato e lo mostra; mantenerlo o resettare un nodo è una decisione dichiarata nella PR.
  • Il numero non arretra: ritirare la v5 tornando alla v4 dà una v6 col codice della v4, e la voce «rollback alla v4» col motivo.
  • Criticità: alta. È un rilascio in produzione fuori dalla promozione normale.

1. Preparare il branch ​

Lavora in un worktree dedicato, come per ogni attività: il comando cambia branch nella cartella in cui lo lanci, e la vuole pulita.

bash
git fetch origin
git worktree add --detach .claude/worktrees/rollback-<pipeline> origin/main
cd .claude/worktrees/rollback-<pipeline>
pnpm install
pnpm run pipeline:rollback <pipeline> <N> --motivo "<perché si ritira la versione>" --ticket <chiave Jira>

Scegli <N> dalla sezione Versioni della scheda della pipeline: dev'essere una versione che è stata in cima a main. Una versione rimasta in un branch e superata prima del merge non è mai andata in produzione, e il comando la rifiuta elencando quelle che lo sono state. Il fetch serve: il comando legge origin/main così com'è in locale.

Per leggere lo stato del worker invece di quello locale aggiungi --workspace <id> (servono NOEVA_API_BASE_URL e NOEVA_API_KEY, come per etl state show). Il comando ne usa solo la lettura.

Il comando crea hotfix/rollback-<pipeline>-v<N> da origin/main e prepara le modifiche senza committarle:

  • la cartella è quella che la pipeline ha su main: se su dev è stata spostata, il comando la ritrova dal nome negli snapshot di main;
  • la cartella della pipeline torna com'era nell'ultimo commit di main con la vN, file aggiunti dopo compresi (spariscono) e file tolti dopo compresi (tornano);
  • changelog.ts e versions/ restano quelli di main, e il changelog guadagna la voce nuova;
  • lo snapshot del piano della versione nuova viene rigenerato, in un processo a parte che carica il codice ripristinato.

Alla fine stampa il branch, il commit da cui ha ripreso la cartella, lo stato salvato e le source che la versione ritirata aggiungeva o toglieva. Tieni quell'output: va nella PR.

La voce nuova registra la versione del core installata (core), e la riga Core del resoconto la confronta con quella della voce della vN: la cartella ripristinata gira sul core di oggi, non su quello con cui la vN è andata in produzione. Se i due differiscono, guarda lo snapshot nel diff: il piano può non essere più quello della vN. Se serve anche il core di allora, il rollback giusto è il downgrade del core, o il rollback del deploy.

Se il comando si ferma prima (exit 2) non ha toccato nulla: il messaggio dice perché. Gli esiti sono nella tabella della convenzione.

2. Se la cartella vecchia non gira più ​

Il core di oggi può non essere più quello con cui la vN girava (la riga Core del resoconto lo dice, se la voce della vN lo registra). Succede in due modi:

  • il comando esce con 1: lo snapshot non si genera, perché la cartella non si carica (un import che non c'è più, una firma cambiata). Il branch è già pronto, con la voce scritta;
  • il comando riesce, ma il gate del repo (pnpm exec etl ci; nel core pnpm run check) fallisce sul typecheck o sui test della pipeline.

In entrambi i casi adatta a mano la cartella sul branch di hotfix, il minimo per farla compilare contro il core di oggi. Resta un rollback: nella voce del changelog aggiungi alle Modifiche cosa hai adattato. Poi:

bash
pnpm run pipeline:snapshot <pipeline>           # --force se lo snapshot c'è già ed è cambiato
pnpm exec etl ci          # nel repo del core: pnpm run check

Se l'adattamento diventa una riscrittura, fermati: a quel punto una correzione in avanti su un hotfix/* normale costa meno, e dice meglio cosa è successo.

3. Lo stato di pipeline ​

Il rollback non tocca lo stato. La PR dichiara cosa farne, guardando l'output del comando:

SituazioneDi solito
Nessuna source cambiata fra le due versioniMantieni. La vN riparte dal watermark a cui era arrivata la versione ritirata.
Una source che la versione ritirata aggiungeva, con stato salvatoMantieni: dopo il rollback il nodo non c'è, e lo stato resta fermo. Se la versione tornerà, ripartirà da lì.
Una source che la versione ritirata toglieva, con stato salvatoLo stato è quello di prima del ritiro: la source rilegge dal vecchio watermark. Con sink idempotenti va bene; altrimenti reset in avanti.
La versione ritirata ha cambiato cosa misura il watermark di una sourceReset del nodo: il valore salvato non ha più senso per il codice della vN.
La versione ritirata ha scritto dati sbagliati da rileggereReset all'indietro al valore prima della versione ritirata: la vN rilegge quella finestra. Sistemare i dati scritti resta un lavoro a parte, caso per caso.

Il reset si fa dopo il deploy, con l'operazione esplicita di Stato di pipeline e watermark § Reset, e col motivo che cita il rollback:

bash
pnpm run etl state reset <pipeline> --node <id> [--to <valore>] --reason "rollback alla v<N> (<ticket>)" --workspace <id>

4. Revisione della PR di hotfix ​

Committa, pusha e apri la PR verso main. Chi rivede controlla:

  • [ ] il diff tocca solo src/pipelines/<pipeline>/ (cartella, changelog.ts, il nuovo versions/v<M>.plan.json); niente core, connettori o altre pipeline;
  • [ ] la voce del changelog ha il numero giusto (la versione su main più uno), rollbackTo con la vN e un motivo comprensibile, il ticket, la versione del core (core) e gli eventuali adattamenti fra le Modifiche;
  • [ ] pnpm exec etl ci (nel core pnpm run check) è verde: sul branch hotfix/* il gate si confronta con origin/main, non con dev;
  • [ ] la descrizione riporta l'output del comando e la dichiarazione sullo stato (mantieni, o quale nodo resettare e a che valore);
  • [ ] il diff della scheda (sezione Versioni) non segnala «rompe il contratto» in modo inatteso: tornare indietro può togliere colonne che a valle si leggono già.

Dopo il merge segue il deploy normale (Deploy, Worker), poi l'eventuale reset dello stato.

5. Back-merge in staging e dev ​

Come ogni hotfix, il codice di main torna in staging e in dev con una PR ciascuno. Sul back-merge il gate si confronta con dev, ed è lì che può scattare una collisione di numero.

dev non ha toccato la pipeline. Il back-merge passa così com'è.

dev ha già una versione nuova della stessa pipeline (la regressione è lì, o ci sono altri lavori in corso). Il numero che il rollback ha preso su main può essere già occupato su dev, e il gate lo dice: la vM è già presa. Si risolve sul branch di back-merge, così:

  1. La voce del rollback tiene il suo numero: è andata in produzione, e una run lo porta già nel report.
  2. La voce in lavorazione su dev scala al numero successivo: rinumera la voce in changelog.ts e rinomina il suo snapshot (git mv versions/vM.plan.json versions/vM+1.plan.json prima del merge, o risolvi il conflitto tenendo lo snapshot di main per la vM).
  3. Il codice della cartella resta quello di dev, non quello del rollback: è il lavoro che deve arrivare dopo. Ma la regressione che il rollback ha ritirato non deve ripartire alla prossima promozione: se è ancora nel codice di dev, correggila prima di promuovere.
  4. pnpm run pipeline:snapshot <pipeline> --force per la versione di dev, poi pnpm exec etl ci. Il gate accetta lo snapshot della vM sostituito perché è cambiata anche la sua voce: la vM ora è il rollback. Uno snapshot di dev cambiato con la voce di prima resta invece una violazione.

Lo stesso vale per un ticket in un branch di feature che ha già fatto il bump: allinealo con git merge origin/dev dopo il back-merge e rinumera come sopra.

Escalation ​

  • Primo livello: l'owner della pipeline, dalla sua scheda in docs/pipelines/.
  • Secondo livello: il team BI/ETL, che decide fra rollback adattato e correzione in avanti quando la cartella vecchia non regge il core di oggi.

Noeva è un marchio registrato di 4D S.R.L.