구형 Discourse 설치에서 플러그인 및 테마 버전 고정 (d-compat 브랜치)

:open_book: 배경

테마 및 플러그인 개발자는 일반적으로 Discourse의 latest 릴리스를 대상으로 개발하되, 하위 호환성에 대해 걱정하지 않으려는 경향이 있습니다. 하지만 구버전 Discourse를 실행 중인 사이트들은 해당 환경에서 작동하는 테마/플러그인 버전이 여전히 필요합니다.

이 간극을 메우기 위해, Discourse에 테마/플러그인의 이전 ‘고정(pinned)’ 버전을 체크아웃하도록 지시할 수 있습니다. 이를 위한 두 가지 메커니즘이 있으며, 순서대로 확인됩니다:

  1. 테마/플러그인 저장소 내 d-compat/<YYYY>.<M> git 브랜치 (주요 방법 — 모든 새로운 고정(pinning)에 권장됨).
  2. 저장소 루트 디렉터리에 있는 .discourse-compatibility YAML 파일 (원래 메커니즘이며, 여전히 폴백으로 지원됨).

두 가지가 모두 존재하는 경우, 브랜치가 우선합니다.

:herb: d-compat/<YYYY>.<M> 브랜치 시스템

Discourse 릴리스는 2025.5, 2025.6과 같은 날짜 기반 버전을 사용합니다. Discourse가 git에서 플러그인이나 테마를 업데이트할 때 저장소에 "내 버전과 일치하는 d-compat/<YYYY>.<M> 이름의 브랜치가 있습니까?"라고 질문합니다 (예: Discourse 2025.5.x의 경우 d-compat/2025.5). 해당 브랜치가 있으면, Discourse는 main 대신 해당 브랜치의 끝(tip)을 체크아웃합니다.

이 조회는 로컬 체크아웃이 저장소의 기본 브랜치에 있을 때만 실행됩니다. 다른 브랜치로 의도적으로 고정했다면, d-compat 로직은 건너뛰고 사용자의 고정이 존중됩니다.

이 시스템으로 이전 Discourse 버전을 지원하려면:

  1. 해당 버전에서 정상 동작이 확인된 커밋에서 d-compat/<YYYY>.<M> 이름의 브랜치를 생성합니다 (예: git checkout -b d-compat/2025.5 <commit>).
  2. origin에 푸시합니다. 브랜치가 실수로 삭제되는 것을 방지하기 위해 브랜치를 보호하는 것이 좋습니다.
  3. 백포트된 커밋을 해당 브랜치에 반영합니다. 2025.5.x를 실행 중인 Discourse 인스턴스는 다음 업데이트 시 자동으로 이를 가져오게 되며, 더 새로운 Discourse를 실행 중인 인스턴스는 기본 브랜치를 계속 추적합니다.

브랜치를 사용할 때 .discourse-compatibility 파일에 대해 전혀 수정할 필요가 없습니다.

:gear: 자동 브랜치 생성 (create-d-compat-branch.yml)

실제로는 이러한 브랜치를 수동으로 생성할 필요가 거의 없습니다. 기본 테마 및 플러그인 스켈레톤에는 Discourse 코어 새 버전을 확인하고 필요한 경우 일치하는 d-compat/<YYYY>.<M> 브랜치를 푸시하는 일일 실행 워크플로우인 d-compat-branch.yml 워크플로우가 포함되어 있습니다.

저장소가 구버전 스켈레톤에서 생성된 경우, 작동하도록 하려면 d-compat-branch.yml 파일을 .github/workflows 디렉터리에 복사하기만 하면 됩니다.

:git_merged: 수정 사항을 d-compat 브랜치에 백포트하기

기본 브랜치에 수정 사항을 반영했는데, 이전 Discourse 릴리스를 사용하는 사이트에도 해당 수정 사항이 필요할 경우:

  1. 대상 d-compat 브랜치에서 분기(branch)하고 수정 사항을 체리픽(cherry-pick)합니다:

    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. 베이스 브랜치d-compat/2025.5로 설정하여 PR을 엽니다 (main이 아닙니다). 다른 PR과 동일한 방식으로 검토 및 병합을 진행합니다.

  3. 수정 사항이 필요한 각 이전 d-compat/<YYYY>.<M> 브랜치에 대해 이 과정을 반복합니다.

2025.5.x를 실행 중인 사이트는 다음 업데이트 시 병합된 커밋을 가져오게 됩니다.

레거시 폴백: `.discourse-compatibility` 파일

일치하는 d-compat 브랜치가 없으면, Discourse는 저장소 루트에 있는 YAML .discourse-compatibility 파일로 폴백하여, Discourse 버전을 플러그인/테마의 git ref로 매핑합니다:

< 3.2.0.beta2-dev: abcde

Discourse는 실행 중인 코어 버전과 일치하는 가장 낮은 항목을 선택하므로, < 3.2.0.beta2-dev를 실행 중인 모든 사용자는 커밋 abcde를 체크아웃하게 됩니다. 버전 경계를 지정하려면 < (또는 연산자가 지정되지 않은 경우 기본값인 레거시 <=)를 사용합니다. 이는 브랜치 기반 시스템으로 원하는 것을 표현할 수 없는 경우에만 사용하세요.


이 문서는 버전 관리됩니다 - 변경 사항을 github에서 제안해 주세요.

17개의 좋아요

If the version is < 3.5.0.beta8-dev, would it include 3.5.0?

No. 3.5.0 is considered “higher” than the prerelease version “3.5.0.beta8-dev”.

You can always try out comparisons on a ruby console:

> Gem::Version.new("3.5.0") < Gem::Version.new("3.5.0.beta8-dev")
=> false
5개의 좋아요

Understood. Thanks for the explanation!

1개의 좋아요

This document has been updated to describe the new d-compat/* strategy from RFC: A new versioning strategy for Discourse, which is now available for use.

5개의 좋아요

The d-compat/<YYYY>.<M>strategy would require a branch for every specific release right? No range possible as with the .discourse-compatibility construction.

So if I was maintaining a plugin for which works from ESR to latest. When I am then moving the developments to the new ESR (which overlaps with the old-ESR) I would need to create branches for each intermediate version?

For example, right now ESR is 2026.1, release is 2026.6, and latest is 2026.7, still supported in 2026.5. When I’m moving my plugin to the new ESR (2026.7), while the old-ESR is still supported by Discourse. Would I need to create the branches:

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

Where .2 to .5 (including) are EOL by Discourse, but people could still be using it.

Or does Discourse find the most suitable branch if one is missing, instead of assuming the main branch?

For example, if I was running 2026.5 and the only branches are d-compat/2026.1 and d-compat/2026.6. Which branch would be used?

  1. d-compat/2026.1 which is the closest compatible version?
  2. main as there is no specific branch?
1개의 좋아요

Yes, one branch is required for each version of Discourse core. We recommend automating their creation:

main would be used.

2개의 좋아요