RFC: Eine neue Versionierungsstrategie für Discourse

Wir planen, eine neue Versionierungsstruktur für Discourse einzuführen. Unser Ziel ist es, Administratoren von Communities mehr Auswahlmöglichkeiten und Vorhersehbarkeit zu bieten und gleichzeitig unsere Entwicklungsgeschwindigkeit beizubehalten. Wir passen auch einige Terminologien an, um sie besser an andere Software anzupassen.

Dieses Dokument wird sich weiterentwickeln, wenn wir Kommentare erhalten, mit der Implementierung des Systems beginnen und dann die Nutzung der neuen Release-Streams erweitern.

Wenn Sie in dieser Phase Kommentare/Vorschläge haben, lassen Sie es uns bitte wissen, indem Sie auf dieses Thema antworten!


Ziele

  1. Einführung regelmäßigerer „Releases“ für Discourse, die ein Gleichgewicht zwischen Entwicklungsgeschwindigkeit und Stabilität bieten.

  2. Fortsetzung der Bereitstellung von ca. 6-monatigen Releases, die über einen längeren Zeitraum unterstützt werden.

  3. Bereitstellung überlappender Unterstützung für reguläre und Langzeit-Support-Releases, damit Administratoren mehr Flexibilität bei der Aktualisierung haben und weiterhin kritische Sicherheitsupdates erhalten.

  4. Die Zeremonie rund um „Releases“ auf ein Minimum beschränken. So viel wie möglich sollte automatisiert werden und die Kernentwicklungserfahrung nicht verlangsamen. ESR-Releases sind genauso wie alle anderen Releases.

  5. Benennung und Verfahren sollten Industriestandards entsprechen, damit sie für Entwickler und Endbenutzer leichter zu erklären sind.

Grobe Übersicht

  • Etwa ein Release pro Monat. Die „Hauptversion“ ist das aktuelle Jahr, und die „Nebenversion“ wird mit jedem Release inkrementiert. Die Patch-Versionsnummer wird für alle zurückportierten Korrekturen erhöht.

    z. B. wäre das erste Release von 2026 v2026.0, das nächste v2026.1 usw.

    Releases erhalten kritische Korrekturen für zwei vollständige Release-Zyklen. z. B. würde die Unterstützung für 2026.0 bis zur Veröffentlichung von 2026.2 fortgesetzt.

  • Etwa alle 6 Monate wird eines dieser Releases als Extended Support Release (ESR) deklariert. ESR-Versionen bleiben zwei Releases nach der Deklaration des nächsten ESR unterstützt.

    z. B. wenn v2026.0 ESR ist und v2026.6 das nächste ESR ist, endet die Unterstützung für v2026.0 mit der Veröffentlichung von v2026.8. Bei einer monatlichen Kadenz wäre dies eine 2-monatige Überlappung der ESR-Unterstützung.

  • Bereitstellung kritischer Korrekturen für latest, das neueste Release, das vorherige Release und alle aktiven ESR-Versionen.

  • Umbenennung des tests-passed-Branches in latest.

Beispielgraph der Support-Zeiträume über ein Jahr:

