# 배포 거버넌스 개요

GitHub에서는 저장소에 푸시할 수 있는 사람이 보통 배포도 할 수 있습니다. Mocco는 이 둘을 분리합니다. 파이프라인은 단계 목록으로 실행되고, 단계 사이에 **게이트**를 둘 수 있습니다. 게이트는 적절한 역할을 가진 사람이 충분히 승인할 때까지 실행을 멈춥니다. 프로덕션 자격 증명이 필요한 단계는 그 자격 증명을 Mocco에서 받으며, Mocco는 해당 단계의 게이트가 승인된 뒤에만 내어 줍니다. 워크플로에서 게이트를 지워도 건너뛸 수 없습니다. 게이트 없이는 자격 증명이 나가지 않기 때문입니다.

배포 거버넌스는 모든 워크스페이스에서 항상 켜져 있습니다. 구성 요소는 다음과 같습니다.

- **Repositories**: 워크스페이스의 **Deploys** 페이지에 있으며, Mocco가 지켜보는 GitHub 저장소입니다.
- **`.mocco.yml` 파일**: 각 저장소에 두는 파일로, 단계와 게이트로 이루어진 파이프라인을 담습니다.
- **커밋**과 **실행**: 지켜보는 브랜치의 각 커밋을 파이프라인으로 실행할 수 있고, 승인자는 실행 페이지에서 승인합니다. **Deploys** 페이지는 모든 저장소의 최근 실행과 상태를 보여 줍니다. 게이트에서 대기 중인 실행은 워크스페이스 **Home**에도 표시됩니다.
- **Access** 페이지의 **Roles**와 **Credential releases**: 누가 승인하는지, 어떤 게이트가 어떤 자격 증명을 여는지 정합니다.

## GitHub 연결

워크스페이스의 **Deploys** 페이지를 엽니다. 저장소가 아직 없으면 **Connect GitHub**가 보입니다. 이를 선택하고 GitHub 계정이나 조직에 Mocco GitHub App을 설치하면서, 사용할 저장소에 대한 접근 권한을 줍니다. 조직에서 앱 설치에 관리자 승인이 필요하면, 관리자가 승인할 때까지 Mocco가 설치가 승인을 기다리는 중이라고 알려 줍니다.

Mocco로 돌아오면 앱이 볼 수 있는 저장소가 **Add a repository from** 계정 아래에 나열됩니다. 저장소 옆의 **Add**를 선택하면 **Connected repositories**에 나타납니다.

