다른 언어: English, Español, Português, 日本語, Deutsch, Français, 简体中文, Italiano, हिन्दी · 한국어 가이드 전체
공개: 저희는 100monkeys.ai에서 Carbon Forge를 만들고 있으므로 이 글은 만든 쪽의 설명으로 읽어 주세요. 이 가이드는 저희 AI 에이전트 하나가 공개 문서(영어), 주로 Code and files on the substrate의 "Cut a release"와 "Publish to git" 절, Archives 카탈로그 페이지, Source control settings를 바탕으로 초안을 쓰고 회사가 검토했으며, 이 한국어판은 영어 원문 가이드의 번역입니다. 모든 호출은 문서 자체의 예시이고, 인용은 영어 원문 옆에 번역을 붙였습니다. 문서가 답하지 않은 질문은 마지막 절에서 밝힙니다.
두 문장으로 보는 모델
"A cut names the whole workspace's state at one moment and never moves."(cut은 한 순간의 워크스페이스 전체 상태에 이름을 붙이며 절대 움직이지 않습니다.) "The git archive renders a code tree as git: one commit per tree revision, whose message is the landing's intent, and an annotated tag refs/tags/nn/<cut> per cut, whose message carries the cut's notes."(git 아카이브는 코드 트리를 git으로 렌더링합니다. 트리 리비전마다 커밋 하나, 그 메시지는 랜딩의 intent이고, cut마다 annotated 태그 refs/tags/nn/<cut> 하나, 그 메시지는 cut의 노트를 담습니다.) "from the record byte for byte, so the same revision always renders to the same commit"(기록에서 바이트 단위로 그대로, 그래서 같은 리비전은 언제나 같은 커밋으로 렌더링되기) 때문에, GitHub의 사본은 언제든 기록과 대조해 확인할 수 있습니다.
1단계. 릴리스에 담을 작업 랜딩하기
cut은 trunk에 이름을 붙이므로, 아직 lane에 있는 것은 들어가지 않습니다. 릴리스에 속하는 것을 먼저 랜딩하고, intent를 feat, fix, docs, chore, revert로 시작하세요. 그 첫 단어가 노트가 각 랜딩을 묶는 기준입니다(코드 변경과 그 문서를 하나의 changeset으로 랜딩하기가 랜딩 하나를 따라갑니다).
2단계. 릴리스 cut하기
snapshots.cut { "name": "v1.4.0" } cut은 영구적입니다. 패러다임 페이지는 "the database refuses to change or remove a snapshot or a cut while the workspace exists."(워크스페이스가 있는 동안 데이터베이스는 스냅숏이나 cut을 바꾸거나 지우기를 거부합니다)라고 말합니다. snapshots.materialize는 어떤 엔티티든 cut이 가진 그대로 읽고, trees.diff와 trees.grep도 스냅숏을 받습니다.
3단계. 릴리스 노트 읽기
cuts.notes { "from": "v1.3.0", "to": "v1.4.0" } cuts.notes는 "lists every changeset landed between the two cuts, grouped by the first word of its intent"(두 cut 사이에 랜딩한 모든 changeset을 intent의 첫 단어로 묶어 나열하며), 각각이 랜딩한 lane과 건드린 경로를 함께 보여 줍니다. path_glob은 워크스페이스의 한 부분으로 좁힙니다. 앱에서는 /<workspace>/cuts/<name>이 Notes from <previous cut>이라는 제목으로 같은 노트를 열고, Compare with another cut으로 임의의 두 cut을 고릅니다.
4단계. 인스턴스에 GitHub 계정 연결하기
push는 "as the instance's GitHub App"(인스턴스의 GitHub App으로) 이루어지므로, 저장소를 소유한 계정에 그 App이 설치되어 있어야 합니다. 인스턴스 관리자가 Settings → Instance → Source control을 열고 Connect a GitHub account를 누르면, 브라우저가 "GitHub's install page for the CarbonForge.dev GitHub App"(CarbonForge.dev GitHub App의 GitHub 설치 페이지)으로 갑니다. 거기서 계정이나 조직, 그리고 저장소를 고릅니다. 문서가 나열하는 권한:
- Contents: Read and write: 커밋,
refs/heads/main, cut의 태그를 push하기 위해. - Workflows: Read and write: push가
.github/workflows/아래 파일을 추가하거나 바꿀 때만 필요합니다. 없으면 "GitHub refuses"(GitHub가 거부합니다). - Actions: Read: 8단계에서 remote의 실행 결과를 읽기 위해.
Carbon Forge로 돌아오면 탭에 Connected to @<account>가 표시됩니다.
5단계. git 아카이브 렌더링하고 검증하기
archives.render { "tree": "app", "cut": "v1.4.0" }
archives.verify { "tree": "app", "cut": "v1.4.0" } render는 트리의 커밋과 cut의 태그를 아카이브에 쓰고, verify는 아카이브의 상태와, 차이가 있으면 첫 번째 차이를 보고합니다. cut 페이지에서 워크스페이스 관리자는 같은 Render와 Verify 버튼을 가지며, 각 답은 그대로 표시됩니다. Rendered: tag <id>, Verify: <status>.
6단계. remote 설정하기
archives.set_remote { "tree": "app", "remote": "https://github.com/acme/app.git" } remote는 https://github.com/<owner>/<repo>.git 형식으로 씁니다. Settings → Workspace → Source control에 있는 각 저장소의 Remote 필드이기도 합니다. 설정하려면 워크스페이스 관리자 권한이 필요합니다. "because the remote decides where the archive is published"(remote가 아카이브가 어디에 공개될지를 정하기 때문입니다).
7단계. push하기
archives.push { "tree": "app" } "The push sends the remote only what it lacks, fast-forward only, as the instance's GitHub App, and refuses rather than move main backwards or move a tag."(push는 remote에 없는 것만, fast-forward로만, 인스턴스의 GitHub App으로 보내며, main을 뒤로 옮기거나 태그를 옮기느니 거부합니다.) 작업으로 큐에 들어갑니다(Push queued as job <id>.). 거부는 원인을 밝힙니다. 예를 들어 The tree <path> has no archive remote; set one with archives.set_remote, and nothing was pushed., 또는 아카이브가 "has no rendered cut"(렌더링된 cut이 없다)고 말하는 거부입니다. GitHub의 거부는 GitHub 자체의 이유와 함께 The remote refused <ref>: <reason>.으로 돌아옵니다.
"The remote is a copy for git tooling and readers; nothing is read back from it."(remote는 git 도구와 독자를 위한 사본이며, 거기서 다시 읽어 오는 것은 없습니다.) 작업은 Carbon Forge에서 계속되고, 다음 cut이 다시 push합니다.
8단계. 배포 결과 다시 읽기
"Once a cut is pushed, its deploy can be read back"(cut이 push되면 그 배포를 다시 읽을 수 있습니다). archives.deploy_status는 cut의 커밋에 대한 remote의 GitHub Actions 실행을 최대 100개까지 요약과 함께 답하며, "and the record still takes nothing from the remote."(그래도 기록은 remote에서 아무것도 가져오지 않습니다.) cuts 인덱스는 각 트리를 pushed, tagged, not rendered로 표시합니다. cut.taken이나 archive.pushed에 대한 webhook은 폴링 없이 배포 스크립트에 알립니다.
문서가 답하지 않는 것
- 이미 히스토리가 있는 저장소로의 첫 push. push는 fast-forward로만 이루어지고
main을 뒤로 옮기기를 거부합니다. 문서는 선택적인 히스토리 재작성을 설명하지만, 관련 없는 기존main이 있는 경우를 따라가지는 않습니다. - GitHub 외의 호스트. 문서의 모든 remote는 GitHub URL입니다.
- 자체 호스팅 배포가 CarbonForge.dev App을 쓸 수 있는지, 아니면 자체 App을 등록해야 하는지. 설정 페이지는 운영자 설정을 지정하지만 그 선택은 말하지 않습니다.