RFC : Une nouvelle stratégie de versioning pour Discourse

Nous prévoyons d’introduire un nouveau système de versioning pour Discourse. Notre objectif est de fournir plus de choix et de prévisibilité aux administrateurs de communauté, tout en maintenant notre vélocité de développement. Nous ajustons également certains termes pour mieux nous aligner sur d’autres logiciels.

Ce document évoluera au fur et à mesure que nous recevrons des commentaires, commencerons à implémenter le système, puis étendrons l’utilisation des nouveaux flux de publication.

Si vous avez des commentaires/suggestions à ce stade, veuillez nous en faire part en répondant à ce sujet !


Objectifs

  1. Introduire des « publications » plus régulières pour Discourse, qui offrent un équilibre entre la vitesse de développement et la stabilité.

  2. Continuer à fournir environ 6 publications par an qui sont prises en charge pendant une période prolongée.

  3. Fournir une prise en charge chevauchante pour les publications régulières et les publications à support étendu, afin que les administrateurs aient plus de flexibilité quant au moment des mises à jour, tout en continuant à recevoir les mises à jour de sécurité critiques.

  4. Minimiser la cérémonie autour des « publications ». Autant que possible doit être automatisé et ne doit pas ralentir l’expérience du développeur principal. Les publications ESR sont identiques aux autres publications.

  5. La dénomination et la procédure doivent correspondre aux normes de l’industrie, afin qu’il soit plus facile d’expliquer aux développeurs et aux utilisateurs finaux.

Aperçu général

  • Couper environ une publication par mois. La version « majeure » est l’année en cours, et la version « mineure » s’incrémente à chaque publication. Le numéro de version de correctif sera incrémenté pour tous les correctifs rétroportés.

    par exemple, la première publication de 2026 serait v2026.0, la suivante serait v2026.1, etc.

    Les publications recevront des correctifs critiques pendant deux cycles de publication complets. par exemple, la prise en charge de 2026.0 se poursuivra jusqu’à la publication de 2026.2.

  • Environ tous les 6 mois, déclarer l’une de ces publications comme une publication à support étendu (ESR). Les versions ESR restent prises en charge pendant 2 publications après la déclaration de la prochaine ESR.

    par exemple, si v2026.0 est ESR, et v2026.6 est la prochaine ESR, alors la prise en charge de v2026.0 se terminera lors de la publication de v2026.8. En supposant une cadence mensuelle, cela représenterait un chevauchement de 2 mois dans la prise en charge ESR.

  • Fournir des correctifs critiques pour latest, la publication la plus récente, la publication précédente et toutes les versions ESR actives.

  • Renommer la branche tests-passed en latest.

Exemple de graphique des périodes de prise en charge sur un an :

