repos
repos 카테고리의 API 작업 24개를 다룹니다.
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/repos | 프로젝트의 저장소 목록(runlot repo list) |
| POST | /v1/orgs/{orgSlug}/projects/{projectName}/repos | 저장소를 생성합니다(runlot repo create) |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName} | 단일 저장소 |
| PATCH | /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName} | 이름, 공개 범위, 기본 브랜치를 변경합니다(runlot repo rename|visibility) |
| DELETE | /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName} | 저장소를 삭제합니다(runlot repo delete) |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/ref-updates | 참조 이력(runlot repo history) |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/deploy-hook | 푸시 배포 설정(runlot repo hook status) |
| PUT | /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/deploy-hook | 푸시 배포를 켜거나 변경하기(runlot repo hook set) |
| DELETE | /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/deploy-hook | 푸시 배포를 완전히 끄기(runlot repo hook unset) |
| POST | /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/deploy | 푸시 없이 커밋을 빌드하고 배포하기 |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/builds | 빌드 기록(runlot builds list) |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/builds/{buildId} | 빌드 하나(runlot builds show) |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/builds/{buildId}/log | 빌드 출력(runlot builds log) |
| POST | /v1/orgs/{orgSlug}/projects/{projectName}/builds/{buildId}/cancel | 대기 중인 빌드 취소하기(runlot builds cancel) |
| GET | /v1/me/ssh-keys | 내 SSH 공개 키(runlot key list) |
| POST | /v1/me/ssh-keys | SSH 공개 키를 등록합니다(runlot key add) |
| DELETE | /v1/me/ssh-keys/{keyId} | SSH 공개 키를 제거합니다(runlot key rm) |
| GET | /v1/me/tokens | 내 액세스 토큰(runlot token list) |
| POST | /v1/me/tokens | 액세스 토큰을 발급합니다(runlot token create) |
| DELETE | /v1/me/tokens/{tokenId} | 액세스 토큰을 폐기합니다(runlot token revoke) |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/refs | 브랜치와 태그 목록 조회 |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/tree | 디렉터리 하나 목록 조회 |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/blob | 파일 하나 읽기 |
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/commits | 커밋 로그 |
GET /v1/orgs/{orgSlug}/projects/{projectName}/repos
viewer 이상이 필요합니다.
저장소는 프로젝트에 속합니다. 접근 권한은 조직 역할에 따라 결정되며, 저장소 이름은 프로젝트 내에서 고유합니다. 하나의 프로젝트는 여러 저장소(앱, API, 인프라)를 가질 수 있습니다.
operationId listRepos
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 저장소 목록 | object |
| 403 | — | — |
| 404 | — | — |
POST /v1/orgs/{orgSlug}/projects/{projectName}/repos
member 이상 권한이 필요합니다. repo.create로 감사 기록됩니다.
저장소는 즉시 등록되며, 스토리지는 최초 접근 시 생성되므로 저장소 서버가 일시적으로 사용할 수 없는 상태여도 이 호출은 성공합니다.
operationId createRepo
요청 본문: application/json · object
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 201 | 생성된 저장소 | Repo |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
| 409 | 이 프로젝트에 같은 이름의 저장소가 있습니다 (repo_exists) | Error |
GET /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}
단일 저장소
operationId getRepo
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 저장소 | Repo |
| 403 | — | — |
| 404 | — | — |
PATCH /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}
관리자 권한이 필요합니다. repo.update로 감사 기록됩니다.
이름 변경은 메타데이터 변경일 뿐입니다. 이름이 바뀌어도 이미 진행 중인 푸시는 중단되지 않습니다.
operationId updateRepo
요청 본문: application/json · object
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 204 | 변경됨 | — |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
| 409 | 같은 이름의 저장소가 이미 존재합니다 (repo_exists) | Error |
DELETE /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}
관리자 권한이 필요합니다. repo.delete로 감사 기록됩니다.
이는 소프트 삭제입니다. 저장소는 즉시 해당 URL에서 응답을 멈추며, 저장된 사본은 보관 기간이 지난 후 제거되므로 삭제를 되돌릴 수 있는 기간이 존재합니다.
operationId deleteRepo
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 204 | 삭제됨 | — |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/ref-updates
뷰어 이상의 권한이 필요합니다. 가장 최근 200개 항목입니다.
이는 감사 로그가 아니라 저장소 자체의 ref 기록입니다. 강제 푸시로 유실된 커밋을 복구하려면 old가 필요합니다.
operationId listRefUpdates
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | Ref 이력 | object |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/deploy-hook
viewer 이상이 필요합니다.
훅이 한 번도 설정된 적 없으면 configured는 false이며, 이는 훅이 존재하지만 꺼져 있는 경우(enabled)와는 다릅니다. 훅이 없으면 branch는 저장소의 기본 브랜치를 제안 값으로 담고 있습니다.
operationId getDeployHook
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 훅 | DeployHook |
| 403 | — | — |
| 404 | — | — |
PUT /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/deploy-hook
admin 권한이 필요하며, 배포 자체는 member 권한이 필요합니다.
훅이 켜져 있으면, 쓰기 권한이 있는 누구든 branch에 이후 수행하는 모든 푸시가 프로덕션 배포가 되며, 훅을 켠 사람의 신원으로 실행됩니다. 이는 상시 부여되는 권한이므로 deploy 범위 토큰으로는 생성할 수 없습니다.
필드를 생략하면 현재 값이 유지되므로, 스위치와 브랜치를 서로 초기화하지 않고 따로 전송할 수 있습니다.
operationId setDeployHook
요청 본문: application/json · object
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 현재 상태의 훅 | DeployHook |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
DELETE /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/deploy-hook
admin 권한이 필요합니다. 푸시 배포를 완전히 끕니다. 과거 빌드는 여전히 서빙 중인 배포를 만들어냈으므로 그대로 유지됩니다.
operationId deleteDeployHook
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 204 | 제거됨 | — |
| 403 | — | — |
| 404 | — | — |
POST /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/deploy
member 권한이 필요합니다. commitSha의 빌드를 큐에 넣거나, commitSha가 생략된 경우 훅이 연결된 브랜치의 최신 커밋을 빌드합니다.
이는 푸시 배포와 동일한 설정을 사용하므로, 푸시 배포 훅이 꺼져 있거나 없는 저장소는 빌드하는 대신 409 deploy_hook_off를 반환합니다. 훅이 없으면 루트 디렉터리도, 배포에 사용할 신원도 없기 때문입니다.
operationId deployRepoNow
요청 본문: application/json · object
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 202 | 큐에 추가됨 | object |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
| 409 | deploy_hook_off — 이 저장소에는 푸시 배포가 켜져 있지 않음 | Error |
GET /v1/orgs/{orgSlug}/projects/{projectName}/builds
viewer 이상의 권한이 필요합니다. 최신순으로 정렬되며 대기 중인 빌드가 맨 위에 표시됩니다.
이번 달 빌드 시간이 목록과 함께 반환되므로, 요청 한 번으로 빌드 화면에 필요한 모든 정보를 얻을 수 있습니다.
로그는 이 목록에 포함되지 않습니다. 로그는 최대 1 MiB 까지 커질 수 있어 /builds/{buildId}/log 에서 따로 받습니다.
operationId listBuilds
| 매개변수 | 위치 | 필수 | 타입 | 설명 |
|---|---|---|---|---|
limit | query | 아니오 | 정수 | — |
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 빌드 | object |
| 400 | — | — |
| 403 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/builds/{buildId}
빌드 하나(runlot builds show)
operationId getBuild
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 빌드 | Build |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/builds/{buildId}/log
viewer 이상의 권한이 필요합니다. JSON이 아니라 **text/plain**으로 반환됩니다 — 원시 빌드 출력이므로 클라이언트가 그대로 표시할 수 있습니다.
1MiB로 제한되며 끝부분을 유지합니다. 실패한 빌드에서는 오류가 끝부분에 있기 때문입니다. 제한이 적용되면 첫 줄에 그 사실이 표시됩니다.
operationId getBuildLog
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 로그 | string |
| 403 | — | — |
| 404 | — | — |
POST /v1/orgs/{orgSlug}/projects/{projectName}/builds/{buildId}/cancel
member 권한이 필요합니다. 대기 중인 빌드만 취소할 수 있습니다. 이미 시작된 빌드는 중단할 수 없으며 20분 후 자동으로 종료됩니다.
operationId cancelBuild
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 204 | 취소됨 | — |
| 403 | — | — |
| 404 | — | — |
| 409 | build_not_queued — 이미 빌드 중이거나 이미 종료됨 | Error |
GET /v1/me/ssh-keys
내 SSH 공개 키(runlot key list)
operationId listSSHKeys
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 키 목록 | object |
POST /v1/me/ssh-keys
공개 키 지문은 전역적으로 고유합니다. 키가 곧 신원이므로 동일한 키를 두 번 등록할 수 없습니다 — 이미 존재하는 키는 409 ssh_key_exists를 반환합니다.
허용: ed25519, ecdsa-sha2-nistp256/384/521, rsa (2048비트 이상). DSA는 거부됩니다.
operationId addSSHKey
요청 본문: application/json · object
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 201 | 등록된 키 | SSHKey |
| 400 | — | — |
| 409 | 공개 키가 이미 등록되어 있습니다 (ssh_key_exists) | Error |
DELETE /v1/me/ssh-keys/{keyId}
즉시 적용됩니다. 이 호출이 반환되는 즉시 키가 git 액세스에 작동하지 않게 되며, 캐싱 지연이 없습니다.
operationId deleteSSHKey
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 204 | 삭제됨 | — |
| 404 | — | — |
GET /v1/me/tokens
토큰 평문은 저장되지 않으므로 여기서 반환되지 않습니다.
operationId listAccessTokens
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 토큰 목록 | object |
POST /v1/me/tokens
평문 토큰은 이 응답에서만 반환됩니다. 다시 가져올 수 없습니다.
git은 HTTPS를 통해 Basic 인증을 전송하며, 사용자 이름은 무시되고 비밀번호 필드의 토큰만 읽힙니다. 접두사 runlot_pat_는 고정되어 있어 저장소, 로그, 붙여넣기에서 유출된 토큰을 기계적으로 감지할 수 있습니다.
토큰은 scopes 집합, org 또는 project 제한, 만료라는 세 가지 독립적인 축에서 좁힐 수 있습니다. 기본 만료는 90일이고 최대치는 365일이며, noExpiry는 기한 없는 자격 증명을 만드는 유일한 방법으로 명시적으로 설정해야 합니다.
org 또는 project 제한은 본인의 멤버십을 기준으로 확인되므로, 소속되지 않은 org에 토큰을 고정할 수 없습니다.
operationId createAccessToken
요청 본문: application/json · object
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 201 | 발급된 토큰(평문 포함) | AccessTokenCreated |
| 400 | — | — |
DELETE /v1/me/tokens/{tokenId}
토큰을 제거하는 대신 revokedAt을 설정하므로, 토큰 목록에서 수명을 계속 확인할 수 있습니다. 즉시 적용되며 캐싱 지연이 없습니다.
operationId revokeAccessToken
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 204 | 폐기됨 | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/refs
viewer 이상이 필요합니다.
저장소의 모든 브랜치와 태그를 기본 브랜치와 함께 나열합니다. 이는 대시보드에서 사용하는 탐색 API이며, 클론, 페치, 푸시는 대신 git 전송을 통해 이루어집니다.
operationId getRepoRefs
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | ref 목록 | RepoRefs |
| 403 | — | — |
| 404 | — | — |
| 503 | Git 호스팅을 일시적으로 사용할 수 없습니다 (git_unavailable, git_unreachable) | Error |
GET /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/tree
viewer 이상이 필요합니다. path가 비어 있으면 저장소 루트를 의미합니다.
디렉터리는 1000개 항목에서 잘립니다. 이 경우 응답에서 truncated가 true가 됩니다.
저장소를 벗어나는 경로(a/../..)는 404를 반환합니다.
operationId getRepoTree
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 디렉터리 | RepoTree |
| 403 | — | — |
| 404 | 저장소, ref, 또는 경로가 존재하지 않습니다 (no_ref·no_path) | Error |
GET /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/blob
viewer 이상이 필요합니다.
1MiB를 초과하는 파일은 내용과 함께 반환되지 않습니다 — tooLarge가 true이고 content는 비어 있습니다. 바이너리 파일도 내용을 포함하지 않습니다(binary가 true).
operationId getRepoBlob
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 파일 | RepoBlob |
| 403 | — | — |
| 404 | 저장소, ref, 또는 경로가 존재하지 않습니다 (no_ref·no_path) | Error |
GET /v1/orgs/{orgSlug}/projects/{projectName}/repos/{repoName}/commits
viewer 이상이 필요합니다. 최대 200개의 커밋을 반환하며 기본값도 200입니다.
operationId getRepoCommits
| 매개변수 | 위치 | 필수 | 타입 | 설명 |
|---|---|---|---|---|
limit | query | 아니오 | 정수 | — |
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 커밋 목록 | object |
| 403 | — | — |
| 404 | — | — |