gantt
    title Discourse Releases und Support-Zeiträume (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

Implementierung

  • Jedes Release erhält einen Branch, der von latest abgeschnitten wird. Diese werden benannt und bleiben auf unbestimmte Zeit erhalten. Zum Beispiel hätte v2026.1 einen Branch namens release/2026.1.

  • Jedes Patch-Release wird getaggt. z. B. v2026.1.0, v2026.1.1 usw.

  • Das neueste Release wird mit release getaggt. Das neueste ESR wird mit esr getaggt.

  • Das vorherige Release wird mit release-previous getaggt. Das vorherige aktive ESR (falls vorhanden) wird mit esr-previous getaggt.

  • Zur Abwärtskompatibilität werden Tags, die den bestehenden Release-Streams entsprechen, auf das nächstgelegene neue Äquivalent umgeleitet. stableesr. betarelease. tests-passedlatest.

    Diese werden als veraltet betrachtet, und wir werden versuchen, einige oder alle davon in Zukunft zu entfernen. Insbesondere „beta“ ist problematisch, da es den Eindruck erweckt, dass Discourse nicht produktionsreif ist.

  • Auf latest ist die Versionsnummer die aktuell in Entwicklung befindliche Version, ergänzt um -latest. z. B. 2026.3.0-latest.

Automatisierter Release-Prozess

Jeden Monat öffnet eine GitHub-Aktion eine neue PR, die einen einzelnen Commit enthält, der version.rb auf main auf die nächste -latest-Version hochstuft.

Sobald ein Mensch die PR zusammenführt, erkennt eine weitere GitHub-Aktion, dass main zur nächsten -latest-Version wechselt, und schneidet einen Branch für das abgeschlossene Release ab. Im Wesentlichen wird dieser Branch zu einem „Release Candidate“. Eine weitere automatisierte PR wird gegen den Release-Branch geöffnet, um mit einem Update das -latest-Suffix von version.rb zu entfernen und es dadurch zu „releasen“.

Normalerweise werden wir diese beiden PRs schnell hintereinander zusammenführen. Das Vorhandensein separater PRs für die Erstellung und Fertigstellung des Releases gibt uns jedoch die Möglichkeit, Probleme im Branch vor der Fertigstellung zu beheben.

    %%{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'

Separat wird ein weiterer GitHub-Actions-Workflow auf zurückportierte Commits zu Release-Branches achten. Wenn welche gefunden werden, wird eine neue PR generiert, um die Patch-Version auf diesem Branch zu erhöhen. Ein Mensch kann entscheiden, wann diese PRs zusammengeführt werden.

All diese Automatisierungen halten automatisch verschiedene Tags (release, release-previous, esr, esr-previous sowie Abwärtskompatibilitäts-Aliase) auf dem neuesten Stand.

Sicherheitsfixes

Der Workflow für Sicherheitsfixes bleibt weitgehend gleich, mit der Ausnahme, dass wir die Fixes nun an zwei dieser drei neuen Stellen vornehmen müssen:

  • latest

  • esr

  • esr-previous :new_button:

  • release :new_button:

  • release-previous :new_button:

(Denken Sie daran, dass gemäß der vorherigen Abbildung nur zwei der drei erforderlich sind, da esr-previous unterstützt wird, das neue esr dasselbe ist wie release oder release-previous, und wir die Unterstützung für esr-previous einstellen, wenn dies nicht mehr der Fall ist.)

Wenn ein Sicherheitsfix in latest eingeführt wird, wird automatisch ein latest-security-fix-Tag auf diesen Commit verschoben. docker_manager wird aktualisiert, um diesen Tag zu überwachen und Administratoren aufzufordern, zu aktualisieren. Dies ermöglicht es uns, Sicherheitsfixes zu veröffentlichen und darüber zu informieren, ohne eine Versionserhöhung erzwingen zu müssen.

Übersetzungen

Derzeit können die Branches stable und tests-passed in CrowdIn übersetzt werden, und die Ergebnisse werden regelmäßig integriert. Im neuen System planen wir zunächst, latest und release in CrowdIn übersetzbar zu machen.

Idealerweise sind die Übersetzungen bis zu dem Zeitpunkt, an dem release zu release-previous oder esr wird, abgeschlossen. Wenn eine Nachfrage nach kontinuierlichen Übersetzungen dieser Versionen besteht, könnte dies in Zukunft in Betracht gezogen werden.

Plugin-/Theme-Kompatibilität

Die verstärkte Nutzung von Nicht-latest-Streams von Discourse wird unsere Abhängigkeit vom discourse-compatibility-System erhöhen. Daher benötigen wir einige Verbesserungen am Kompatibilitätssystem.

Anstatt eine .discourse-compatibility-Datei auf main zu verwenden, könnten wir stattdessen implizite Kompatibilität basierend auf speziell benannten Branches/Tags unterstützen. Dies sollte viel einfacher sein, als Commit-Hashes manuell zu jonglieren. Zum Beispiel könnte ein Plugin Branches haben wie:

  • d-compat/v2026.1
  • d-compat/v2026.2
  • d-compat/v2026.3
  • main (verwendet für jede Discourse-Version, die keinen eigenen Branch hat)

Beim Installieren eines Plugins kann Discourse nach einem Branch suchen, der mit der aktuellen Version übereinstimmt. Wenn er existiert, wird er ausgecheckt. Andernfalls wird die .discourse-compatibility-Datei geprüft. Andernfalls wird der Standard-Branch ausgecheckt.

Wir können eine öffentliche GitHub-Aktion erstellen, die täglich auf jedem Theme/Plugin ausgeführt wird, nach neuen Discourse-Releases sucht und diese Branches automatisch erstellt. Jedes Theme/Plugin kann sich entscheiden, diese Auto-Pinning-Aktion zu nutzen, oder eine flexiblere Strategie verfolgen.

discourse.org-Hosting

Anfänglich wird unser gehostetes Angebot weiterhin die latest-Version von Discourse ausführen. In Zukunft werden wir Optionen für unsere Enterprise-Kunden prüfen, um eine „Release“-Version auszuwählen.

Standard-Installationsstandards

Anfänglich bleibt der Standard latest. Administratoren können sich auf die gleiche Weise für den neuen Release-Stream entscheiden, wie sie sich derzeit für stable entscheiden. Wir könnten in Zukunft einfachere Wechsel zwischen den Release-Streams untersuchen, sobald das System ausgereifter ist.

38 „Gefällt mir“

Ich bin etwas verwirrt. Also wird tests-passed aka latest (was ich als Standard annehme) das aktuellste sein (die häufigsten Updates erhalten; keine Änderung dort), aber der aktuelle beta-Branch, jetzt der release-Branch, wird sich immer noch so verhalten wie jetzt, d.h. eine “Gruppe” von Commits/Updates, dann wird der ESR (aka stable)-Branch eine größere “Gruppe” von beta/release-Updates sein?

Bedeutet das, dass release jetzt zur Standardoption wird, oder beziehen Sie sich mit “neueste Veröffentlichung” auf das “neueste Update im release-Branch”? Würde es dann einen Unterschied zwischen diesem und latest geben?

Danke!

1 „Gefällt mir“

beta ist derzeit ein Tag und erhält keine zurückportierten Korrekturen.

Mit diesem Vorschlag erhält jede versionierte Veröffentlichung ihren eigenen Branch und erhält Sicherheitspatches, solange sie „unterstützt“ wird. Benutzer könnten ihre Installation auf die spezifische Versionsnummer verweisen und sie nach einer weiteren Veröffentlichung weiter verwenden. Das ist mit dem aktuellen beta oder stable nicht möglich.

release wird ein Tag sein, der die neueste Veröffentlichung (einschließlich Patch-Releases) für Sicherheitspatches verfolgt.

Nein:

„neueste Veröffentlichung“ (oder einfach „release“) = der neueste Commit im neuesten Release-Branch

„latest“ = der neue Name für tests-passed

3 „Gefällt mir“

Danke, das klärt die Sache auf!

2 „Gefällt mir“

Das sieht nach einer positiven Entwicklung aus!

Wird es zum Zeitpunkt der Kennzeichnung von esr spezifische Tests für Upgrades von esr-previous auf esr geben? Solche Upgrades sollten meiner Meinung nach als reibungslose Upgrades gestaltet oder mit guten Beschreibungen versehen werden, wie sie so reibungslos wie möglich durchgeführt werden können.

4 „Gefällt mir“

Ja, Upgrades zwischen ESR-Versionen (oder tatsächlich jeder unterstützten Version) werden weiterhin nahtlos sein.

2 „Gefällt mir“

Nur eine kleine Bitte der Bequemlichkeit halber: Könnte der Zeiger (z. B. 2026.0) eher an den Monat gebunden werden, in dem eine Veröffentlichung erfolgt? (D. h. 2026.01 für Januar, 2026.02 für Februar usw.)

4 „Gefällt mir“

Das Problem bei der expliziten Bindung an einen Monat ist, dass wir einen Monat nicht überspringen oder zwei Versionen in einem Monat veröffentlichen können. Deshalb planen wir, dies als einfache, fortlaufende Nummer beizubehalten.

3 „Gefällt mir“

Ein Projekt, das ich intensiv nutze (mailcow), überspringt den Monat, wenn es keine wesentlichen Änderungen am Kern gibt.

Und das Zählen ab 0 wäre wirklich seltsam. Es ergibt für Programmierer durchaus Sinn, aber für technisch nicht versierte Personen nicht sehr viel Sinn.

2 „Gefällt mir“

Ich habe mich gefragt, was die erwähnte x.0-Version beinhaltet. Ich mag es sehr, sie mit dem Monat zu verknüpfen, damit man sofort erkennen kann, wann eine Version veröffentlicht wurde. Aber vielleicht spielt es keine Rolle, ob xx.8 im September, Dezember oder Juni veröffentlicht wurde. Ich kann mich kaum noch erinnern, welche Version wir jetzt haben, aber die Möglichkeit, sofort zu erkennen, ob jemand über einen Fehler von letzter Woche oder von vor einigen Monaten spricht, ohne wie jetzt in die Commits schauen zu müssen, wäre wirklich schön.

Ubuntu hat YY.04 und YY.10. Das funktioniert seit zwanzig Jahren. Monate zu überspringen scheint nicht schwer zu sein.

Das scheint eher ein Problem zu sein, obwohl man etwas wie 22.1a oder 22.01a machen könnte, wenn man zwei Veröffentlichungen pro Monat hätte.

6 „Gefällt mir“

Wir haben diese Strategie vor einiger Zeit auch für unsere Plattform eingeführt. Genau die gleiche, einschließlich Branching und Patching. Ich kann sie empfehlen.

Wir verwenden monatliche Releases. Also 1–12. Der Rhythmus hilft allen. Es gibt immer etwas zu releasen und niemand möchte sowieso zweimal im Monat den Branch cutten. Auch wenn ich sage „Ich verwende 2025.6“, weiß jeder, dass es derjenige von vor den Sommerferien ist.

7 „Gefällt mir“

Zuerst einmal, :rocket: das ist ein großartiger Schritt!

Nach reiflicher Überlegung habe ich zwei kleine Anmerkungen.

  1. git branch und viele andere Tools verstehen keine Versionierung und sortieren alphabetisch oder numerisch. In beiden Fällen landet 2026.10 zwischen 2026.1 und 2026.2. Inspiriert von Ubuntu schlage ich vor, eine führende Null für Releases und Patch-Releases einzuführen, wenn sie nur einstellig sind, sodass wir v2026.01, v2026.02 und v2026.10 hätten und das Universum wieder glücklich wäre.

  2. Die neue Methode zur Plugin-Kompatibilität erscheint übermäßig komplex und sehr fragil.

Wenn ich also eine neue Funktion in meinem Plugin erstelle, die v2026.3 benötigt, erstelle ich einen Branch und lege meine neue Funktionalität dort ab. Jetzt, da die Funktion erstellt wurde und mein Kunde zufrieden ist, kann ich mich ausruhen und meinen Urlaub genießen :palm_tree: :wine_glass: . Nach meinem dritten Glas Wein entscheidest du dich jedoch, v2026.4 zu veröffentlichen und mein Kunde beschließt, ein Update durchzuführen. Und zack, es gibt keinen v2026.4-Branch in meinem Plugin und die Funktionalität verschwindet :sob:

Daher würde ich dies nie verwenden und stattdessen weiterhin .discourse-compatibility verwenden.

9 „Gefällt mir“

Die Absicht ist umgekehrt. Die Kompatibilitäts-Branches sind nur für ‘veröffentlichte’ Branches von Discourse bestimmt. Discourse latest verwendet immer main Ihres Plugins. Dort entwickeln Sie neue Funktionen.

Die Geschichte wäre also:

Discourse veröffentlicht v2026.2. GitHub Actions in Ihrem Plugin erkennt dies automatisch und erstellt einen d-compat/v2026.2-Branch. Jetzt werden alle, die Discourse v2026.2 verwenden, die Version d-compat/v2026.2 Ihres Plugins verwenden.

Sie veröffentlichen eine neue Funktion auf main Ihres Plugins. Sie müssen sich keine Gedanken über Abwärtskompatibilität machen, da der main-Branch nur von Personen verwendet wird, die Discourse latest ausführen.

Dann, während Sie an Ihrem dritten Glas Wein nippen :wine_glass:, veröffentlicht Discourse v2026.3. Anfangs gibt es keinen Plugin-Branch für diese Version, daher wird main verwendet. Die Dinge funktionieren weiterhin wie für Personen auf latest.

Innerhalb weniger Stunden erkennt Ihre GitHub-Aktion die neue Version und friert d-compat/v2026.3 ein, bereit für Ihre nächste Plugin-Funktion, die ohne Abwärtskompatibilitätsprobleme auf main landet.

Dies ist im Wesentlichen der Workflow, den wir bei CDCK verwenden, um die stabile Kompatibilität von Themes/Plugins zu gewährleisten. Nach jeder stabilen Veröffentlichung führen wir ein Skript aus, das Hunderte unserer Themes/Plugins durchläuft und sie über .discourse-compatibility einfriert. Dieser Branch-basierte Vorschlag zielt darauf ab, eine leichtere Version dieses Workflows zu sein.

16 „Gefällt mir“

Das ist großartig, vielen Dank für die detaillierte Erklärung.

Klingt, als könnte ich noch ein viertes Glas Wein haben :wink:

15 „Gefällt mir“

Ich stimme dem, was andere gesagt haben, zu. Mir gefällt die Richtung der vorgeschlagenen Änderungen. Und ich denke, die vorgeschlagenen Branch-Namen sind viel intuitiver als die alten :+1:

Was mir noch nicht ganz klar ist, ist, wie der Upgrade-Prozess für die release- und esr-Branches funktionieren wird ( latest scheint unkompliziert zu sein). Sie erwähnen, dass zu jedem Zeitpunkt sowohl die aktuelle Version (nennen wir sie n) als auch die vorherige Version (n-1) unterstützt werden und dass ich als Administrator die Wahl habe, wann ich ein Upgrade durchführe.

Basierend auf meiner Erfahrung mit anderer Software würde ich benachrichtigt, wenn eine neue Release-Version (n+1) eintrifft. Und ich könnte dann entscheiden, ob ich ein Major-Upgrade durchführe (entspricht z.B. apt dist-upgrade unter Linux) oder ein Minor/Standard-Update durchführe (entspricht z.B. apt upgrade unter Linux) und bei Version n bleibe. Ist das etwas, das in das Discourse-Launcher-Skript integriert wird?

Außerdem verstehe ich den Wunsch, die Release-Zeremonie/den Prozess auf ein Minimum zu beschränken, aber meine Intuition wäre, dass sowohl normale als auch ESR-Releases zumindest etwas zusätzliche Tests erhalten, bevor sie veröffentlicht werden. Das mag aber auch daran liegen, dass ich zu lange im Enterprise-IT-Bereich gearbeitet habe :smile:

Schließlich frage ich mich, ob monatliche Releases tatsächlich “zu schnell” sind. Das ist zugegebenermaßen auch subjektiv, aber nach meiner eigenen Erfahrung bei der Verwaltung von IT-Sachen nebenbei als Freiwilliger habe ich möglicherweise nicht die Zeit für größere Updates jeden Monat. Und ausgehend davon habe ich mich gefragt, ob Sie vielleicht auch Ihr Leben als Entwickler von Discourse etwas einfacher gestalten könnten, indem Sie einfach vierteljährlich veröffentlichen und keine separaten esr-Branches haben, sondern nur release-Branches.

4 „Gefällt mir“

Das würde das Leben von Entwicklern von Themes und Plugins erschweren, denn in dieser (dieser) Situation habt ihr Zeitdruck, eure Themes und Plugins zu aktualisieren, und ansonsten erhaltet ihr keine Sicherheitsupdates. Eine ESR-Version würde diesen Druck nehmen.

4 „Gefällt mir“

Ich bin mir nicht sicher, ob ich das vollständig verstehe. Mein Verständnis aus den vorherigen Beiträgen war, dass die Erstellung eines Release-Version-Branches automatisch die Erstellung eines Plugin-Branches für diese Version auslösen würde. Daher würde ich davon ausgehen, dass das Zusammenführen von release und esr zu einer einzigen Version auch den Aufwand für Plugin- und Theme-Entwickler reduzieren würde, da jede Korrektur, die Sie pushen müssen, zu weniger Branches gepusht werden müsste (drei statt fünf). Aber vielleicht übersehe ich etwas?

2 „Gefällt mir“

Es geht nicht darum, wann der Theme-/Plugin-Autor einen Fix veröffentlicht, sondern darum, wann Discourse Core einen Sicherheitsfix hat.

Laut

ist der einzige Unterschied zwischen release und esr, dass esr 6 + 2 = 8 Monate lang Sicherheitsfixes erhält.

1 „Gefällt mir“

Mit den aktuellen Launcher-Tools und dieser neuen Branch-Struktur könnten Sie die Upgrade-Zeit wie folgt steuern:

  1. v2026.02 veröffentlicht
  2. Sie setzen version: release/v2026.02 in Ihrer app.yml-Datei
  3. v2026.03 veröffentlicht
  4. Sie führen einen Rebuild durch. Sie erhalten immer noch 2026.02 mit allen aktuellen Sicherheitspatches
  5. Wenn Sie bereit sind, wechseln Sie in der app.yml zu version: release/v2026.03

Aber das manuelle Bearbeiten dieser app.yml jeden Monat ist wirklich nicht ideal, daher hoffen wir, dass wir ein System entwickeln können, das den Prozess benutzerfreundlicher macht.

Der Prozess in der OP erlaubt es uns, die Branches als “Release Candidates” zu behandeln, bevor wir sie tatsächlich als Release kennzeichnen. Ich bin mir in diesem Stadium nicht sicher, ob und wie wir diese Funktion nutzen werden – ich denke, das wird sich entwickeln, wenn wir uns an das neue System gewöhnen.

Wir versuchen hier, ein Gleichgewicht zwischen der Geschwindigkeit der Discourse-Entwicklung und der Stabilität für Personen mit umfangreichen Anpassungen zu finden. Eine Verzögerung von mehr als 3 Monaten, um Funktionen für unsere Kunden verfügbar zu machen, ist keine Option. Wenn überhaupt, ist monatlich für uns eher langsam. Derzeit beabsichtigen wir immer noch, latest für die Mehrheit unseres Hostings zu verwenden.

Aber für diejenigen, die Discourse selbst hosten, verstehe ich natürlich den Wunsch nach selteneren Änderungen. Hier kommen also die ESR-Releases ins Spiel.

5 „Gefällt mir“

Das liegt am Plugin-/Theme-Autor. Entweder können sie die aktuelle Strategie beibehalten, bei der der main-Zweig des Plugins mit allen „freigegebenen“ Versionen von Discourse funktionieren muss. Oder sie können die automatische Verzweigungsstrategie verwenden, die die Kompatibilität erleichtert, aber auch bedeutet, dass Sie möglicherweise viel „Backporting“ in Ihrem Plugin durchführen müssen, falls kritische Fehler/Sicherheitskorrekturen auftreten.

Zu jedem Zeitpunkt gibt es drei „unterstützte“ Versionen von Discourse, plus latest. Kritische Korrekturen müssen daher in bis zu 4 Zweigen angewendet werden.

3 „Gefällt mir“