핀 모델 — 태그·커밋·패키지 버전
coui 는 한 저장소(pub workspace)에서 여러 패키지를 낸다. release-please 가 패키지마다 따로 버전을 올리고 태그를 붙인다.
1. coui 의 버전 체계#
coui 는 한 저장소(pub workspace)에서 여러 패키지를 낸다. release-please 가 패키지마다 따로 버전을 올리고 태그를 붙인다.
| 사실 | 결과 |
|---|---|
태그 이름은
<패키지>-v<버전>
(
coui_flutter-v0.151.1
,
coui_core-v0.149.0
)
|
태그만 보고는 다른 패키지의 어느 태그와 짝인지 알 수 없다 |
| 한 릴리스 커밋에는 그 릴리스에서 바뀐 패키지의 태그만 붙는다 | flutter 만 바뀐 릴리스 커밋에는 core·web 태그가 없다 |
| 패키지 버전은 서로 따로 올라간다 |
같은 커밋이
coui_flutter 0.151.1
·
coui_core 0.149.0
·
coui_web 0.150.0
이다
|
| 같은 번호 태그가 같은 커밋이라는 보장이 없다 |
coui_flutter-v0.134.0
과
coui_core-v0.134.0
은 하루 차이 나는 다른 커밋이다.
coui_flutter-v0.134.0
커밋 시점 core 자체 버전은 0.133.0 이었다
|
커밋별 전 패키지 버전은 루트 .release-please-manifest.json 에 있다 |
버전을 알고 싶으면 태그가 아니라 그 커밋의 매니페스트를 읽는다 |
coui_flutter·coui_web 은 형제 coui_core 를 workspace 제약(
any
)으로 참조하고, coui_core 는
publish_to: none
이다
|
앱에서 플랫폼 패키지만 git 으로 받으면 coui_core 가 hosted 로 풀리려다 소스 충돌 — 형제를 모두 override 에 둔다 |
같은 번호 태그가 우연히 같은 커밋인 버전도 있다(예: v0.131.0). 그래서 한 번 통과했다고 방식이 안전한 것은 아니다. 매 교체마다 커밋으로 풀어 비교한다.
2. 올바른 핀 계산#
-
목표를 주 패키지 태그로 고른다. 주 패키지는 앱이 직접 쓰는 플랫폼 패키지다 — Flutter 앱은
coui_flutter, Jaspr 웹 앱은coui_web.- "최신"은
git tag -l '<주 패키지>-v*'를 semver 로 정렬해 고른다. gh api repos/<owner>/coui/releases의 첫 항목을 쓰지 않는다 — 목록 순서가 발행 순서가 아니라서 더 늦게 나온 릴리스가 뒤에 있을 수 있다.- 두 패키지를 다 쓰는 앱(혼합)은 두 주 패키지의 최신 태그 가운데 다른 쪽 태그 커밋을 조상으로 가진 태그를 고른다(그 커밋에 다른 쪽의 최신 변경도 들어 있다). 그런 태그가 없으면
--target으로 직접 지정하고, 태그 없는 커밋은 쓰지 않는다.
- "최신"은
- 그 태그를 커밋 C 로 푼다:
git rev-parse <주 패키지>-vX.Y.Z^{commit}. - 앱이 쓰는 형제 패키지 전부를 C 로 고정한다. 형제 태그를 따로 찾지 않는다.
-
C 에서 주 패키지 pubspec 의 요구치를 읽어 앱 환경과 비교한다 — coui_flutter 는
environment.flutter, coui_web 은environment.sdk와dependencies.jaspr(web-apps.md §2). - C 의 매니페스트에서 형제 버전을 읽어 핀 주석에 남긴다.
coui_pin.py plan 이 1~5 를 한 번에 한다(주 패키지는 앱 pubspec 에서 판별, --package 로 강제).
3. 핀 표기 방식#
| 방식 | 예 | 장점 | 위험 | 권장 |
|---|---|---|---|---|
| 커밋 SHA 하나 + 태그 주석 | ref: <40자 SHA> # = coui_flutter-vX.Y.Z 태그 커밋(coui_core 자체 버전 A.B.C) |
불변식을 구조로 보장. 태그가 없는 형제도 문제없음 | 사람이 버전을 주석으로만 읽음 | 기본값 |
| 패키지별 태그 이름 | ref: coui_flutter-vX.Y.Z / ref: coui_core-vX.Y.Z |
읽기 쉬움, 자동 bump 스크립트가 다루기 쉬움 | 같은 번호 태그가 다른 커밋이면 깨짐. 태그 없는 형제는 표기 불가 | coui_pin.py check 를 게이트로 둘 때만 |
| 브랜치 이름 / ref 없음 | ref: main |
없음 | 매 pub get 마다 바뀌어 재현 불가 |
쓰지 않음 |
| 앱 전용 보존 태그 | ref: <app>/patched-vX |
coui 기본 브랜치에 없는 앱 전용 패치 커밋을 잃지 않음 | 업스트림과 갈라져 올리기 어려움 | 패치가 업스트림에 들어가기 전 임시로만 |
태그 방식을 쓰다가 같은 번호 태그가 다른 커밋인 릴리스를 만나 SHA 로 돌아간 실제 이관 사례가 있다. 태그 방식을 유지할 거라면 교체 때마다 check 로 형제 커밋이 같은지 확인하고, 같은 커밋에 형제 태그가 없으면 그 형제만이라도 SHA 로 쓴다.
4. 자동 bump 스크립트를 쓰는 앱#
자동으로 coui 핀을 올리는 워크플로가 있다면 다음을 확인한다.
- 최신 릴리스를
/releases[0]로 고르지 않는가 — semver 로 고른다. - 형제 태그가 없는 릴리스 커밋을 만나면 flutter 만 올리고 나머지를 그대로 두지 않는가 — 그러면 형제 커밋이 갈라진다. 형제 태그가 없으면 SHA 를 쓴다.
- 교체 후 형제 ref 가 전부 같은 커밋인지 검사하는가 —
coui_pin.py check를 그대로 쓸 수 있다. - 실패가 조용히 쌓이지 않는가 — 토큰 만료 등으로 매일 실패하는 동안 아무도 모를 수 있다. 실패 알림을 둔다.
- 자동으로 열린 PR 은 BREAKING 을 흡수하지 않는다 — 큰 격차는 이 스킬의 홉 절차로 사람이 올린다.
5. 핀 주석 규약#
핀 옆 주석에는 다음만 남긴다. 긴 이력은 PR·이슈로 보낸다(주석이 옛 핀을 계속 "지금 핀"으로 적는 드리프트가 흔하다).
dependency_overrides:
coui_core:
git:
url: https://github.com/<owner>/coui.git
ref: <SHA> # = coui_flutter-vX.Y.Z 태그 커밋(coui_core 자체 버전 A.B.C)
path: packages/coui_core
coui_flutter:
git:
url: https://github.com/<owner>/coui.git
ref: <SHA> # = coui_flutter-vX.Y.Z 태그 커밋
path: packages/coui_flutter
- 불변식 한 줄(형제는 같은 커밋)과 올리는 방법 링크(이 스킬, 프로젝트 프로필)를 섹션 머리 주석에 둔다.
- "지금 핀: …" 처럼 값 자체를 주석에 반복해 적지 않는다 — ref 줄이 곧 값이다.