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

**URL:** https://meta.discourse.org/t/pinning-plugin-and-theme-versions-for-older-discourse-installs-d-compat-branches/272665
**Category:** Developer Guides
**Created:** [7월 26, 2023, 10:00오전 UTC](https://meta.discourse.org/t/pinning-plugin-and-theme-versions-for-older-discourse-installs-d-compat-branches/272665 "2023-07-26T10:00:42Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![Discourse](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/discourse/32/148734_2.png) [@Discourse](https://meta.discourse.org/u/Discourse)
#### Post date: [7월 26, 2023, 10:00오전 UTC](https://meta.discourse.org/t/pinning-plugin-and-theme-versions-for-older-discourse-installs-d-compat-branches/272665/1 "2023-07-26T10:00:42Z")

</div>

### 📖 배경

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

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

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

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

### 🌿 `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` 파일에 대해 전혀 수정할 필요가 없습니다.

### ⚙ 자동 브랜치 생성 (`create-d-compat-branch.yml`)

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

저장소가 구버전 스켈레톤에서 생성된 경우, 작동하도록 하려면 [`d-compat-branch.yml`](https://github.com/discourse/discourse-plugin-skeleton/blob/main/.github/workflows/d-compat-branch.yml) 파일을 `.github/workflows` 디렉터리에 복사하기만 하면 됩니다.

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

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

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

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

* * *

이 문서는 버전 관리됩니다 - 변경 사항을 [github에서](https://github.com/discourse/discourse/blob/main/docs/developer-guides/docs/03-code-internals/06-version-compatibility.md) 제안해 주세요.

---

<div class="post-metadata">

### Author: ![NateDhaliwal](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/natedhaliwal/32/313494_2.png) [@NateDhaliwal](https://meta.discourse.org/u/NateDhaliwal)
#### Post date: [9월 12, 2025, 10:37오전 UTC](https://meta.discourse.org/t/pinning-plugin-and-theme-versions-for-older-discourse-installs-d-compat-branches/272665/4 "2025-09-12T10:37:47Z")

</div>

버전이 `< 3.5.0.beta8-dev`인 경우, `3.5.0`을 포함하나요?

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [9월 15, 2025, 7:46오전 UTC](https://meta.discourse.org/t/pinning-plugin-and-theme-versions-for-older-discourse-installs-d-compat-branches/272665/5 "2025-09-15T07:46:37Z")

</div>

3.5.0은 사전 릴리스 버전인 "3.5.0.beta8-dev"보다 “높은” 것으로 간주됩니다.

ruby 콘솔에서 비교를 직접 시도해 볼 수 있습니다:

```ruby
> Gem::Version.new("3.5.0") < Gem::Version.new("3.5.0.beta8-dev")
=> false

```

---

<div class="post-metadata">

### Author: ![NateDhaliwal](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/natedhaliwal/32/313494_2.png) [@NateDhaliwal](https://meta.discourse.org/u/NateDhaliwal)
#### Post date: [9월 15, 2025, 9:44오전 UTC](https://meta.discourse.org/t/pinning-plugin-and-theme-versions-for-older-discourse-installs-d-compat-branches/272665/6 "2025-09-15T09:44:16Z")

</div>

이해했습니다. 설명해 주셔서 감사합니다!

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [5월 27, 2026, 9:30오전 UTC](https://meta.discourse.org/t/pinning-plugin-and-theme-versions-for-older-discourse-installs-d-compat-branches/272665/7 "2026-05-27T09:30:24Z")

</div>

이 문서는 [RFC: A new versioning strategy for Discourse](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536) 에서 설명한 새로운 `d-compat/*` 전략을 설명하도록 업데이트되었으며, 이제 사용할 수 있습니다.

---

<div class="post-metadata">

### Author: ![elmuerte](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/elmuerte/32/456517_2.png) [@elmuerte](https://meta.discourse.org/u/elmuerte)
#### Post date: [7월 17, 2026, 10:55오전 UTC](https://meta.discourse.org/t/pinning-plugin-and-theme-versions-for-older-discourse-installs-d-compat-branches/272665/8 "2026-07-17T10:55:43Z")

</div>

`d-compat/<YYYY>.<M>` 전략은 각 특정 릴리스마다 브랜치가 필요하다는 뜻이죠? `.discourse-compatibility` 구성처럼 범위 지정은 불가능합니다.

만약 ESR부터 최신 버전까지 동작하는 플러그인을 관리하고 있다고 가정해 봅시다. 개발을 새로운 ESR(구 ESR과 겹치는 경우)으로 옮길 때, 각 중간 버전에 대한 브랜치를 생성해야 하나요?

예를 들어, 현재 ESR은 2026.1, 릴리스 버전은 2026.6, 최신 버전은 2026.7이며, 2026.5는 여전히 지원되고 있다고 합시다. 구 ESR이 여전히 Discourse에서 지원되는 동안 플러그인을 새로운 ESR(2026.7)으로 이동할 때, 다음 브랜치를 생성해야 하나요?

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

여기서 .2부터 .5(포함)는 Discourse에서 EOL(지원 종료)되었지만, 여전히 사용 중인 사람들이 있을 수 있습니다.

아니면 특정 브랜치가 없는 경우 Discourse가 main 브랜치를 가정하는 대신 가장 적합한 브랜치를 찾나요?

예를 들어, 2026.5를 실행 중이고 유일한 브랜치가 `d-compat/2026.1`과 `d-compat/2026.6`인 경우, 어떤 브랜치가 사용되나요?

1. 가장 가까운 호환 버전인 `d-compat/2026.1`?
2. 특정 브랜치가 없으므로 `main`?

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [7월 17, 2026, 10:56오전 UTC](https://meta.discourse.org/t/pinning-plugin-and-theme-versions-for-older-discourse-installs-d-compat-branches/272665/9 "2026-07-17T10:56:56Z")

</div>

네, Discourse 코어 버전마다 하나의 브랜치가 필요합니다. 브랜치 생성을 자동화하는 것을 권장합니다:

> [@Discourse](#):
>
> 실제로는 이러한 브랜치를 수동으로 생성할 필요가 거의 없습니다. 기본 테마 및 플러그인 스켈레톤에는 매일 실행되어 Discourse 코어의 새 버전을 확인하고 필요에 따라 일치하는 `d-compat/<YYYY>.<M>` 브랜치를 푸시하는 [`d-compat-branch.yml` 워크플로](https://github.com/discourse/discourse-plugin-skeleton/blob/main/.github/workflows/d-compat-branch.yml)가 포함되어 있습니다.

> [@elmuerte](#):
>
> 2026.5를 실행 중이고 브랜치가 `d-compat/2026.1`과 `d-compat/2026.6`만 있는 경우, 어떤 브랜치가 사용되나요?

`main`이 사용됩니다.
