# GitHub 아카이빙 가이드

`synapse plugin publish` 명령으로 플러그인을 배포하면, SDK가 플러그인 소스 코드를 GitHub에 자동으로 아카이빙할 수 있습니다 — 리포지토리(repository) 생성, 코드 푸시, 버전 태그 부여, ZIP 자산이 포함된 GitHub 릴리스 생성까지 한 번에 처리합니다.

## 플러그인 라이프사이클 컨텍스트[​](#플러그인-라이프사이클-컨텍스트 "플러그인 라이프사이클 컨텍스트에 대한 직접 링크")

`synapse plugin` CLI는 플러그인을 스캐폴딩부터 배포까지 안내합니다. **아카이빙(Archiving)** 은 모든 릴리스에 버전이 부여된, 변경 불가능한 소스 오브 트루스(source-of-truth)를 GitHub에 남기는 라이프사이클 단계로, 런타임 백엔드에 배포하는 단계와는 구분됩니다.

| #     | 단계        | CLI                                                                                          | 동작                                                                                                                                             |
| ----- | ----------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| 1     | Create      | `synapse plugin create`                                                                      | 새 플러그인 디렉토리를 대화형으로 스캐폴딩합니다.                                                                                                |
| 2     | Develop     | `synapse plugin run`, `synapse plugin test`                                                  | 로컬 실행과 반복적 테스트를 수행합니다.                                                                                                          |
| 3     | Configure   | `synapse plugin update-config`                                                               | 액션을 자동 발견하여 `config.yaml`을 동기화합니다.                                                                                               |
| 4     | Validate    | `synapse plugin publish --dry-run`, `--debug`                                                | 업로드 없이 미리보기; debug 모드는 백엔드 검증을 우회합니다.                                                                                     |
| 5     | Publish     | `synapse plugin publish`                                                                     | Synapse 백엔드(런타임 레지스트리)에 ZIP을 업로드합니다.                                                                                          |
| **6** | **Archive** | **`synapse plugin publish`** *(배포 후 단계)*                                                | **GitHub 설정이 있을 때, 소스를 GitHub 리포지토리에 미러링하고 태그를 달고 릴리스를 생성합니다. 옵트인(opt-in)이며 비차단(non-blocking)입니다.** |
| 7     | Distribute  | `synapse plugin publish -m plugin.yaml`, `synapse plugin package -m plugin.yaml [--offline]` | 매니페스트 기반 일괄 배포 / 패키징을 GitHub 아카이빙된 릴리스로부터 수행합니다.                                                                  |

<!-- -->

### 아카이브가 별도 단계인 이유[​](#아카이브가-별도-단계인-이유 "아카이브가 별도 단계인 이유에 대한 직접 링크")

GitHub 아카이빙은 단순히 배포의 부수효과가 아니라 그 자체로 라이프사이클 단계입니다. 다음과 같은 가치를 제공하기 때문입니다:

* **릴리스별 변경 불가능한 소스 오브 트루스.** 백엔드에 업로드된 동일한 ZIP이 GitHub 릴리스의 자산으로 첨부됩니다.
* **변형(variant) 브랜치 격리.** 고객별 또는 배포 환경별로 커스터마이징된 빌드는 `variant/{name}` 브랜치와 `{version}+{variant}` 태그로 메인 릴리스 라인과 격리됩니다.
* **매니페스트 기반 배포의 해석 기준.** `synapse plugin publish -m plugin.yaml` 과 `synapse plugin package -m plugin.yaml` 은 로컬 체크아웃이 아닌 GitHub 릴리스로부터 플러그인 버전을 해석합니다.
* **로컬 소스 없이 복구 및 재배포.** `repo` 권한을 가진 누구든 원본 작업 트리를 보유하지 않고도 알려진 릴리스를 다시 배포할 수 있습니다.
* **감사 추적.** 어떤 소스가 언제 배포되었는지에 대한 시간 표시·태그 기록.

### 백엔드 vs GitHub[​](#백엔드-vs-github "백엔드 vs GitHub에 대한 직접 링크")

|               | 백엔드                                    | GitHub 아카이브                                    |
| ------------- | ----------------------------------------- | -------------------------------------------------- |
| **역할**      | Synapse 에이전트를 위한 런타임 레지스트리 | 버전이 부여된 소스 아카이브                        |
| **소비 주체** | 실행 시점의 에이전트                      | `publish -m`, `package -m`, 소스를 열람하는 사용자 |
| **기록 시점** | 정식 `synapse plugin publish` 호출마다    | 동일 호출의 배포 후 단계 (GitHub 설정 시)          |
| **실패 영향** | 배포를 차단함 (반드시 성공해야 함)        | 경고만 기록 — 백엔드 배포는 그대로 성공            |

