# 앱 배포 피드

> 데스크톱 앱이 업데이트를 받는 Sparkle appcast 피드와 다운로드 주소, 그리고 누가 무엇을 받는지.

Gujo 에서 산 데스크톱 앱은 app 호스트의 배포 피드로 업데이트를 받습니다. 피드는 Sparkle 2 형식이고, 요청마다 서버가 그 사람이 받을 수 있는 릴리스만 골라 만듭니다.

## 피드 주소

```text
https://app.gujo.ai/distribution/v1/products/{id}/appcast.xml
```

```bash
curl https://app.gujo.ai/distribution/v1/products/42/appcast.xml \
  -H "Authorization: Bearer $GUJO_DEVICE_KEY"
```

- `{id}` 는 앱 상품의 숫자 id 입니다.
- 앱 상품의 피드는 언제나 `Authorization: Bearer <기기 키>` 가 필요하고, 그 키에 `device.install` 능력이 있어야 합니다. 상품 하나에 묶인 키라면 그 상품이어야 합니다.
- 응답은 `application/rss+xml; charset=UTF-8` 이고 소비자는 Sparkle 2.9 이상입니다.
- 기기 키를 본 응답은 `Cache-Control: no-store, private` 와 `Vary: Authorization` 을 답니다. 세션과 쿠키는 쓰지 않습니다.
- 피드 주소는 설치된 앱의 `SUFeedURL` 이라 앱을 다시 배포하지 않고는 바꿀 수 없습니다. 그래서 이 경로는 바뀌지 않습니다.

## 누가 무엇을 받나

앱 상품은 상태마다 받을 수 있는 사람과 실리는 릴리스가 정해져 있습니다.

| 상품 상태 | 받을 수 있는 사람 | 실리는 릴리스 |
|---|---|---|
| 초안(`draft`) | 기기 키 + 그 상품 이용권(시험 설치용) | dev 와 승인된 릴리스 |
| 게시(`published`) | 기기 키 + 그 앱의 이용권, 또는 그 앱을 여는 Gujo Pass 구독 | 승인된 stable·beta·alpha(dev 제외) |
| 내림(`retired`) | 게시와 같은 조건 + 내린 시각 전에 서버에 남은 설치 기록 | 내린 시각까지 승인된 마지막 stable 하나 |

- Gujo Pass 는 앱 상품만 엽니다. 에셋·강의는 Pass 로 열리지 않습니다.
- stable·beta·alpha 릴리스는 등록된 뒤 사람이 승인해야 피드에 실립니다. 승인을 기다리는 릴리스는 누구의 피드에도 나오지 않습니다.
- 내린 앱의 설치 기록은 서버가 그 기록을 처음 받은 시각으로 판정합니다. 기기가 보내는 설치 시각은 보지 않습니다.

## 404 로만 답합니다

없는 상품, 앱이 아닌 상품, 모르는 채널, 위 판정에 걸린 요청은 모두 404 입니다. 401 이나 403 으로 답하면 그 상품과 릴리스가 있다는 사실이 드러나기 때문입니다. 피드가 404 라면 키, 키의 `device.install` 능력, 이용권이나 Pass 를 차례로 확인합니다.

## 채널

채널은 `stable`·`beta`·`alpha`·`dev` 입니다.

- 쿼리 없는 주소는 통합 피드입니다. 게시된 모든 채널의 릴리스를 최신 게시 순으로 싣고, stable 이 아닌 항목에만 `<sparkle:channel>` 태그를 넣습니다. 앱은 설치본 설정(`allowedChannels`)으로 볼 채널을 고릅니다.
- `?channel=<c>` 주소는 채널을 피드 주소에 넣었던 옛 빌드 호환용입니다. 그 채널 항목만 태그 없이 싣습니다.
- 항목 수 제한은 채널마다 적용합니다.

## 내려받기

```text
https://app.gujo.ai/distribution/v1/releases/{id}/download
```

- 피드와 같은 기기 키로 부르고, 판정도 피드와 같습니다.
- 통과하면 302 로 짧은 수명의 서명 주소를 줍니다. 응답은 `Cache-Control: no-store, private` 이고 `Set-Cookie` 가 없습니다.
- 없거나 회수됐거나 승인을 기다리는 릴리스, 지금 상태에서 실리지 않는 릴리스는 404 입니다.
- 서버에 배포 저장소가 설정되지 않았으면 503 `distribution_not_configured` 입니다.

서명 주소에는 기기 키를 다시 보내지 않습니다.

## 릴리스 등록

릴리스 등록은 Gujo 의 발행 도구만 합니다. 이 사이트의 키로는 등록할 수 없습니다.
