# 배포 내역

Tuist는 의미 있는 변경 사항이 메인 브랜치에 병합될 때마다 새 버전을 자동으로 게시하는 지속적 릴리스 시스템을 사용합니다. 이 접근 방식은
관리자의 수동 개입 없이도 개선 사항이 사용자에게 신속하게 전달되도록 합니다.

## 개요

세 가지 주요 구성 요소를 지속적으로 출시하고 있습니다:
- **Tuist CLI** - 명령줄 도구
- **Tuist 서버** - 백엔드 서비스
- **튜이스트 앱** - macOS 및 iOS 앱(iOS 앱은 TestFlight에만 지속적으로 배포됩니다. 자세한 내용은
  [여기](#app-store-release)를 참조하세요.

각 컴포넌트에는 메인 브랜치로 푸시할 때마다 자동으로 실행되는 자체 릴리스 파이프라인이 있습니다.

## 작동 방식

### 1. 커밋 규칙

기존 커밋](https://www.conventionalcommits.org/)을 사용하여 커밋 메시지를 구성합니다. 이를 통해 툴링이 변경
사항의 특성을 이해하고 버전 범프를 결정하며 적절한 변경 로그를 생성할 수 있습니다.

형식: `유형(범위): 설명`

#### 커밋 유형과 그 영향

| 유형      | 설명           | 버전 영향            | 예                             |
| ------- | ------------ | ---------------- | ----------------------------- |
| `feat`  | 새로운 기능 또는 기능 | 마이너 버전 범프(x.Y.z) | `feat(cli): Swift 6 지원 추가`    |
| `수정`    | 버그 수정        | 패치 버전 범프(x.y.Z)  | `수정(앱): 프로젝트 열기 시 충돌 해결`      |
| `문서`    | 문서 변경 사항     | 릴리스 없음           | `문서: 업데이트 설치 가이드`             |
| `스타일`   | 코드 스타일 변경    | 릴리스 없음           | `스타일: 스위프트포맷을 사용한 포맷 코드`      |
| `리팩터링`  | 코드 리팩토링      | 릴리스 없음           | `refactor(server): 인증 로직 간소화` |
| `perf`  | 성능 개선        | 패치 버전 범프         | `perf(cli): 종속성 해결 최적화`       |
| `테스트`   | 테스트 추가/변경    | 릴리스 없음           | `테스트: 캐시에 대한 단위 테스트 추가`       |
| `chore` | 유지 관리 작업     | 릴리스 없음           | `잡일: 종속성 업데이트`                |
| `ci`    | CI/CD 변경 사항  | 릴리스 없음           | `CI: 릴리스용 워크플로 추가`            |

#### 획기적인 변화

브레이킹 변경은 메이저 버전 범프(X.0.0)를 트리거하며 커밋 본문에 표시해야 합니다:

```
feat(cli): change default cache location

BREAKING CHANGE: The cache is now stored in ~/.tuist/cache instead of .tuist-cache.
Users will need to clear their old cache directory.
```

### 2. 변경 감지

각 컴포넌트는 [git cliff](https://git-cliff.org/)을 사용합니다:
- 마지막 릴리스 이후의 커밋 분석
- 범위별 커밋 필터링(cli, 앱, 서버)
- 릴리스 가능한 변경사항이 있는지 확인
- 변경 로그 자동 생성

### 3. 릴리스 파이프라인

릴리스 가능한 변경 사항이 감지된 경우:

1. **버전 계산**: 파이프라인이 다음 버전 번호를 결정합니다.
2. **변경 로그 생성**: 커밋 메시지에서 변경 로그를 생성하는 git cliff
3. **빌드 프로세스**: 컴포넌트 빌드 및 테스트
4. **릴리스 생성**: 아티팩트로 GitHub 릴리스가 생성됩니다.
5. **배포**: 업데이트는 패키지 관리자(예: CLI용 Homebrew)에 푸시됩니다.

### 4. 범위 필터링

각 컴포넌트는 관련 변경 사항이 있을 때만 릴리스됩니다:

- **CLI**: `(cli)` 범위 또는 범위 없음으로 커밋합니다.
- **앱**: ` (앱)` 범위로 커밋
- **서버**: ` (서버)` 범위로 커밋합니다.

## 좋은 커밋 메시지 작성하기

커밋 메시지는 릴리스 노트에 직접적인 영향을 미치므로 명확하고 설명적인 메시지를 작성하는 것이 중요합니다:

### Do:
- 현재 시제 사용: "추가된 기능"이 아닌 "기능 추가"
- 간결하지만 상세하게 설명하세요.
- 변경 사항이 컴포넌트별인 경우 범위를 포함하세요.
- 해당되는 경우 참조 문제: `fix(cli): 빌드 캐시 문제 해결(#1234)`

### 하지 마세요:
- "버그 수정" 또는 "코드 업데이트"와 같은 모호한 메시지 사용
- 서로 관련이 없는 여러 변경 사항을 하나의 커밋에 혼합
- 속보 변경 정보를 포함하는 것을 잊지 마세요.

### 획기적인 변화

변경 내용을 중단하려면 커밋 본문에 `BREAKING CHANGE:` 을 포함하세요:

```
feat(cli): change cache directory structure

BREAKING CHANGE: Cache files are now stored in a new directory structure.
Users need to clear their cache after updating.
```

## 릴리스 워크플로

릴리스 워크플로에 정의되어 있습니다:
- `.github/workflows/cli-release.yml` - CLI 릴리스
- `.github/workflows/app-release.yml` - 앱 릴리스
- `.github/workflows/server-release.yml` - 서버 릴리스

각 워크플로:
- 메인으로 푸시에서 실행
- 수동으로 트리거 가능
- 변경 사항 감지를 위해 git 클리프 사용
- 전체 릴리스 프로세스를 처리합니다.

## 릴리스 모니터링

다음을 통해 릴리스를 모니터링할 수 있습니다:
- [GitHub 릴리스 페이지](https://github.com/tuist/tuist/releases)
- 워크플로 실행을 위한 GitHub 작업 탭
- 각 컴포넌트 디렉터리의 변경 로그 파일

## 혜택

이러한 지속적인 릴리스 접근 방식은 다음과 같은 이점을 제공합니다:

- **빠른 배송**: 병합 후 변경 사항이 사용자에게 즉시 전달
- **병목 현상 감소**: 수동 릴리스를 기다릴 필요 없음
- **명확한 커뮤니케이션**: 커밋 메시지에서 자동화된 변경 로그
- **일관된 프로세스**: 모든 구성 요소에 대해 동일한 릴리스 흐름
- **품질 보증**: 테스트된 변경 사항만 릴리스됩니다.

## 문제 해결

릴리스가 실패한 경우:

1. 실패한 워크플로에 대한 GitHub 작업 로그를 확인하세요.
2. 커밋 메시지가 기존 형식을 따르는지 확인하세요.
3. 모든 테스트가 통과되었는지 확인
4. 컴포넌트가 성공적으로 빌드되었는지 확인

즉시 릴리스해야 하는 긴급한 수정 사항입니다:
1. 커밋의 범위가 명확한지 확인
2. 병합 후 릴리스 워크플로우 모니터링
3. 필요한 경우 수동 릴리스를 트리거합니다.

## 앱 스토어 출시

CLI와 서버는 위에서 설명한 지속적인 릴리스 프로세스를 따르지만, **iOS 앱(** )은 Apple의 앱 스토어 검토 프로세스로 인해
예외입니다:

- **수동 릴리스**: iOS 앱 릴리스는 앱 스토어에 수동으로 제출해야 합니다.
- **검토 지연**: 각 릴리스는 1~7일이 소요될 수 있는 Apple의 검토 프로세스를 거쳐야 합니다.
- **일괄 변경**: 일반적으로 여러 변경 사항은 각 iOS 릴리스에 함께 번들로 제공됩니다.
- **테스트 플라이트**: App Store 출시 전에 TestFlight를 통해 베타 버전을 배포할 수 있습니다.
- **릴리스 노트**: 앱스토어 가이드라인에 맞게 작성해야 합니다.

iOS 앱은 여전히 동일한 커밋 규칙을 따르고 변경 로그 생성에 git cliff를 사용하지만 사용자에게 실제로 배포되는 것은 덜 빈번한 수동
일정에 따라 이루어집니다.