한쪽의 실패가 다른 쪽을 차단하지 않습니다.

사전 요구 사항

GitHub 아카이빙을 설정하기 전에 다음을 준비하세요:

* [인증](/ko/operations/cli-usage.md#%EC%9D%B8%EC%A6%9D) 완료 (`synapse login`)
* `repo` 스코프를 가진 GitHub **Personal Access Token** 준비
* GitHub 조직(organization) 이름 확인 (기본값: `synapse-plugins`)

## 개요[​](#개요 "개요에 대한 직접 링크")

### 한눈에 보기[​](#한눈에-보기 "한눈에 보기에 대한 직접 링크")

| 기능              | 명령 / 설정                                  | 설명                            |
| ----------------- | -------------------------------------------- | ------------------------------- |
| **설정**          | `synapse plugin github-setup`                | GitHub 토큰과 조직 구성         |
| **제거**          | `synapse plugin github-clear`                | GitHub 설정 제거                |
| **자동 아카이빙** | `synapse plugin publish`                     | 정식 배포 시 자동으로 아카이빙  |
| **일괄 배포**     | `synapse plugin publish -m plugin.yaml`      | GitHub에서 가져와 백엔드로 배포 |
| **환경 변수**     | `SYNAPSE_GITHUB_TOKEN`, `SYNAPSE_GITHUB_ORG` | 설정 파일 값을 재정의           |

### 동작 방식[​](#동작-방식 "동작 방식에 대한 직접 링크")

GitHub 아카이빙은 **옵트인(opt-in)** 이며 **비차단(non-blocking)** 방식입니다:

* **옵트인**: GitHub 설정이 존재할 때만 활성화됩니다 (`github-setup` 완료 시).
* **비차단**: GitHub 아카이빙이 실패해도 백엔드 배포는 그대로 성공합니다 — 오류가 아닌 경고를 받게 됩니다.
* **Debug 건너뜀**: `synapse plugin publish --debug` 는 빠른 반복 작업을 위해 GitHub 아카이빙을 완전히 건너뜁니다.

## 설정[​](#설정 "설정에 대한 직접 링크")

### GitHub 연동 구성[​](#github-연동-구성 "GitHub 연동 구성에 대한 직접 링크")

대화형 설정을 실행합니다:

```bash
synapse plugin github-setup

```

다음 항목을 입력하라는 프롬프트가 표시됩니다:

1. **GitHub personal access token** — 리포지토리와 릴리스 생성을 위해 `repo` 스코프가 필요합니다.
2. **GitHub 조직** — 플러그인 리포지토리가 생성될 위치 (기본값: `synapse-plugins`).

이 명령은 토큰을 저장하기 전에 GitHub API를 호출하여 토큰을 검증합니다.

값을 직접 제공할 수도 있습니다:

```bash
synapse plugin github-setup --token ghp_xxxxxxxxxxxx --org my-org

```

설정은 `~/.synapse/config.json` 의 `github` 키 아래에 저장됩니다.

### 환경 변수[​](#환경-변수 "환경 변수에 대한 직접 링크")

환경 변수가 설정 파일보다 우선합니다:

| 변수                   | 설명                         |
| ---------------------- | ---------------------------- |
| `SYNAPSE_GITHUB_TOKEN` | GitHub personal access token |
| `SYNAPSE_GITHUB_ORG`   | GitHub 조직 이름             |

```bash
# 환경 변수로 설정 (CI/CD에 유용)
export SYNAPSE_GITHUB_TOKEN=ghp_xxxxxxxxxxxx
export SYNAPSE_GITHUB_ORG=my-org

```

> **알아두면 좋은 점**: 두 환경 변수가 모두 설정되어 있으면 설정 파일은 전혀 읽지 않습니다. 한쪽만 설정되어 있으면 나머지는 설정 파일에서 보충합니다.

### 설정 제거[​](#설정-제거 "설정 제거에 대한 직접 링크")

```bash
# 대화형 확인
synapse plugin github-clear

# 확인 건너뛰기
synapse plugin github-clear -y

```

## 자동 아카이빙 워크플로우[​](#자동-아카이빙-워크플로우 "자동 아카이빙 워크플로우에 대한 직접 링크")

`synapse plugin publish` 를 (`--debug` 없이) 실행하면, 백엔드 업로드가 성공한 후 SDK가 다음 단계를 실행합니다:

<!-- -->

### 아카이빙되는 대상[​](#아카이빙되는-대상 "아카이빙되는 대상에 대한 직접 링크")

* 모든 플러그인 소스 파일 (`.synapseignore` 규칙으로 필터링됨)
* 100MB를 초과하는 파일은 자동으로 건너뜀
* 백엔드에 업로드된 동일한 ZIP이 GitHub 릴리스 자산으로 첨부됨

### 출력 예시[​](#출력-예시 "출력 예시에 대한 직접 링크")

GitHub 아카이빙이 포함된 성공적인 배포 출력:

```text
Using config: config.yaml
Plugin: my-plugin v1.2.0 (neural_net)
Archive: 15 files, 45.2 KB

✓ Published to Backend (release_id: 42)

╭─ GitHub ──────────────────────────────────────╮
│ GitHub archived!                               │
│                                                │
│ Repo: https://github.com/my-org/my-plugin      │
│ Tag: 1.2.0                                     │
│ Release: https://github.com/my-org/my-plugin/  │
│          releases/tag/1.2.0                     │
╰────────────────────────────────────────────────╯

```

GitHub 아카이빙이 실패하면 대신 다음과 같은 경고가 표시됩니다:

```text
Warning: GitHub archiving failed: <error details>
The plugin was published to Backend successfully.
GitHub sync can be retried later.

```

## 변형(Variant) 브랜치 전략[​](#변형variant-브랜치-전략 "변형(Variant) 브랜치 전략에 대한 직접 링크")

플러그인은 특정 고객 또는 배포 환경을 위한 커스터마이징된 빌드인 **변형(variant)** 을 가질 수 있습니다. 각 변형은 자체 브랜치와 태그 체계를 사용합니다.

### 브랜치 규칙[​](#브랜치-규칙 "브랜치 규칙에 대한 직접 링크")

| 변형        | 브랜치        | 예시          |
| ----------- | ------------- | ------------- |
| 없음 (기본) | `main`        | `main`        |
| `lig`       | `variant/lig` | `variant/lig` |
| `ke`        | `variant/ke`  | `variant/ke`  |

### 태그 규칙[​](#태그-규칙 "태그 규칙에 대한 직접 링크")

| 변형  | 태그 형식             | 예시        |
| ----- | --------------------- | ----------- |
| 없음  | `{version}`           | `1.2.0`     |
| `lig` | `{version}+{variant}` | `1.2.0+lig` |
| `ke`  | `{version}+{variant}` | `1.2.0+ke`  |

`+` 기호는 [SemVer 빌드 메타데이터](https://semver.org/#spec-item-10) 규칙을 따릅니다.

### 리포지토리 구조[​](#리포지토리-구조 "리포지토리 구조에 대한 직접 링크")

여러 변형을 가진 플러그인은 GitHub에 다음과 같은 구조를 만듭니다:

```text
github.com/{org}/{plugin-code}/
├── main branch
│   └── tags: 1.0.0, 1.1.0, 1.2.0
├── variant/lig branch
│   └── tags: 1.0.0+lig, 1.1.0+lig
└── variant/ke branch
    └── tags: 1.0.0+ke

```

플러그인의 `config.yaml` 에서 변형을 지정하세요:

```yaml
code: my-plugin
version: "1.2.0"
variant: lig  # 선택사항 — 기본 변형이라면 생략

```

## 매니페스트 기반 일괄 배포[​](#매니페스트-기반-일괄-배포 "매니페스트 기반 일괄 배포에 대한 직접 링크")

여러 플러그인을 한 번에 배포하려면 **플러그인 매니페스트**(`plugin.yaml`)를 사용합니다.

### plugin.yaml 작성[​](#pluginyaml-작성 "plugin.yaml 작성에 대한 직접 링크")

```yaml
plugins:
  yolo_test:
    version: ">=2.0.0"
  sam2-smart-tool:
    version: ">=1.0.0"

```

각 항목은 플러그인 코드와 [PEP 440](https://peps.python.org/pep-0440/) 버전 지정자를 명시합니다. SDK는 GitHub 릴리스에서 가장 적합한 버전을 해석합니다.

**축약형** (최신 버전):

```yaml
plugins:
  yolo_test:
  sam2-smart-tool:

```

### 일괄 배포[​](#일괄-배포 "일괄 배포에 대한 직접 링크")

```bash
# GitHub에서 해석 → 다운로드 → 백엔드로 배포
synapse plugin publish -m plugin.yaml

# Debug 모드 (백엔드 검증 건너뜀)
synapse plugin publish -m plugin.yaml --debug

```

### 추이 의존성 해석[​](#추이-의존성-해석 "추이 의존성 해석에 대한 직접 링크")

플러그인이 `config.yaml` 에 `dependencies` 를 선언하면, 해당 의존성은 자동으로 해석되어 포함됩니다:

```text
plugin.yaml: [sam2-smart-tool]       (1 declared)
  ↓ resolve + download
sam2-smart-tool
  → dependencies: { segment-anything-2: ">=2.0.0" }
    ↓ auto-added
segment-anything-2                    (2 total processed)

```

SDK는 추이 의존성을 처리하기 위해 사이클 감지가 포함된 BFS(너비 우선 탐색)를 사용합니다.

### 일괄 패키징[​](#일괄-패키징 "일괄 패키징에 대한 직접 링크")

오프라인 배포를 위해 플러그인을 패키징할 수도 있습니다:

```bash
# 표준 패키징 (코드만)
synapse plugin package -m plugin.yaml

# 오프라인 패키징 (코드 + Python 휠)
synapse plugin package -m plugin.yaml --offline

```

## 안전 기능[​](#안전-기능 "안전 기능에 대한 직접 링크")

### 원격 저장소 불일치 경고[​](#원격-저장소-불일치-경고 "원격 저장소 불일치 경고에 대한 직접 링크")

아카이빙 전에 SDK는 플러그인 디렉토리에 로컬 `.git/config` 가 있고 `remote origin` URL이 설정되어 있는지 확인합니다. 그 URL이 아카이빙 대상과 다른 `{org}/{repo}` 를 가리키면 경고가 표시됩니다:

```text
Warning: local git remote (personal-org/my-plugin) does not match
         archive target (datamaker-kr/my-plugin)

```

이는 서로 다른 조직에 중복 리포지토리를 실수로 만드는 일을 방지합니다.

### 사전 점검: 조직 접근 권한 검증[​](#사전-점검-조직-접근-권한-검증 "사전 점검: 조직 접근 권한 검증에 대한 직접 링크")

매니페스트 기반 일괄 작업(`publish -m`, `package -m`)에서는 SDK가 플러그인을 처리하기 전에 GitHub 토큰 권한을 검증합니다:

* `GET /orgs/{org}` 를 호출하여 토큰 접근 권한 확인
* 토큰에 조직 권한이 없으면 조기에 실패
* 일괄 작업에서 부분 실패를 방지

### 치명적 오류 시 조기 종료[​](#치명적-오류-시-조기-종료 "치명적 오류 시 조기 종료에 대한 직접 링크")

일괄 배포/패키징 중 **치명적 오류**(HTTP 401 Unauthorized 또는 403 Forbidden)가 발생하면, SDK는 남은 플러그인 처리를 계속하지 않고 즉시 중단합니다 — 동일한 인증 오류로 이후 작업도 모두 실패할 것이기 때문입니다.

## 문제 해결[​](#문제-해결 "문제 해결에 대한 직접 링크")

| 문제                    | 원인                                   | 해결책                                   |
| ----------------------- | -------------------------------------- | ---------------------------------------- |
| "GitHub not configured" | 토큰/조직이 저장되어 있지 않음         | `synapse plugin github-setup` 실행       |
| "Invalid GitHub token"  | 토큰이 만료되었거나 스코프가 잘못됨    | `repo` 스코프를 가진 새 PAT 생성         |
| 조직 접근 시 404        | 토큰에 조직 권한이 없음                | GitHub 설정에서 토큰을 해당 조직에 인가  |
| "No files to archive"   | `.synapseignore` 가 모든 파일을 제외함 | `.synapseignore` 규칙 확인               |
| 원격 저장소 불일치 경고 | 로컬 git 원격이 아카이빙 대상과 다름   | `github-setup` 에서 올바른 조직 확인     |
| GitHub archive failed   | 네트워크 문제 또는 API 속도 제한       | 백엔드 배포는 그대로 성공; 나중에 재시도 |
| 일괄 배포 부분 실패     | 인증/네트워크 오류 혼재                | 요약 출력에서 플러그인별 상태 확인       |

## 관련 문서[​](#관련-문서 "관련 문서에 대한 직접 링크")

* [CLI 사용 가이드](/ko/operations/cli-usage.md) — 전체 CLI 명령 레퍼런스
* [플러그인 개발](/ko/plugins/plugin-development.md#publishing) — 배포 워크플로우 개요
* [Semantic Versioning](https://semver.org/) — 버전 형식 레퍼런스
* [PEP 440](https://peps.python.org/pep-0440/) — 매니페스트 파일의 버전 지정자 문법
