RFC: Una nuova strategia di versioning per Discourse

Stiamo pianificando di introdurre un nuovo sistema di versioning per Discourse. Il nostro obiettivo è fornire maggiore scelta e prevedibilità agli amministratori della community, mantenendo al contempo la nostra velocità di sviluppo. Stiamo inoltre modificando alcune terminologie per allinearle meglio ad altri software.

Questo documento si evolverà man mano che riceveremo commenti, inizieremo a implementare il sistema ed espanderemo l’uso dei nuovi flussi di rilascio.

Se avete commenti/suggerimenti in questa fase, fatecelo sapere rispondendo a questo argomento!


Obiettivi

  1. Introdurre ‘release’ più regolari per Discourse, che forniscano un equilibrio tra velocità di sviluppo e stabilità
  2. Continuare a fornire circa 6 rilasci semestrali che sono supportati per un periodo prolungato
  3. Fornire supporto sovrapposto per i rilasci regolari e quelli a supporto esteso, in modo che gli amministratori abbiano maggiore flessibilità sui tempi di aggiornamento, continuando a ricevere aggiornamenti critici di sicurezza
  4. Mantenere al minimo la cerimonia attorno ai ‘release’. Il più possibile dovrebbe essere automatizzato e non rallentare l’esperienza dello sviluppatore principale. I rilasci ESR sono uguali a qualsiasi altro rilascio.
  5. La denominazione e la procedura dovrebbero corrispondere agli standard del settore, in modo che sia più facile spiegarlo agli sviluppatori e agli utenti finali

Panoramica di alto livello

  • Tagliare circa un rilascio al mese. La versione ‘maggiore’ è l’anno corrente, e la versione ‘minore’ si incrementa con ogni rilascio. Il numero di versione di patch verrà incrementato per eventuali correzioni backportate

    es. il primo rilascio del 2026 sarà v2026.0, il successivo sarà v2026.1, ecc.

    I rilasci riceveranno correzioni critiche per due cicli di rilascio completi. es. il supporto per 2026.0 continuerà fino al rilascio di 2026.2.

  • Circa ogni 6 mesi, dichiarare uno di questi rilasci come Extended Support Release (ESR). Le versioni ESR rimangono supportate per 2 rilasci dopo la dichiarazione del successivo ESR.

    es. se v2026.0 è ESR, e v2026.6 è il successivo ESR, allora il supporto per v2026.0 terminerà al rilascio di v2026.8. Assumendo una cadenza mensile, ciò comporterebbe una sovrapposizione di 2 mesi nel supporto ESR.

  • Fornire correzioni critiche per latest, l’ultimo rilascio, il rilascio precedente e tutte le versioni ESR attive.

  • Rinominare il branch tests-passed in latest

Esempio di grafico dei periodi di supporto nel corso di un anno:

gantt
    title Discourse Releases and Support Periods (Jan 2026 – Jan 2027)
    dateFormat  YYYY-MM-DD
    axisFormat  %b %Y

    2026.0 (ESR) :active, 2026-01-27, 2026-09-29
    2026.1 :done, 2026-02-24, 2026-04-28
    2026.2 :done, 2026-03-31, 2026-05-26
    2026.3 :done, 2026-04-28, 2026-06-30
    2026.4 :done, 2026-05-26, 2026-07-28
    2026.5 :done, 2026-06-30, 2026-08-25
    2026.6 (ESR) :active, 2026-07-28, 2027-01-26
    2026.7 :done, 2026-08-25, 2026-10-27
    2026.8 :done, 2026-09-29, 2026-11-24
    2026.9 :done, 2026-10-27, 2026-12-29
    2026.10 :done, 2026-11-24, 2027-01-26
    2026.11 :done, 2026-12-29, 2027-01-26

Implementazione

  • Ogni rilascio avrà un branch tagliato da latest. Questi saranno namespaces e conservati indefinitamente. Ad esempio, v2026.1 avrà un branch chiamato release/2026.1

  • Ogni rilascio di patch sarà taggato. es. v2026.1.0, v2026.1.1, ecc.

  • L’ultimo rilascio sarà taggato release. L’ultimo ESR sarà taggato esr.

  • Il rilascio precedente sarà taggato release-previous. L’ESR attivo precedente (se presente) sarà taggato esr-previous.

  • Per retrocompatibilità, i tag che corrispondono ai flussi di rilascio esistenti saranno aliasati al nuovo equivalente più vicino. stableesr. betarelease. tests-passedlatest.

    Questi saranno considerati deprecati, e mireremo a eliminarne alcuni o tutti in futuro. In particolare, ‘beta’ è problematico perché dà l’impressione che Discourse non sia pronto per la produzione.

  • Su latest, il numero di versione sarà la versione attualmente in sviluppo, suffissata con -latest. es. 2026.3.0-latest

