# 패키지 버전 관리와 릴리스 사이클

#### 버전 관리의 중요성

ROS 2 패키지는 특정 로봇 애플리케이션을 구성하는 중요한 단위로서, 버전 관리는 기능 개선과 유지보수를 체계적으로 수행하기 위한 핵심 절차다. 버전 정보는 다른 개발자나 사용자가 해당 패키지가 어떠한 변경 사항을 포함하는지, 그리고 특정 기능이 어느 버전에서 추가·삭제 또는 수정되었는지를 명확히 추적할 수 있게 해준다. 버전 관리를 통해 협업 환경에서 패키지를 일관성 있게 통합할 수 있으며, 필요에 따라 과거 버전으로 쉽게 롤백하거나 패치를 적용할 수 있다.

ROS 2 Humble 환경에서의 버전 관리는 다음과 같은 과정을 거쳐 체계적으로 수행된다.

1. 패키지의 **기능 변경 범위**에 따른 버전 번호 조정
2. **최신 기능 릴리스**와 **장기 지원(LTS) 버전**의 분리 운영
3. 브랜치 관리, 태깅, 릴리스 노트 기록 등 **소프트웨어 개발 생명주기(SDLC)** 전반의 프로세스 적용

#### 버전 번호 규칙과 $v\_\text{major}.v\_\text{minor}.v\_\text{patch}$ 형식

대부분의 ROS 2 패키지는 \*\*Semantic Versioning(시맨틱 버저닝)\*\*을 사용한다. 시맨틱 버저닝은 일반적으로 $v\_\text{major}.v\_\text{minor}.v\_\text{patch}$ 형식을 따른다.

* $v\_\text{major}$: 호환성이 깨지는 변경 사항(인터페이스나 API가 크게 변경되거나 삭제되는 경우 등)이 발생할 때 증가
* $v\_\text{minor}$: 하위 호환성을 유지하면서 기능이 추가되는 경우 증가
* $v\_\text{patch}$: 버그 수정이나 사소한 변경, 문서 보완 등 하위 호환성을 깨지 않는 단순 수정 시 증가

예를 들어 ROS 2 Humble에서 제공되는 여러 핵심 패키지들은 “0.7.1” 또는 “1.4.2” 등과 같은 방식으로 버전이 표시된다. `package.xml` 내의 `<version>` 태그를 이용하여 패키지 버전을 관리할 수 있으며, 릴리스 준비 단계에서 $v\_\text{major}$, $v\_\text{minor}$, $v\_\text{patch}$를 변경함으로써 사용자에게 변경 규모와 호환성 정보를 명확히 전달한다.

#### 패키지 릴리스와 태그 관리

릴리스를 수행할 때에는 소스 코드 저장소(예: GitHub, GitLab 등)에서 태그(tag)를 이용하여 특정 시점의 코드를 명시적으로 구분한다. 예를 들어 다음과 같은 방식으로 태그를 생성할 수 있다.

```bash
git tag -a v1.2.0 -m "Release version 1.2.0"
git push origin v1.2.0
```

이렇게 태그를 생성하면, ROS 2 패키지 빌드 툴(colcon, bloom 등)이나 CI(Continuous Integration) 파이프라인과 연동하여 해당 태그가 달린 상태의 코드를 패키징할 수 있다. 이후, 릴리스 노트(release note)에 변경 내용과 주의 사항을 정리하여 사용자와 개발자 모두가 패키지의 상태를 파악하기 용이하도록 한다.

#### 릴리스 사이클 전략

ROS 2 패키지를 배포할 때에는 단순히 “버전을 올리고 끝내는” 것이 아니라, **릴리스 사이클**을 계획적으로 수립·운영하는 것이 중요하다. 일반적으로 다음과 같은 유형의 릴리스 사이클 전략이 존재한다.

1. **정기(Periodic) 릴리스**: 매주, 격주, 혹은 매달과 같이 일정 주기로 정해진 날짜에 릴리스를 진행.
2. **기능(Function) 기반 릴리스**: 특정 기능이 완성될 때마다 릴리스를 진행.
3. **마일스톤(Milestone) 릴리스**: 프로젝트에서 중요한 마일스톤(예: 알파, 베타, RC)마다 진행.

ROS 2 환경에서는 대규모 프레임워크 업데이트가 1\~2년에 걸쳐 정기적으로 진행되며, 그 사이사이에 특정 기능 보강 및 버그 수정을 위한 릴리스가 추가로 이루어진다. 이를 통해 프로젝트 규모에 따라 **주기적 패키지 개선**과 **유연한 핫픽스(Hotfix) 대응**이 가능해진다.