gantt
    title Publications et périodes de prise en charge de Discourse (janv. 2026 – janv. 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

Implémentation

  • Chaque publication aura une branche créée à partir de latest. Celles-ci seront nommées et conservées indéfiniment. Par exemple, v2026.1 aurait une branche nommée release/2026.1.

  • Chaque publication de correctif sera taguée. par exemple, v2026.1.0, v2026.1.1, etc.

  • La dernière publication sera taguée release. La dernière ESR sera taguée esr.

  • La publication précédente sera taguée release-previous. L’ESR active précédente (le cas échéant) sera taguée esr-previous.

  • Pour des raisons de compatibilité ascendante, les tags correspondant aux flux de publication existants seront aliasés vers le nouvel équivalent le plus proche. stableesr. betarelease. tests-passedlatest.

    Ceux-ci seront considérés comme obsolètes, et nous visons à les supprimer à l’avenir. En particulier, « beta » est problématique car il donne l’impression que Discourse n’est pas prêt pour la production.

  • Sur latest, le numéro de version sera la version en cours de développement, suffixée par -latest. par exemple, 2026.3.0-latest.

Processus de publication automatisé

Chaque mois, une action GitHub ouvrira une nouvelle PR contenant un seul commit qui incrémente version.rb sur main vers la prochaine version -latest.

Une fois qu’un humain aura fusionné la PR, une autre action GitHub détectera le passage de main à la prochaine version -latest et créera une branche pour la publication terminée. Essentiellement, cette branche devient un « candidat à la publication ». Une autre PR automatisée sera ouverte contre la branche de publication avec une mise à jour pour supprimer le suffixe -latest de version.rb, et ainsi la « publier ».

Généralement, nous fusionnerons ces deux PR rapidement. Mais avoir des PR séparées pour la création et la finalisation de la publication nous donne la possibilité de résoudre tout problème dans la branche avant la finalisation.

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

Séparément, un autre workflow d’actions GitHub surveillera les commits rétroportés vers les branches de publication. Lorsqu’ils sont trouvés, une nouvelle PR sera générée pour incrémenter la version de correctif sur cette branche. Un humain pourra décider quand fusionner ces PR.

Toutes ces automatisations maintiendront automatiquement à jour les différents tags (release, release-previous, esr, esr-previous, ainsi que les alias de compatibilité ascendante).

Correctifs de sécurité

Le flux de travail des correctifs de sécurité reste largement le même, à l’exception du fait que nous devons maintenant apporter les correctifs dans deux des trois endroits suivants :

  • latest

  • esr

  • esr-previous :new_button:

  • release :new_button:

  • release-previous :new_button:

(Rappelez-vous, selon l’illustration précédente, il ne s’agit que de deux des trois car esr-previous est pris en charge, le nouvel esr est identique à release ou release-previous, et nous supprimons la prise en charge de esr-previous lorsque ce n’est plus le cas).

Lors de l’introduction d’un correctif de sécurité dans latest, un tag latest-security-fix sera automatiquement déplacé vers ce commit. docker_manager sera mis à jour pour surveiller ce tag et inviter les administrateurs à mettre à jour. Cela nous permet de publier et de notifier les correctifs de sécurité sans avoir besoin d’accélérer une augmentation de version.

Traductions

Actuellement, les branches stable et tests-passed peuvent être traduites dans CrowdIn, et les résultats sont régulièrement intégrés. Dans le nouveau système, nous prévoyons initialement que latest et release soient traduisibles dans CrowdIn.

Idéalement, au moment où release deviendra release-previous ou esr, les traductions seront stabilisées. S’il y a une demande pour des traductions continues de ces versions, alors c’est quelque chose qui pourrait être envisagé à l’avenir.

Compatibilité des plugins/thèmes

L’augmentation de l’utilisation des flux autres que latest de Discourse augmentera notre dépendance au système discourse-compatibility. Nous avons donc besoin d’améliorations du système de compatibilité.

Au lieu d’utiliser un fichier .discourse-compatibility sur main, nous pourrions plutôt prendre en charge la compatibilité implicite basée sur des branches/tags nommés de manière spéciale. Ce devrait être beaucoup plus facile que de jongler manuellement avec les hachages de commit. Par exemple, un plugin pourrait avoir des branches comme :

  • d-compat/v2026.1
  • d-compat/v2026.2
  • d-compat/v2026.3
  • main (utilisé pour toute version de Discourse qui n’a pas sa propre branche)

Lors de l’installation d’un plugin, Discourse peut vérifier l’existence d’une branche correspondant à la version actuelle. Si elle existe, la récupérer. Sinon, vérifier le fichier .discourse-compatibility. Sinon, récupérer la branche par défaut.

Nous pouvons créer une action GitHub publique qui s’exécute quotidiennement sur chaque thème/plugin, vérifie les nouvelles versions de Discourse et crée automatiquement ces branches. Chaque thème/plugin pourrait choisir d’utiliser cette action d’épinglage automatique, ou opter pour une stratégie plus « flottante ».

Hébergement discourse.org

Initialement, notre offre hébergée continuera à exécuter la version latest de Discourse. À l’avenir, nous explorerons des options pour que nos clients de niveau entreprise puissent sélectionner une version « release ».

Paramètres par défaut de l’installation standard

Initialement, le paramètre par défaut restera latest. Les administrateurs pourront opter pour le nouveau flux de publication de la même manière qu’ils optent actuellement pour stable. Nous pourrions explorer des commutations plus faciles entre les flux de publication à l’avenir, une fois que le système sera plus mature.

38 « J'aime »

Je suis un peu confus. Donc, tests-passed alias latest (qui, je suppose, est le défaut) sera le plus à jour (recevant les mises à jour les plus fréquentes ; aucun changement là-bas), mais la branche beta actuelle, maintenant la branche release, se comportera toujours comme elle le fait maintenant, c’est-à-dire un « groupe » de commits/mises à jour, puis la branche ESR (alias stable) sera un plus grand « groupe » de mises à jour beta/release ?

Cela signifie-t-il que release devient maintenant l’option par défaut, ou quand vous dites « dernière version », vous faites référence à la « dernière mise à jour sur la branche release » ? Y aurait-il alors une différence entre cela et latest ?

Merci !

1 « J'aime »

beta est actuellement une étiquette et ne reçoit aucune correction rétroportée.

Avec cette proposition, chaque version publiée aura sa propre branche et recevra des correctifs de sécurité tant qu’elle sera « prise en charge ». Les utilisateurs pourraient choisir de pointer leur installation vers le numéro de version spécifique et continuer à l’utiliser après la publication d’une autre version. Ce n’est pas possible avec les branches beta ou stable actuelles.

release sera une étiquette qui suit la dernière version (y compris les versions de correctifs) pour les correctifs de sécurité.

Non :

« dernière version » (ou simplement « release ») = le commit le plus récent sur la branche de version la plus récente

« latest » = le nouveau nom pour tests-passed

3 « J'aime »

Merci, c’est plus clair !

2 « J'aime »

Cela ressemble à une évolution positive !

Y aura-t-il des tests spécifiques des mises à niveau de esr-previous vers esr au moment où esr sera étiqueté ? Je soutiendrais que ces mises à niveau devraient être conçues pour être des mises à niveau fluides, ou pour avoir de bonnes descriptions sur la façon de les effectuer aussi fluidement que possible.

4 « J'aime »

Oui, les mises à niveau entre les versions ESR (ou toute autre version prise en charge) resteront transparentes.

2 « J'aime »

Juste une petite requête pour plus de commodité, le pointeur (par exemple, 2026.0) pourrait-il être plutôt lié au mois où une version est poussée ? (C’est-à-dire 2026.01 pour janvier, 2026.02 pour février, etc.)

4 « J'aime »

Le problème avec le fait de lier explicitement les choses à un mois est que nous ne pourrons pas sauter un mois, ou publier deux versions en un mois. C’est pourquoi nous prévoyons de conserver un simple numéro d’incrémentation.

3 « J'aime »

Un projet que j’utilise intensivement (mailcow) saute le mois lorsqu’il n’y a pas de changement significatif dans le cœur.

Et compter à partir de 0 serait vraiment étrange. Cela a parfaitement du sens pour les programmeurs, mais pas beaucoup de sens pour les personnes non techniques.

2 « J'aime »

Je me demandais à propos de la version x.0 mentionnée. J’aime beaucoup lier cela au mois pour que l’on puisse dire tout de suite quand une version est sortie. Mais peut-être que cela n’a pas d’importance si xx.8 est sorti en septembre, décembre ou juin. J’ai du mal à me souvenir de la version sur laquelle nous sommes actuellement, cependant, donc pouvoir dire tout de suite si quelqu’un parle d’un bug de la semaine dernière ou d’il y a quelques mois sans avoir à regarder le commit comme je le fais maintenant, serait vraiment bien.

Ubuntu a YY.04 et YY.10. Cela fonctionne depuis vingt ans. Sauter des mois ne semble pas difficile.

Cela semble être plus un problème, bien que vous puissiez faire quelque chose comme 22.1a ou 22.01a si vous deviez avoir deux versions en un mois.

6 « J'aime »

Il y a quelque temps, nous avons également commencé à utiliser cette stratégie pour notre plateforme. Exactement la même chose, y compris le branching et le patching. Je peux le recommander.

Nous utilisons des versions mensuelles. Donc, il y a 1 à 12. Le rythme aide tout le monde. Il y a toujours quelque chose à publier et personne ne veut de toute façon couper la branche deux fois par mois. De plus, quand je dis « J’utilise 2025.6 », tout le monde sait que c’est celle d’avant les vacances d’été.

7 « J'aime »

Tout d’abord, :rocket: c’est un grand pas !

Après mûre réflexion, j’ai deux remarques mineures.

  1. git branch et de nombreux autres outils ne comprennent pas le versionnement et trieront par ordre alphabétique ou numérique. Dans les deux cas, 2026.10 se retrouvera entre 2026.1 et 2026.2. Inspiré par Ubuntu, je propose d’introduire un zéro initial pour les versions et les versions mineures lorsqu’elles ne comportent qu’un seul chiffre, de sorte que nous aurions v2026.01, v2026.02 et v2026.10, et alors l’univers sera à nouveau heureux.

  2. la nouvelle méthode de compatibilité des plugins semble trop complexe et très fragile.

Donc, si je crée une nouvelle fonctionnalité dans mon plugin qui nécessite v2026.3, je crée une branche et y mets ma nouvelle fonctionnalité. Maintenant que la fonctionnalité a été créée et que mon client est satisfait, je peux me reposer et profiter de mes vacances :palm_tree: :wine_glass:. Cependant, après mon troisième verre de vin, vous décidez de publier v2026.4 et mon client décide de mettre à jour. Et pouf, il n’y a pas de branche v2026.4 dans mon plugin et la fonctionnalité disparaît :sob:

Je n’utiliserais donc jamais cela et je continuerais à utiliser .discourse-compatibility à la place.

9 « J'aime »

L’intention est inverse. Les branches de compatibilité sont uniquement pour les branches ‘publiées’ de Discourse. Discourse latest utilisera toujours main de votre plugin. C’est là que vous développerez de nouvelles fonctionnalités.

L’histoire serait donc la suivante :

Discourse publie v2026.2. Les actions GitHub sur votre plugin le détectent automatiquement et créent une branche d-compat/v2026.2. Désormais, toute personne utilisant Discourse v2026.2 utilisera la version d-compat/v2026.2 de votre plugin.

Vous publiez une nouvelle fonctionnalité sur main de votre plugin. Vous n’avez pas besoin de penser à la rétrocompatibilité, car la branche main n’est utilisée que par les personnes exécutant Discourse latest.

Ensuite, pendant que vous sirotez votre troisième verre de vin :wine_glass:, Discourse publie v2026.3. Initialement, il n’y a pas de branche de plugin pour cette version, donc main sera utilisée. Les choses continueront de fonctionner comme avant pour les personnes sur latest.

En quelques heures, votre action GitHub détecte la nouvelle version et gèle d-compat/v2026.3, prête pour que votre prochaine fonctionnalité de plugin arrive sur main sans souci de rétrocompatibilité.

C’est essentiellement le flux de travail que nous utilisons chez CDCK pour gérer la compatibilité stable des thèmes/plugins. Après chaque version stable, nous avons un script pour parcourir nos centaines de thèmes/plugins et les geler via .discourse-compatibility. Cette proposition basée sur les branches vise à être une version plus légère de ce flux de travail.

16 « J'aime »

C’est génial, merci pour l’explication détaillée.

On dirait que je peux me permettre un quatrième verre de vin :wink:

15 « J'aime »

Je rejoins ce que d’autres ont dit, j’aime la direction des changements proposés. Et je pense que les noms de branches proposés sont beaucoup plus intuitifs que les anciens :+1:

Ce qui n’est pas encore tout à fait clair pour moi, c’est comment le processus de mise à niveau fonctionnera pour les branches release et esr (la branche latest semble simple). Vous mentionnez qu’à chaque instant, la version actuelle (n) et la version précédente (n-1) seront prises en charge, et qu’en tant qu’administrateur, j’aurai le choix de la mise à niveau.

D’après mon expérience avec d’autres logiciels, lorsqu’une nouvelle version (n+1) arrive, je suis informé de sa disponibilité. Et je peux alors décider de faire une mise à niveau majeure (équivalente à par exemple apt dist-upgrade sous Linux) ou une mise à jour mineure/standard (équivalente à par exemple apt upgrade sous Linux) et rester sur la version n. Est-ce quelque chose qui sera intégré au script du lanceur Discourse ?

De plus, je comprends le désir de minimiser la cérémonie/le processus de publication, mais mon intuition serait que les versions normales et ESR reçoivent au moins un peu de tests supplémentaires avant d’être publiées. Cela pourrait être dû au fait que j’ai trop longtemps travaillé dans l’informatique d’entreprise :smile:

Enfin, je me demande si les publications mensuelles ne sont pas en fait “trop rapides”. C’est certes subjectif, mais d’après ma propre expérience dans la gestion d’infrastructures informatiques en tant que bénévole, je n’aurai peut-être pas le temps d’effectuer des mises à jour majeures chaque mois. Et partant de là, je me demandais si vous ne pourriez pas également vous simplifier la vie en tant que développeurs de Discourse en publiant simplement trimestriellement, et en n’ayant pas de branches esr séparées, mais uniquement des branches release.

4 « J'aime »

Cela rendra la vie des développeurs de thèmes et de plugins plus difficile, car dans cette (cette) situation, vous subissez une pression temporelle pour mettre à jour vos thèmes et plugins, et sinon vous n’aurez aucune mise à jour de sécurité. Une version ESR soulagera cette pression.

4 « J'aime »

Je ne suis pas sûr de bien suivre. D’après les messages précédents, la création d’une branche de version de publication déclencherait automatiquement la création d’une branche de plugin pour cette version. Mon hypothèse serait donc que la fusion de release et esr en une seule réduirait également les efforts des constructeurs de plugins et de thèmes, car chaque fois que vous avez besoin d’appliquer un correctif, il devrait être appliqué à moins de branches (trois au lieu de cinq). Mais peut-être que je manque quelque chose ?

2 « J'aime »

Il ne s’agit pas de savoir quand l’auteur du thème/plugin publie un correctif, mais de savoir quand le cœur de Discourse a un correctif de sécurité.

Selon

la seule différence entre release et esr est que esr reçoit des correctifs de sécurité pendant 6 + 2 = 8 mois.

1 « J'aime »

Avec les outils de lancement actuels et cette nouvelle structure de branches, vous pourriez contrôler le moment des mises à niveau en faisant quelque chose comme ceci :

  1. v2026.02 publiée
  2. Vous définissez version: release/v2026.02 dans votre fichier app.yml
  3. v2026.03 publiée
  4. Vous exécutez une reconstruction. Vous obtenez toujours la version 2026.02, avec les correctifs de sécurité récents.
  5. Lorsque vous êtes prêt, vous passez à version: release/v2026.03 dans app.yml

Mais modifier manuellement ce app.yml chaque mois n’est vraiment pas idéal, nous espérons donc pouvoir concevoir un système qui rendra le processus plus convivial.

Le processus décrit dans le message initial nous permet de traiter les branches comme des « candidats à la publication » avant de les marquer comme une publication. Je ne suis pas sûr exactement si/comment nous utiliserons cette capacité à ce stade - je pense que c’est quelque chose qui évoluera à mesure que nous nous habituerons au nouveau système.

Nous essayons de trouver un équilibre entre la vélocité du développement de Discourse et la stabilité pour ceux qui ont des personnalisations étendues. Avoir un délai de 3 mois ou plus pour que les fonctionnalités parviennent à nos clients n’est pas une option. En tout cas, mensuellement est plutôt lent pour nous. Pour le moment, nous avons toujours l’intention d’utiliser latest pour la majorité de notre hébergement.

Mais bien sûr, pour les personnes qui hébergent Discourse elles-mêmes, je comprends le désir d’avoir des changements moins fréquents. C’est là qu’interviennent les publications ESR.

5 « J'aime »

C’est à l’auteur du plugin/thème de décider. Soit il continue avec la stratégie actuelle, où la branche main du plugin doit fonctionner avec toutes les versions « publiées » de Discourse. Soit il utilise la stratégie de branchement automatique, qui facilite la compatibilité, mais signifie également que vous devrez peut-être faire beaucoup de « rétroportage » dans votre plugin en cas de corrections de bugs critiques/de sécurité.

À tout moment, il existe trois versions « prises en charge » de Discourse, plus latest. Les corrections critiques devront donc être appliquées dans jusqu’à 4 branches.

3 « J'aime »