Processo di rilascio automatizzato

Ogni mese, un’azione di GitHub aprirà una nuova PR contenente un singolo commit che incrementa version.rb su main alla successiva versione -latest.

Una volta che un umano avrà unito la PR, un’altra azione di GitHub rileverà che main è passato alla successiva versione -latest e creerà un branch per il rilascio completato. Essenzialmente, questo branch diventerà un ‘release candidate’. Un’altra PR automatizzata verrà aperta contro il branch di rilascio con un aggiornamento per rimuovere il suffisso -latest da version.rb, e quindi ‘rilasciarlo’.

Di solito, uniremo queste due PR in rapida successione. Ma avere PR separate per la creazione e la finalizzazione del rilascio ci dà la possibilità di affrontare eventuali problemi nel branch prima della finalizzazione.

    %%{init: { 'logLevel': 'debug', 'gitGraph': {'showBranches': true, 'showCommitLabel':true,'mainBranchOrder': 2}} }%%
    gitGraph
       checkout main
       commit id:'version v2026.1-latest'
       commit id:'...'
       commit id:'....'
       branch 'release/2026.1'
       commit id:'version 2026.1'
       checkout 'main'
       commit id:'version v2026.2-latest'

Separately, another GitHub actions workflow will watch for any backported commits to release branches. When any are found, a new PR will be generated to bump the patch version on that branch. A human can decide when to merge those PRs.

Tutte queste automazioni manterranno automaticamente aggiornati vari tag (release, release-previous, esr, esr-previous, più alias di retrocompatibilità).

Correzioni di sicurezza

Il flusso di lavoro per le correzioni di sicurezza rimane in gran parte lo stesso, tranne per il fatto che ora dobbiamo apportare le correzioni in due dei seguenti tre posti:

  • latest
  • esr
  • esr-previous :new_button:
  • release :new_button:
  • release-previous :new_button:

(Ricorda, secondo l’illustrazione precedente, sono solo due dei tre perché esr-previous è supportato, il nuovo esr è uguale a release o release-previous, e interrompiamo il supporto per esr-previous quando ciò non è più vero).

Quando si introduce una correzione di sicurezza in latest, un tag latest-security-fix verrà automaticamente spostato su quel commit. docker_manager verrà aggiornato per monitorare quel tag e chiedere agli amministratori di aggiornare. Questo ci consente di rilasciare e notificare le correzioni di sicurezza senza dover accelerare un incremento di versione.

Traduzioni

Al momento, i branch stable e tests-passed possono essere tradotti in CrowdIn, e i risultati vengono regolarmente integrati. Nel nuovo sistema, inizialmente prevediamo che latest e release siano traducibili in CrowdIn.

Idealmente, entro il momento in cui release diventerà release-previous o esr, le traduzioni si saranno stabilizzate. Se c’è una domanda per traduzioni continue di quelle versioni, allora è qualcosa che potrebbe essere considerato in futuro.

Compatibilità Plugin/Tema

L’aumento dell’uso di flussi non-latest di Discourse aumenterà la nostra dipendenza dal sistema discourse-compatibility. Quindi abbiamo bisogno di alcuni miglioramenti al sistema di compatibilità.

Invece di utilizzare un file .discourse-compatibility su main, potremmo invece supportare la compatibilità implicita basata su branch/tag nominati in modo speciale. Questo dovrebbe essere molto più semplice che destreggiarsi manualmente con gli hash dei commit. Ad esempio, un plugin potrebbe avere branch come

  • d-compat/v2026.1
  • d-compat/v2026.2
  • d-compat/v2026.3
  • main (utilizzato per qualsiasi versione di Discourse che non ha un proprio branch)

Quando si installa un plugin, Discourse può controllare un branch corrispondente alla versione corrente. Se esiste, effettua il checkout. Altrimenti, controlla il file .discourse-compatibility. Altrimenti, effettua il checkout del branch predefinito.