#### 장기 지원(LTS) 버전과 단기 지원 버전

ROS 2에서는 **LTS(Long Term Support) 버전**과 **단기 지원 버전**이 병행하여 제공된다. 예를 들어 Humble 버전이 LTS에 해당한다면, 이 버전을 기준으로 안정적인 기능 지원과 장기 보안 업데이트가 이뤄진다. 반면 Rolling과 같은 단기 지원 버전은 최신 기능을 빠르게 반영하면서도 미래 버전으로 이어지는 기반이 된다. 이러한 구조는 각 로봇 개발 프로젝트가 요구하는 안정성, 호환성, 혁신성을 조합하여 적절히 선택할 수 있는 유연성을 제공한다.

* **LTS 버전(Humble 등)**
  * 장기적으로 안정적인 패키지 호환성과 신뢰도를 제공
  * 호환성 파괴가 없는 범위 내에서 보안 패치와 버그 수정
  * 잦은 변경에 따른 리스크가 적으므로 프로덕션 환경에 적합
* **단기 지원 버전(Rolling 등)**
  * 최신 기능과 개선을 신속히 반영
  * 사용자 피드백을 얻고, 차기 LTS로 이관하기 위한 실험적 성격
  * 변경 폭이 크고 자주 릴리스되므로, 사용 시 주기적인 업데이트 및 호환성 점검 필요

개별 ROS 2 패키지도 이러한 LTS 및 단기 지원 버전 정책에 맞춰 배포 전략을 수립한다. 예를 들어 LTS 기반의 패키지는 보안 취약점이나 심각한 버그만 신속 패치하고, 큰 기능 추가는 신중히 판단하여 제한적으로 반영한다. 반면 Rolling 같은 빠른 릴리스 버전에서는 다양한 실험적 기능과 대규모 내부 구조 변경을 우선 적용하여, 차후에 LTS로 가져갈 때 안정화 과정을 거치도록 한다.

#### 브랜치 전략과 릴리스 채널

버전 관리에서 빼놓을 수 없는 것이 **브랜치 전략**이다. 브랜치 전략은 패키지 개발, 테스트, 통합, 릴리스 과정을 유연하고 명료하게 유지하기 위한 체계를 제공한다. ROS 2 Humble 패키지를 포함한 여러 오픈소스 프로젝트는 다음과 같은 브랜치 전략을 참조하여 운영할 수 있다.

1. **Git Flow**
   * 개발 브랜치(`develop`), 메인 브랜치(`main` 또는 `master`), 기능 브랜치(feature), 릴리스 브랜치(release), 핫픽스 브랜치(hotfix) 등으로 구분
   * 큰 규모의 프로젝트에 적합하나 브랜치가 많아지므로 관리가 까다로울 수 있음
2. **GitHub Flow**
   * 메인 브랜치 하나와 기능 단위(feature) 브랜치만 존재
   * Pull Request를 통해 기능 추가·수정 후 코드 리뷰를 마치면 메인 브랜치에 병합
   * 비교적 간단하고 빠른 피드백 사이클이 장점
3. **Trunk-Based Development**
   * ‘Trunk(메인 브랜치)’를 중심으로 개발하며, 기능 구현 후 빠른 병합을 지향
   * 릴리스 브랜치는 버전 태그를 부여하여 관리
   * 기능 테스트와 코드 리뷰를 자동화해, 메인 브랜치가 늘 안정된 상태를 유지하도록 설계

또한, LTS 버전에 맞춘 독립적인 브랜치를 두어, LTS 환경을 위한 수정과 패치만 모아서 관리하는 방식도 널리 쓰인다. 이 경우 다음과 같은 채널(Channel)로 브랜치를 구분한다.

* **Stable(또는 LTS) 브랜치**: 보안 및 심각 버그 패치 중심
* **Current(또는 Dev) 브랜치**: 현재 개발 상황 반영, 새로운 기능과 변경 사항의 실험적 적용
* **Legacy(또는 Maintenance) 브랜치**: 더 이상 주요 개발이 이뤄지지 않으나 일부 사용자 지원이 필요한 역사의 버전

이러한 브랜치 전략과 릴리스 채널 구분을 통해, 개발팀은 동시에 서로 다른 수준의 안정성을 요구하는 패키지를 병행 관리할 수 있다.

#### 의존성 버전 고정(Version Pinning)