![워크스페이스 Deploys 페이지: 연결된 저장소 두 개와 각각 지켜보는 브랜치](https://fi-workers-mocco-storage.s3.ap-northeast-2.amazonaws.com/pub/w/93e11fe8-0494-4e3d-b1cb-fe4dffd3ee7e/p/d64785b8-9a23-4fa1-a81d-550af30e203a/helpcenter/272e2ad3-4396-4239-9c2d-050e9c97148b/repositories.png)

연결된 저장소마다 지켜보는 브랜치가 있습니다. 바꾸지 않으면 기본 브랜치입니다. 브랜치를 입력하고 **Save**를 선택합니다. 지켜보는 브랜치를 저장하면 **Commits**에 Mocco가 그 브랜치에서 동기화한 커밋이 최신순으로 나열되고, **Load more**를 선택하면 더 오래된 커밋이 나옵니다. 각 커밋은 자체 페이지로 열립니다.

프로젝트에서 저장소의 릴리스를 사용하려면 프로젝트의 **Overview** 페이지에서 저장소를 연결합니다. [워크스페이스와 프로젝트 설정하기](https://www.mocco.club/docs/ko/articles/iu3d9y-workspace-and-projects#5-link-repositories)을 참고하세요.

## 파이프라인 정의

저장소 루트에 `.mocco.yml`을 추가합니다. 이 파일은 GitHub Actions 워크플로를 대체하지 않습니다. 각 단계가 자신을 실행할 실행기(executor)를 지정하면, Mocco가 그곳에서 단계를 시작합니다. 형식의 버전 2는 단계와 게이트를 함께 쓸 수 있습니다.

```yaml
version: 2
pipeline: deploy
steps:
  - kind: step
    run: deploy-staging
    executor: github-actions
  - kind: gate
    name: production
    resume:
      - { role: deployer, count: 2 }
      - { role: security, count: 1 }
    prevent_self: true
    reason_required: true
  - kind: step
    run: deploy-production
    executor: github-actions
```

단계에는 `run` 이름과 `executor`가 있습니다. `github-actions`는 [파이프라인에 토큰 발급하기](https://www.mocco.club/docs/ko/articles/yjbg5q-pipeline#4-fetch-it-in-the-workflow)에서 보듯이 `repository_dispatch` 이벤트로 저장소의 GitHub Actions에서 단계를 시작합니다. 게이트에는 `name`과 `resume`이 있습니다. `resume`은 승인해야 하는 역할과 역할별 필요 인원입니다. `resume`의 요구 사항은 모두 충족해야 합니다. `prevent_self: true`는 실행을 시작한 사람이 직접 승인하지 못하게 하고, `reason_required: true`는 승인하거나 거부하는 모든 사람에게 사유를 요구합니다. 둘 다 설정하지 않으면 꺼져 있습니다. 단계와 게이트의 이름은 파일 안에서 고유해야 합니다. `kind` 없이 단계만 있는 버전 1 파일도 계속 동작합니다.

역할 이름은 워크스페이스 **Access** 페이지의 역할을 가리키며, 파일에는 사람이 나오지 않습니다. [멤버와 접근 권한](https://www.mocco.club/docs/ko/articles/pns8fb-members-and-access#roles-on-the-access-page)을 참고하세요.

## 커밋 페이지

Mocco는 동기화한 각 커밋에서 `.mocco.yml`을 읽고 그 버전을 커밋과 함께 보관합니다. 그래서 실행은 항상 해당 커밋 시점의 파일을 따릅니다. 커밋 페이지에는 커밋 메시지, 작성자, 시각이 나오고, 이어서 다음 중 하나가 나옵니다.

- 파이프라인: 단계가 순서대로 나오고, 각 게이트는 **Gate:**와 이름으로 표시되며, 뒤에 필요 조건이 붙습니다. 예: "Requires 2× deployer, 1× security · no self-approval · reason required"
- **Invalid .mocco.yml**: 각 문제와 파일 안의 위치
- **No .mocco.yml at this commit**
- **Config pending**: Mocco가 아직 커밋을 읽는 중일 때

**Run**을 선택하면 해당 커밋의 실행을 시작하고 그 페이지를 엽니다. 커밋에 유효한 `.mocco.yml`이 있을 때만 사용할 수 있습니다. 워크스페이스 멤버라면 누구나 실행을 시작할 수 있습니다.

## 실행과 게이트

실행 페이지에는 실행 상태, 각 단계와 단계별 상태, 게이트가 나옵니다. 실행이 아직 진행 중이면 **Live**가 표시되고 스스로 갱신됩니다.

실행은 `queued`에서 `running`이 됩니다. 게이트에 닿으면 `awaiting_gate`에서 멈추고, `succeeded`, `failed`, `canceled`, `rejected` 중 하나로 끝납니다. 각 단계는 `pending`에서 `dispatched`, `running`을 거쳐 `succeeded`, `failed`, `skipped`, `canceled` 중 하나로 끝납니다.

각 게이트 카드에는 게이트 상태(`pending`, `resumed`, `rejected`, `expired`)와 필요한 역할별 승인 수가 "1 / 2 approvals"처럼 표시됩니다. 실행이 그 게이트에서 대기 중이면 카드에 사유 입력란과 **Approve**, **Reject**가 있습니다.

- 게이트에 지정된 역할 중 하나에 속한 사람만 투표할 수 있고, 한 사람은 한 번만 투표합니다. 여러 역할에 속한 사람도 한 명으로 계산됩니다.
- 모든 역할이 충분히 승인하면 게이트는 `resumed`가 되고 실행은 다음 단계로 이어집니다.
- **Reject** 한 번이면 실행이 즉시 멈춥니다. 게이트도 실행도 `rejected`가 됩니다.
- 이미 투표했거나, 직접 실행을 시작했는데 게이트가 직접 승인을 막는 경우에는 카드가 투표할 수 없는 이유를 알려 줍니다.

알림을 설정해 두면 Mocco는 실행이 게이트에 닿을 때, 게이트가 승인되거나 거부될 때, 실행이 실패하거나 성공할 때 Discord에 알릴 수 있습니다. [Mocco 이벤트](https://www.mocco.club/docs/ko/articles/eriac3-mocco-events)를 참고하세요.

## 게이트 뒤의 자격 증명

게이트만으로는 파이프라인이 멈출 뿐이고, 자격 증명을 내주지 않아야 통제가 실제로 효력을 가집니다. 단계는 `.mocco.yml`에서 `credential: { provider, role, ttl, gate }`로 자격 증명을 요청합니다. 여기서 `gate`는 `steps`에서 앞에 있는 게이트의 이름입니다. 그 게이트가 단계보다 앞에 있지 않으면 Mocco는 파일을 거부합니다.

요청만으로는 아무것도 허용되지 않습니다. 워크스페이스 소유자나 관리자가 **Access** 페이지의 **Credential releases**에서 허용합니다. 저장소, 파이프라인, 게이트, 프로바이더와 역할, 그리고 자격 증명이 유효할 수 있는 최대 시간(초)을 지정합니다. 단계가 요청하면 Mocco는 세 가지를 확인한 뒤에만 자격 증명을 건네줍니다. Mocco가 시작한 실행이어야 하고, 지정한 게이트가 승인되었어야 하며, 일치하는 허용 항목이 있어야 합니다. 내어 주거나 거부한 모든 자격 증명은 [감사 로그](https://www.mocco.club/docs/ko/articles/2yiscf-audit-log)에 기록됩니다.

![Access 페이지의 Credential releases, 추가 양식이 열린 모습](https://fi-workers-mocco-storage.s3.ap-northeast-2.amazonaws.com/pub/w/93e11fe8-0494-4e3d-b1cb-fe4dffd3ee7e/p/d64785b8-9a23-4fa1-a81d-550af30e203a/helpcenter/a7887d37-96ac-49ec-8649-06188dbb6599/credential-releases.png)

현재 Mocco는 이 방식으로 OTA 도구의 배포 토큰을 내어 줍니다. 처음부터 끝까지의 과정은 [파이프라인에 토큰 발급하기](https://www.mocco.club/docs/ko/articles/yjbg5q-pipeline)에 있습니다. 배포 단계에 발급하는 단기 AWS 자격 증명 같은 클라우드 자격 증명은 아직 지원하지 않습니다.

## 기록되는 내용

Mocco는 실행이 시작될 때(`run.triggered`), 게이트가 재개되거나 거부될 때(`gate.resumed`, `gate.rejected`, 어떤 역할로 누가 승인했는지 포함), 자격 증명을 내어 주거나 거부할 때마다(`credential.issued`, `credential.denied`) 워크스페이스의 [감사 로그](https://www.mocco.club/docs/ko/articles/2yiscf-audit-log)에 항목을 추가합니다.