Possiamo creare un’azione GitHub pubblica che viene eseguita quotidianamente su ogni tema/plugin, controlla i nuovi rilasci di Discourse e crea automaticamente questi branch. Ogni tema/plugin potrebbe scegliere di utilizzare questa azione di auto-fissaggio, oppure potrebbe optare per una strategia più ‘fluttuante’.

Hosting discourse.org

Inizialmente, la nostra offerta ospitata continuerà a eseguire la versione latest di Discourse. In futuro, esploreremo opzioni per i nostri clienti di livello enterprise per selezionare una versione ‘release’.

Impostazioni predefinite di installazione standard

Inizialmente, l’impostazione predefinita rimarrà latest. Gli amministratori potranno scegliere di aderire al nuovo flusso di rilascio nello stesso modo in cui aderiscono attualmente a stable. Potremmo esplorare switch più semplici tra i flussi di rilascio in futuro, una volta che il sistema sarà più maturo.

38 Mi Piace

Sono un po’ confuso. Quindi tests-passed alias latest (che presumo sia il default) sarà il più aggiornato (ricevendo gli aggiornamenti più frequenti; nessun cambiamento lì), ma l’attuale branch beta, ora il branch release, si comporterà ancora come adesso, cioè un “gruppo” di commit/aggiornamenti, e poi il branch ESR (alias stable) sarà un “gruppo” più grande di aggiornamenti beta/release?

Ciò significa che release diventa ora l’opzione predefinita, o quando dici “ultima release” ti riferisci all’“ultimo aggiornamento sul branch release”? Ci sarebbe quindi una differenza tra quello e latest?

Grazie!

1 Mi Piace

beta è attualmente un tag e non riceve correzioni retroattive.

Con questa proposta, ogni rilascio versionato avrà il proprio ramo e riceverà correzioni di sicurezza finché sarà “supportato”. Le persone potrebbero scegliere di puntare la loro installazione al numero di versione specifico e continuare a usarla dopo che sarà stato effettuato un altro rilascio. Ciò non è possibile con gli attuali beta o stable.

release sarà un tag che seguirà l’ultimo rilascio (incluse le patch) per le correzioni di sicurezza.

No:

‘ultimo rilascio’ (o semplicemente ‘release’) = l’ultimo commit sul ramo di rilascio più recente

‘latest’ = il nuovo nome per tests-passed

3 Mi Piace

Grazie, è più chiaro!

2 Mi Piace

Sembra uno sviluppo positivo!

Ci saranno test specifici degli aggiornamenti da esr-previous a esr al momento in cui verrà etichettato esr? Tali aggiornamenti, a mio parere, dovrebbero essere organizzati per essere aggiornamenti fluidi, o per avere buone descrizioni su come eseguirli nel modo più fluido possibile.

4 Mi Piace

Sì, gli aggiornamenti tra versioni ESR (o qualsiasi versione supportata) continueranno a essere trasparenti.

2 Mi Piace

Solo una piccola richiesta per comodità, il puntatore (ad esempio 2026.0) potrebbe essere piuttosto legato al mese in cui viene rilasciata una versione? (Cioè 2026.01 per gennaio, 2026.02 per febbraio ecc.)

4 Mi Piace

Il problema di legare esplicitamente le cose a un mese è che non saremo in grado di saltare un mese o rilasciare due versioni in un mese. Ecco perché stiamo pianificando di mantenerlo come un semplice numero incrementale.

3 Mi Piace

Un progetto che uso molto (mailcow) salta il mese quando non ci sono cambiamenti significativi al core.

E contare da 0 sarebbe davvero strano. Ha perfettamente senso per i programmatori, ma non molto senso per le persone non tecniche.

2 Mi Piace

Mi stavo chiedendo della versione x.0 menzionata. Mi piace molto legarla al mese in modo da poter dire subito quando è stata rilasciata una versione. Ma forse non ha importanza se xx.8 è stato rilasciato a settembre, dicembre o giugno. Faccio fatica a ricordare di quale versione stiamo parlando ora, quindi poter dire subito se qualcuno sta parlando di un bug della settimana scorsa o di qualche mese fa senza dover guardare il commit come faccio ora, sarebbe davvero bello.

Ubuntu ha YY.04 e YY.10. Funziona da vent’anni. Saltare i mesi non sembra difficile.

Questo sembra più un problema, anche se potresti fare qualcosa come 22.1a o 22.01a se dovessi avere due rilasci in un mese.