ROS 2 패키지는 서로 간에 의존성이 있으므로, 특정 버전에서 빌드가 원활히 이뤄지도록 \*\*의존성 버전 고정(version pinning)\*\*이 필수적인 경우가 많다. 예컨대 `package.xml`의 `<depend>` 태그나 `<exec_depend>` 태그에서 특정 버전 이상의 패키지가 필요하다는 정보를 명시하거나, `pip` 혹은 `apt` 같은 패키지 매니저를 통해 설치되는 라이브러리 버전을 제한한다.

* 예시: `<depend>rclcpp >= 8.0.0</depend>`
* 예시: `<depend>nav2_costmap_2d == 1.0.3</depend>`

이를 통해 개발자는 예측 가능성 높은 환경을 구성할 수 있으며, 패키지 릴리스 시에도 사용자가 “해당 패키지가 **정확히 어느 버전**과 호환되는지” 명확히 파악하도록 도움을 준다.

#### 패키지 릴리스 프로세스 예시

아래는 **버전 1.0.0** 릴리스를 목표로 하는 ROS 2 Humble 패키지의 예시 프로세스를 단순화한 것이다.

{% @mermaid/diagram content="flowchart TD
A\[개발 브랜치에서 기능 구현] --> B(코드 리뷰 및 테스트)
B --> C{"릴리스 \n 후보(RC) \n 선정"}
C -->|승인| D\[버전 태깅<br/>v1.0.0]
D --> E\[Release 노트 작성]
E --> F\["빌드 및 배포(Colcon, Bloom 등)"]
F --> G\[ROS Index 반영 및 사용자 공지]" %}

1. 개발 브랜치에서 기능 구현
   * 버전 1.0.0에 포함될 핵심 기능을 각 기능 브랜치에서 개발
   * 코드 리뷰와 CI를 거쳐 개발 브랜치에 병합
2. 릴리스 후보(RC) 선정
   * 모든 테스트와 검증을 마친 뒤 `release/v1.0.0-rc` 브랜치 또는 Git 태그로 릴리스 후보를 구분
3. 버전 태깅
   * 최종 릴리스가 확정된 시점에 `v1.0.0` 태그를 부여
4. Release 노트 작성
   * 변경 사항, 주의 사항, 버그 수정, 향후 계획 등을 릴리스 노트로 정리
5. 빌드 및 배포
   * 빌드 도구(colcon, bloom)와 자동화 파이프라인을 통해 ROS 2 패키지를 빌드 후 패키지 저장소에 업로드
6. ROS Index 반영 및 사용자 공지
   * ROS Index 사이트(rosindex.github.io 등)에 등록하여 널리 알림
   * ROS Discourse 등 공식 커뮤니티와 개발 문서를 통해 사용자에게 공지

#### 릴리스 단계별 검증과 품질 확보

ROS 2 패키지를 배포할 때는 단순히 코드를 빌드하고 태그를 달아 배포하는 과정만 거치는 것이 아니다. 여러 단계의 **검증 과정**을 통해 품질을 확보하고, 안정성을 보장하기 위한 절차가 필수적으로 뒤따른다.

**단위 테스트(Unit Test)**:

* 각 함수나 클래스 레벨에서 동작 검증
* gtest, ament\_cmake\_gtest 등 ROS 2에서 지원하는 테스트 프레임워크를 사용
* 아래와 같이 CMakeLists.txt에 테스트를 등록 가능

```cmake
# CMakeLists.txt 예시
find_package(ament_cmake_gtest REQUIRED)

ament_add_gtest(my_package_test test/test_my_package.cpp)
target_link_libraries(my_package_test
  ${PROJECT_NAME}
)
ament_target_dependencies(my_package_test
  rclcpp
)
```

* 버전 릴리스 전 해당 테스트를 모두 통과해야만 다음 단계 진행

**통합 테스트(Integration Test)**:

* 여러 패키지가 상호작용할 때 정상 동작하는지 여부 검증
* 토픽, 서비스, 액션, 매니저 등에서 정상적인 메시지 교환이나 로직 흐름이 이뤄지는지 확인
* 시뮬레이션(예: Gazebo, Ignition, Webots 등) 환경과 연동하여 대규모 통합 시험을 수행하기도 함

**회귀 테스트(Regression Test)**:

* 이전에 정상 동작했던 기능이 새로운 버전에서 깨졌는지 확인
* 과거 버전과 동일한 테스트 시나리오·입력·환경을 반복 적용
* 자동화 스크립트를 만들어 CI/CD에서 정기적으로 실행

**성능 테스트(Performance Test)**:

* 메시지 처리 지연(latency), 시스템 자원 사용량(CPU, RAM), 통신 대역폭 등 성능 지표를 계측
* 로봇 시스템은 실시간 대응이 중요한 경우가 많으므로, 성능 하락 여부를 면밀히 관찰해야 함
* 필요 시 라즈베리 파이 같은 임베디드 보드나 산업용 컴퓨터에서도 실제로 테스트

**보안 점검(Security Audit)**:

* 의존성 라이브러리에 보안 취약점이 없는지, 패치가 누락되지 않았는지 확인
* 비인가된 접근 방지, DDS(Datadistribution Service) 보안 설정, 인증·암호화 기술 적용 등 점검
* CI 툴이나 소스 분석 툴을 활용해 자동화할 수도 있음

이러한 검증 과정을 **단계별로 세분화**하고, 각 단계를 모두 통과해야만 릴리스가 확정되도록 자동화(CI 파이프라인, DevOps 등)하는 것이 이상적이다. ROS 2 Humble 패키지는 위 테스트 단계를 충실히 거침으로써, 실제 로봇 현장에서도 신뢰성 높게 운영될 수 있다.

#### 디프리케이션(Deprecation) 정책

ROS 2 패키지는 코어 메시지나 API가 변경될 때, 완전히 삭제하기 전 **디프리케이션(Deprecated) 단계**를 거치며 사용자에게 경고한다. 이 과정에서 버전 정책을 세심히 설정하여 사용자와 하위 호환성 문제가 최소화되도록 조정한다.

디프리케이트(Deprecated) 태그 부여:

* 패키지 내의 메시지 정의(.msg), 서비스 정의(.srv), 함수 등에 경고 메시지를 추가
* ROS 2 로그(예: `RCLCPP_WARN`) 등을 통해 호출 시점에 경고 출력

마이너 버전에서 예고:

* $v\_\text{minor}$ 버전대에서 “다음 메이저 버전에서 해당 기능은 사라질 예정”임을 안내
* 문서(`README.md`, `package.xml`)에 명시하여 사용자 혼선을 방지

메이저 버전에서 제거:

* 새롭게 출시되는 $v\_\text{major}$ 버전으로 올라갈 때 기존 인터페이스를 완전히 삭제
* 사용자는 이전 버전을 사용할지, 혹은 새로운 API로 마이그레이션할지를 결정

이러한 과정을 거침으로써 “호환성을 유지하되, 불필요한 기능이나 API를 계속 유지하지 않는” 균형 잡힌 진행이 가능하다.

#### ROS 빌드 팜(Build Farm) 연동과 Bloom 릴리스

ROS 2 패키지 릴리스 프로세스에서 핵심이 되는 툴 중 하나가 **Bloom**이다. Bloom은 ROS 공식 빌드 팜(ROS Build Farm)과 연동하여 ROS 2 패키지를 자동 빌드 및 배포하는 데 활용된다. 이를 통해 개발자는 별도의 복잡한 스크립트 작성 없이도 꾸준히 새 버전을 릴리스할 수 있다.

**Bloom 설정(bloom-release 명령)**:

* ROS 빌드 팜이 패키지를 인식하도록, 소스 코드 저장소(Git) URL과 브랜치 정보를 Bloom 설정 파일에 기입
* 원하는 ROS 2 버전(Humble, Rolling 등)과 Ubuntu 배포판(Jammy 등)을 지정
* 예시:

```bash
bloom-release --rosdistro humble --track humble my_package
```

* 위 명령 실행 시, Bloom이 요구하는 파일(`track.yaml` 등)이 자동 생성되거나 보완 작업을 유도함

**Debian 메타 정보 생성**:

* Bloom은 `package.xml` 정보를 바탕으로 Debian 패키지 메타 정보를 생성
* 이후 로컬에서 자동 빌드 테스트가 수행되며, 성공 시 Git 저장소에 릴리스 브랜치 및 태그가 추가됨

**ROS 빌드 파арм의 자동 빌드**:

* Git 저장소에 등록된 새로운 버전(태그 등)을 빌드 파ーム이 자동으로 감지
* 다양한 환경(AMD64, ARM64 등)에서 병렬 빌드가 이루어지며, 문제 발생 시 CI 로그를 통해 디버깅 가능
* 빌드 파암이 성공하면, apt 저장소(예: packages.ros.org)에 새로운 버전의 패키지가 업로드

**사용자 측 업데이트**:

* 사용자는 `$ sudo apt update && sudo apt upgrade` 명령을 통해 새 버전의 패키지를 설치하거나 업데이트 가능
* 이 과정에서 의존성 충돌이 있으면 자동으로 경고 메시지를 보여주므로, 명확하게 버전 충돌을 파악할 수 있음

이처럼 **Bloom을 활용해 중앙화된 빌드 환경**에서 ROS 2 패키지를 안정적으로 릴리스하고, 사용자는 apt 등 패키지 관리자를 통해 손쉽게 설치·업데이트할 수 있다.

#### 소스 배포 vs 바이너리 배포

ROS 2 패키지 릴리스 시, 두 가지 주요 방식이 존재한다.

**소스 배포(Source Distribution)**:

* Git 저장소 등을 통해 소스 코드를 직접 다운로드 받아 빌드
* ROS 2 빌드 도구(colcon, ament 등)를 사용해 환경 설정 후 컴파일
* 커스텀 환경이나 임베디드 환경 등에서 유연한 설정이 가능
* 빌드 시간 및 의존성 관리에 대한 부담이 있음

**바이너리 배포(Binary Distribution)**:

* `$ apt install ros-humble-my-package` 같은 식으로 패키지를 바로 설치
* 빌드 파암에서 미리 빌드된 결과물(바이너리)이므로 설치가 빠름
* 표준적인 Ubuntu/Debian 환경에서 즉시 사용 가능
* 수정·재빌드가 필요할 때는 소스 배포가 적합

ROS 2 LTS 버전(Humble 등)은 안정적인 환경에서 **바이너리 배포**가 가장 흔하다. 그러나 최신 기능 테스트나 특수 아키텍처(예: Raspberry Pi OS 32bit, Yocto Linux 등)를 지원할 때에는 **소스 배포** 방식으로 빌드하여 사용하는 일이 많다.

#### Changelog 및 릴리스 노트 자동화

**릴리스 노트**와 **Changelog**는 릴리스마다 달라진 점, 버그 수정, 새 기능, 삭제·변경된 API 등을 체계적으로 정리하는 문서다. 제대로 정리된 문서는 다른 개발자와 사용자 모두에게 매우 유용하다.

Changelog 관리 도구:

* ROS 2 생태계에서 `catkin_generate_changelog`, `ros2_generate_changelog` 같은 스크립트를 통해 자동 생성 가능
* Git 커밋 로그를 분석해 “추가(Added) / 수정(Changed) / 제거(Removed) / 보안 패치(Security)” 등 섹션별 목록을 뽑아주는 방식

릴리스 노트 템플릿:

* 버전, 날짜, 주요 변경 사항, 호환성 주의 사항, 알려진 문제(known issues) 등을 템플릿으로 만들어 매 릴리스 시 채워넣음
* 마일스톤 기반, 혹은 브랜치별로 Changelog를 자동 병합하여 릴리스 노트에 포함

이러한 문서를 **버전 태그**와 함께 GitHub 릴리스 페이지에 업로드하거나, 패키지 홈페이지(ROS Index)에서 확인 가능하게 하면 릴리스 히스토리 관리가 수월해진다.

#### 릴리스 실패 대응 전략

ROS 2 패키지 릴리스 후 의도치 않은 문제(크래시, 성능 저하, 의존성 충돌 등)가 발견될 수 있다. 이를 대비해 빠르게 대응할 수 있는 전략이 필요하다.

핫픽스(Hotfix) 릴리스:

* 버전명을 $v\_{patch}$로 빠르게 올려서 문제를 즉시 수정
* 예: 1.2.0 릴리스 후 치명적 버그 발견 시 1.2.1로 핫픽스

롤백(Rollback):

* 이전 태그로 되돌려 패키지를 다시 빌드·배포
* LTS 버전인 경우 더욱 신중하게 진행

긴급 브랜치 생성:

* Git Flow 전략에서 핫픽스 브랜치(`hotfix/*`)를 만들어 문제를 해결한 뒤 메인 브랜치와 LTS 브랜치에 병합

사용자 공지:

* ROS Discourse, GitHub Releases, 프로젝트 문서를 통해 “어떤 문제가 있었고 어떻게 해결되었는지” 공지
* 업데이트 전까지 임시 방안(Workaround)을 안내하기도 함

이런 과정을 거쳐야 패키지가 신뢰도 높게 유지될 수 있다. 특히 물리적인 로봇 시스템에서는 장애가 실제 위험으로 이어질 수 있기 때문에, 개발자는 **릴리스된 버전에 문제가 없는지** 항시 모니터링해야 한다.
