Versions von Plugins und Themes für ältere Discourse-Installationen fixieren (d-compat-Branches)

:open_book: Hintergrund

Entwickler von Themes und Plugins möchten in der Regel die latest-Version von Discourse als Ziel haben, ohne sich um die Abwärtskompatibilität kümmern zu müssen. Aber Sites, die ältere Discourse-Versionen ausführen, benötigen weiterhin eine Version des Themes/Plugins, die für sie funktioniert.

Um diese Lücke zu schließen, kann Discourse angewiesen werden, eine ältere, „gepinnte“ Version des Themes/Plugins auszuchecken. Es gibt zwei Mechanismen dafür, die in dieser Reihenfolge geprüft werden:

  1. d-compat/<YYYY>.<M>-Git-Branches im Repository des Themes/Plugins (die primäre Methode – für alle neuen Pins empfohlen).
  2. Eine .discourse-compatibility-YAML-Datei im Stammverzeichnis des Repositorys (der ursprüngliche Mechanismus, der weiterhin als Fallback unterstützt wird).

Wenn beide existieren, hat der Branch Vorrang.

:herb: Das d-compat/<YYYY>.<M>-Branch-System

Discourse-Releases verwenden datumsbasierte Versionen wie 2025.5, 2025.6 usw. Wenn Discourse ein Plugin oder Theme aus Git aktualisiert, fragt es das Repository: „Hast du einen Branch mit dem Namen d-compat/<YYYY>.<M>, der meiner Version entspricht?“ (z. B. d-compat/2025.5 für Discourse 2025.5.x). Wenn ja, checkt Discourse die Spitze dieses Branches statt main aus.

Die Suche wird nur ausgeführt, wenn der lokale Checkout auf dem Standard-Branch des Repositorys ist. Wenn du bewusst auf einen anderen Branch gepinnt hast, wird die d-compat-Logik übersprungen und dein Pin respektiert.

Um eine ältere Discourse-Version mit diesem System zu unterstützen:

  1. Erstelle einen Branch mit dem Namen d-compat/<YYYY>.<M> aus einem Commit, der bekanntermaßen mit dieser Version funktioniert (z. B. git checkout -b d-compat/2025.5 <commit>).
  2. Schiebe ihn auf origin. Möglicherweise möchtest du den Branch vor versehentlichem Löschen schützen.
  3. Bringe alle Backport-Commits in diesen Branch. Discourse-Instanzen auf 2025.5.x werden sie automatisch beim nächsten Update übernehmen; Instanzen mit neuerem Discourse werden weiterhin den Standard-Branch verfolgen.

Wenn du Branches verwendest, musst du .discourse-compatibility überhaupt nicht anfassen.

:gear: Automatisierte Branch-Erstellung (create-d-compat-branch.yml)

In der Praxis musst du diese Branches selten manuell erstellen. Die Standard-Skeletons für Themes und Plugins enthalten einen d-compat-branch.yml-Workflow, der täglich ausgeführt wird, nach neuen Versionen von Discourse Core sucht und bei Bedarf passende d-compat/<YYYY>.<M>-Branches schiebt.

Wenn dein Repository aus einer älteren Kopie der Skeletons erstellt wurde, kopiere einfach die d-compat-branch.yml-Datei in dein .github/workflows-Verzeichnis, damit sie funktioniert.

:git_merged: Backporting eines Fixes in einen d-compat-Branch

Wenn du einen Fix auf dem Standard-Branch gelandet hast, der auch Sites mit einer älteren Discourse-Version erreichen muss:

  1. Erstelle einen Branch vom Ziel-d-compat-Branch und cherry-picke den Fix:

    git fetch origin
    git checkout -b backport/my-fix-2025.5 origin/d-compat/2025.5
    git cherry-pick <commit-sha>
    git push -u origin backport/my-fix-2025.5
    
  2. Eröffne einen PR mit d-compat/2025.5 als Basis-Branch (nicht main). Lass ihn auf dieselbe Weise überprüfen und zusammenführen wie jeden anderen PR.

  3. Wiederhole dies für jeden älteren d-compat/<YYYY>.<M>-Branch, der den Fix benötigt.