6 Mi Piace

Qualche tempo fa abbiamo iniziato a usare questa strategia anche per la nostra piattaforma. Esattamente la stessa, inclusi branching e patching. Posso raccomandarla.

Usiamo rilasci mensili. Quindi da 1 a 12. Il ritmo aiuta tutti. C’è sempre qualcosa da rilasciare e nessuno vuole tagliare il branch due volte al mese comunque. Inoltre, quando dico “uso 2025.6”, tutti sanno che è quello di prima delle vacanze estive.

7 Mi Piace

Prima di tutto, :rocket: questo è un ottimo passo avanti!

Dopo averci riflettuto un po’, ho due piccole osservazioni.

  1. git branch e molti altri strumenti non comprendono il versioning e ordineranno alfabeticamente o numericamente. In entrambi i casi, 2026.10 finirebbe tra 2026.1 e 2026.2. Ispirato da Ubuntu, propongo di introdurre uno zero iniziale per le release e le patch release quando sono a una sola cifra, quindi avremmo v2026.01, v2026.02 e v2026.10 e l’universo sarebbe di nuovo felice.

  2. il nuovo metodo di compatibilità dei plugin sembra eccessivamente complesso e molto fragile

Quindi, se creo una nuova funzionalità nel mio plugin che necessita di v2026.3, creo un branch e ci metto la mia nuova funzionalità. Ora che la funzionalità è stata creata e il mio cliente è felice, posso riposarmi e godermi la vacanza :palm_tree: :wine_glass:. Tuttavia, dopo il mio terzo bicchiere di vino, decidi di rilasciare v2026.4 e il mio cliente decide di aggiornare. E puff, non c’è un branch v2026.4 nel mio plugin e la funzionalità scompare :sob:

Quindi non userei mai questo e continuerei invece a usare .discourse-compatibility.

9 Mi Piace

L’intenzione è l’opposto. I branch di compatibilità sono solo per i branch “rilasciati” di Discourse. Discourse latest utilizzerà sempre main del tuo plugin. È lì che svilupperai nuove funzionalità.

Quindi la storia sarebbe:

Discourse rilascia v2026.2. Le azioni di GitHub sul tuo plugin lo rilevano automaticamente e creano un branch d-compat/v2026.2. Ora, chiunque utilizzi Discourse v2026.2 utilizzerà la versione d-compat/v2026.2 del tuo plugin.

Rilasci una nuova funzionalità su main del tuo plugin. Non devi preoccuparti della retrocompatibilità, perché il branch main viene utilizzato solo da coloro che eseguono Discourse latest.

Poi, mentre sorseggi il tuo terzo bicchiere di vino :wine_glass:, Discourse crea v2026.3. Inizialmente non c’è un branch del plugin per questa versione, quindi verrà utilizzato main. Le cose continuano a funzionare come prima per le persone su latest.

Entro poche ore, la tua azione di GitHub rileva la nuova versione e blocca d-compat/v2026.3, pronto per la tua prossima funzionalità del plugin che arriverà su main senza problemi di retrocompatibilità.

Questo è essenzialmente il flusso di lavoro che utilizziamo in CDCK per gestire la compatibilità stabile di temi/plugin. Dopo ogni rilascio stabile, abbiamo uno script per eseguire centinaia dei nostri temi/plugin e bloccarli tramite .discourse-compatibility. Questa proposta basata su branch mira ad essere una versione più leggera di quel flusso di lavoro.

16 Mi Piace

Fantastico, grazie per la spiegazione dettagliata.

Sembra che potrò bere un quarto bicchiere di vino :wink:

15 Mi Piace

Concordo con quanto detto da altri, mi piace la direzione delle modifiche proposte. E penso che i nomi dei branch proposti siano molto più intuitivi di quelli vecchi :+1:

Ciò che non mi è ancora del tutto chiaro è come funzionerà il processo di aggiornamento per i branch release e esr (sembra che latest sia semplice). Menzioni che, in ogni momento, saranno supportate sia la release corrente (chiamiamola n) sia la release precedente (n-1), e che, come amministratore, avrò la possibilità di scegliere quando aggiornare.

