# 코드로 관리하는 플래그

기능 플래그를 그 플래그를 읽는 코드 옆, 저장소에 둘 수 있습니다. 파일 변경은 평소의 풀 리퀘스트를 거치고, 머지하면 Mocco가 갱신됩니다. 머지가 곧 릴리스는 아닙니다. 보호한 환경은 여전히 승인자를 기다립니다.

## 1. 저장소 연결하기

저장소는 파이프라인과 마찬가지로 GitHub App으로 Mocco에 연결되어 있고 프로젝트에 링크되어 있어야 합니다. Mocco는 저장소의 **기본 브랜치**에 푸시가 올 때마다, 그리고 기본 브랜치로 향하는 풀 리퀘스트에서 파일을 읽습니다.

## 2. `.mocco/flags.yml` 추가하기

```yaml
version: 1
flags:
  onboarding_v2:
    description: The new onboarding flow
    client_visible: true        # browsers and apps may evaluate it
    targets:
      staging:
        default: on
      production:
        default: off
        rules:
          - when: { attribute: plan, op: in, values: [pro] }
            serve: on
```

각 플래그는 자신의 **targets**를 나열합니다. targets는 플래그가 켜져 있는 환경(환경 키 기준)이며, 기본으로 제공하는 값과 규칙을 함께 적습니다. 파일이 나열하지 않은 환경에서 플래그는 꺼져 있습니다. 불리언 플래그에는 `on`과 `off` 변형이 있습니다. 다른 타입은 자체 변형을 나열합니다.

```yaml
  checkout_copy:
    type: string
    variants: { short: Pay, long: Pay securely }
    off_variant: short          # what a kill serves
    targets:
      production:
        default: long
        rollout: { short: 50, long: 50 }   # instead of `default`, when no rule matches
```

규칙의 `when`은 하나의 조건이거나, 모두 일치해야 하는 조건 목록입니다. 조건은 `{ attribute, op, values }` 또는 `{ segment }` 형태입니다. `serve`는 변형 하나이거나 `{ rollout: { variant: weight, … } }`입니다.

| 필드 | 위치 | 의미 |
|---|---|---|
| `type` | 플래그 | `boolean`(기본값), `string`, `number`, `json` |
| `description` | 플래그 | 콘솔에 표시됩니다 |
| `lifecycle` | 플래그 | `temporary`(기본값) 또는 `permanent`. permanent 플래그는 정리 대상으로 제안되지 않습니다 |
| `client_visible` | 플래그 | `true`이면 브라우저와 앱이 평가할 수 있습니다(기본값 `false`) |
| `variants`, `off_variant` | 플래그 | 플래그가 불리언이 아니면 필수입니다 |
| `enabled` | target | 기본값은 `true`입니다. `false`이면 호출자가 코드의 기본값을 받습니다 |
| `default` | target | 일치하는 규칙이 없을 때 제공하는 변형 |
| `rules` | target | 순서대로 시도하며, 조건이 모두 일치하는 첫 규칙이 값을 제공합니다 |
| `rollout` | target | 일치하는 규칙이 없을 때 `default` 대신 제공합니다 |

연산자는 콘솔의 규칙 편집기가 제공하는 것과 같습니다. `in`, `not_in`, `starts_with`, `ends_with`, `lt`, `lte`, `gt`, `gte`, 그리고 `semver_` 비교입니다. 알 수 없는 필드는 거부되므로, 철자가 틀린 키가 무시되지 않고 걸러집니다.

## 3. 풀 리퀘스트 열기

기본 브랜치로 향하는 풀 리퀘스트가 `.mocco/flags.yml`을 바꾸면 Mocco가 **Mocco flags plan**이라는 체크를 추가합니다. 저장소가 링크된 모든 프로젝트에서 머지했을 때 일어날 일을 알려 줍니다.

- 새로 만드는 플래그, 콘솔에서 넘겨받는 플래그, 콘솔로 돌려주는 플래그
- 변경되는 각 환경과 그 변경 내용, 그리고 즉시 적용되는지 승인을 기다리는지
- 파일에 실수가 있으면 각 문제와 그 위치. 머지하기 전에 고칠 수 있습니다.

이 체크는 현재 플래그를 기준으로 계획하므로, 브랜치를 만든 뒤 누군가 콘솔에서 바꾼 내용도 보여 줍니다. 풀 리퀘스트에 푸시할 때마다 다시 실행됩니다. 이 체크만으로 머지가 막히는 일은 없습니다. 파일에 문제가 없으면 통과하고, 문제가 있으면 중립(neutral)으로 끝납니다. 머지하기 전까지 Mocco에서는 아무것도 바뀌지 않습니다.

## 4. 머지하고, 보호된 환경에서는 승인하기

변경이 기본 브랜치에 반영되면 다음과 같이 동작합니다.

- **보호되지 않은 환경**은 즉시 갱신됩니다.
- **보호된 환경**에는 승인을 기다리는 변경이 생기고, 그 변경이 나온 커밋이 표시됩니다. 더 새로운 푸시가 오면 대체됩니다.
- **승인할 수 없는 사람**: 변경을 제안한 사람은 푸시하거나 머지한 사람(해당 GitHub 계정으로 로그인한 멤버)과 커밋의 작성자(검증된 이메일이 일치하는 멤버)입니다. 두 사람 모두 승인할 수 없습니다.

![보호된 환경에서 승인을 기다리는 커밋 3f9c2a1의 변경](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/3afcb1ec-26f2-43c0-a23b-ce9bbe0797b1/flags-repo-changeset.png)

플래그 화면은 저장소에서 온 플래그를 표시하고 마지막 동기화 목록을 보여 줍니다. 존재하지 않는 환경이나 플래그에 없는 변형처럼 파일에 실수가 있으면 아무것도 바뀌지 않고, 동기화 기록에 문제가 있는 위치가 나옵니다.

![플래그 목록: "From repo"로 표시된 onboarding_v2와, 이유와 함께 거부된 동기화를 포함한 동기화 목록](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/07c0fea5-a1f1-4469-bd06-e686f68c6e6e/flags-repo-list.png)

## 콘솔에서

저장소에서 온 플래그는 콘솔에서 읽기 전용입니다. 규칙, 스위치, 설정은 파일을 통해서만 바뀝니다. 인시던트 중에는 머지를 기다리면 안 되므로 **킬 스위치**는 그대로 동작합니다. 동기화가 킬을 되돌리는 일은 없습니다. 안전해지면 콘솔에서 플래그를 복원하세요.

![콘솔의 저장소 플래그: 안내 문구, 읽기 전용 설정, 킬 스위치](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/7332c7a6-5f59-4f86-a18f-807925e04ead/flags-repo-detail.png)

플래그를 콘솔로 돌려주려면 파일에서 제거하세요. Mocco가 모든 환경에서 플래그를 끄고 다시 편집할 수 있게 합니다. 콘솔에서 만든 플래그를 넘겨받으려면 같은 타입과 변형으로 파일에 추가하세요. 변형은 나중에 추가할 수 있지만 제거하거나 바꿀 수는 없습니다.