Sites auf 2025.5.x werden den zusammengeführten Commit bei ihrem nächsten Update übernehmen.

Legacy-Fallback: die `.discourse-compatibility`-Datei

Wenn kein passender d-compat-Branch existiert, fällt Discourse auf eine YAML-Datei .discourse-compatibility im Stammverzeichnis des Repositorys zurück, die Discourse-Versionen auf Git-Refs deines Plugins/Themas abbildet:

< 3.2.0.beta2-dev: abcde

Discourse wählt den niedrigsten Eintrag, der der laufenden Kernversion entspricht, sodass jeder, der < 3.2.0.beta2-dev ausführt, den Commit abcde auscheckt. Verwende < (oder das Legacy-<=, der Standard, wenn kein Operator angegeben wird), um die Versionsgrenze zu spezifizieren. Greife nur dazu, wenn das branchbasierte System nicht ausdrücken kann, was du benötigst.


Dieses Dokument wird versioniert verwaltet – schlage Änderungen auf GitHub vor.

17 „Gefällt mir“

Wenn die Version < 3.5.0.beta8-dev ist, würde sie 3.5.0 enthalten?

Nr. 3.5.0 gilt als „höher“ als die Vorabversion „3.5.0.beta8-dev“.

Sie können Vergleiche jederzeit in einer Ruby-Konsole ausprobieren:

> Gem::Version.new("3.5.0") < Gem::Version.new("3.5.0.beta8-dev")
=> false
5 „Gefällt mir“

Verstanden. Danke für die Erklärung!

1 „Gefällt mir“

Dieses Dokument wurde aktualisiert, um die neue d-compat/*-Strategie aus RFC: A new versioning strategy for Discourse zu beschreiben, die nun zur Verfügung steht.

5 „Gefällt mir“

Die Strategie d-compat/<YYYY>.<M> würde doch einen Branch für jede spezifische Version erfordern, oder? Es ist kein Bereich möglich, wie bei der Konstruktion .discourse-compatibility.

Wenn ich also ein Plugin pflege, das von ESR bis zur neuesten Version funktioniert: Wenn ich die Entwicklungen dann zur neuen ESR (die mit der alten ESR überlappt) verschiebe, müsste ich für jede Zwischenversion Branches erstellen?

Zum Beispiel: Derzeit ist ESR 2026.1, Release 2026.6 und die neueste Version 2026.7, wobei 2026.5 noch unterstützt wird. Wenn ich mein Plugin zur neuen ESR (2026.7) verschiebe, während die alte ESR von Discourse noch unterstützt wird, müsste ich die folgenden Branches erstellen:

  • d-compat/2026.1
  • d-compat/2026.2
  • d-compat/2026.3
  • d-compat/2026.4
  • d-compat/2026.5
  • d-compat/2026.6

Wobei .2 bis .5 (einschließlich) von Discourse als EOL (End of Life) gelten, aber Nutzer sie möglicherweise noch verwenden.

Oder findet Discourse den am besten passenden Branch, wenn einer fehlt, anstatt den Hauptbranch anzunehmen?

Zum Beispiel: Wenn ich Version 2026.5 betreiben würde und die einzigen Branches d-compat/2026.1 und d-compat/2026.6 wären, welcher Branch würde verwendet?

  1. d-compat/2026.1, da dies die nächstliegende kompatible Version ist?
  2. main, da es keinen spezifischen Branch gibt?
1 „Gefällt mir“

Ja, für jede Version des Discourse-Kerns ist ein eigener Branch erforderlich. Wir empfehlen, deren Erstellung zu automatisieren:

main würde verwendet.

2 „Gefällt mir“