Ora, basandomi sulla mia esperienza con altri software, quando arriva una nuova versione di release (n+1), sarei avvisato della disponibilità della versione n+1. E potrei quindi decidere di fare un aggiornamento maggiore (equivalente ad esempio a apt dist-upgrade su Linux) o fare un aggiornamento minore/standard (equivalente ad esempio a apt upgrade su Linux) e rimanere alla versione n. È qualcosa che verrà integrato nello script del launcher di Discourse?

Inoltre, capisco il desiderio di ridurre al minimo la cerimonia/processo di rilascio, ma la mia intuizione sarebbe che sia i rilasci normali che quelli esr ricevano almeno un po’ di test aggiuntivi, prima di essere rilasciati. Questo potrebbe derivare dal fatto di aver lavorato troppo a lungo nell’IT aziendale, però :smile:

Infine, mi chiedo se i rilasci mensili siano in realtà “troppo veloci”. Ammetto che anche questo è soggettivo, ma a giudicare dalla mia esperienza nella gestione di cose IT come volontario, potrei non avere il tempo per aggiornamenti più importanti ogni mese. E partendo da questo, mi chiedevo se poteste anche semplificarvi la vita come sviluppatori di Discourse rilasciando semplicemente trimestralmente, e non avendo branch esr separati, ma solo branch release.

4 Mi Piace

Ciò renderà la vita degli sviluppatori di temi e plugin più difficile, perché in quella (questa) situazione si ha una pressione temporale per aggiornare temi e plugin, altrimenti non si avranno aggiornamenti di sicurezza. Una versione ESR eliminerà quella pressione.

4 Mi Piace

Non sono sicuro di aver capito completamente. La mia comprensione basata sui post precedenti era che la creazione di un branch di versione di rilascio avrebbe automaticamente innescato la creazione di un branch di plugin per quella versione. Quindi la mia ipotesi sarebbe che unire release e esr in uno solo ridurrebbe anche lo sforzo per i costruttori di plugin e temi, perché ogni volta che è necessario apportare una correzione, questa dovrebbe essere apportata a meno branch (tre invece di cinque). Ma forse mi sfugge qualcosa?

2 Mi Piace

Non si tratta di quando l’autore del tema/plugin rilascia una correzione, ma di quando il core di Discourse ha una correzione di sicurezza.

Secondo

l’unica differenza tra release e esr è che esr riceve correzioni di sicurezza per 6 + 2 = 8 mesi.

1 Mi Piace

Con gli attuali strumenti del launcher e questa nuova struttura dei branch, potresti avere il controllo sui tempi di aggiornamento facendo qualcosa come:

  1. Rilasciata v2026.02
  2. Imposti version: release/v2026.02 nel tuo file app.yml
  3. Rilasciata v2026.03
  4. Esegui una nuova build. Ottieni ancora la 2026.02, con eventuali correzioni di sicurezza recenti
  5. Quando sei pronto, passi a version: release/v2026.03 in app.yml

Ma modificare manualmente quel app.yml ogni mese non è davvero l’ideale, quindi speriamo di poter progettare un sistema che renda il processo più user-friendly.

Il processo nell’OP ci consente di trattare i branch come ‘release candidate’ prima di contrassegnarli effettivamente come release. Non sono sicuro esattamente se/come utilizzeremo tale capacità in questa fase: penso che sia qualcosa che si evolverà man mano che ci abitueremo al nuovo sistema.

Stiamo cercando di trovare un equilibrio tra la velocità di sviluppo di Discourse e la stabilità per coloro che hanno personalizzazioni estese. Avere un ritardo di oltre 3 mesi per portare le funzionalità ai nostri clienti non è un’opzione. Semmai, il mensile è un po’ lento per noi. Al momento intendiamo ancora utilizzare latest per la maggior parte del nostro hosting.

Ma ovviamente, per le persone che ospitano Discourse da sole, capisco il desiderio di avere cambiamenti meno frequenti. È qui che entrano in gioco le release ESR.

5 Mi Piace

Dipende dall’autore del plugin/tema. O possono continuare con la strategia attuale, in cui il branch main del plugin deve funzionare con tutte le versioni “rilasciate” di Discourse. Oppure possono utilizzare la strategia di branching automatico, che facilita la compatibilità, ma significa anche che potrebbe essere necessario eseguire un sacco di “backporting” nel proprio plugin in caso di correzioni critiche di bug/sicurezza.

In qualsiasi momento, ci sono tre versioni “supportate” di Discourse, più latest. Quindi le correzioni critiche dovranno essere applicate in un massimo di 4 branch.

3 Mi Piace