Bitbucket Server
bitbucket-server 스킬 완전 가이드.
GS Retail 자체 호스팅 Bitbucket Data Center REST API — PAT 설정, 탐색, PR 읽기/쓰기, 브랜치, 코드 검색, Code Insights.
베이스 URL: https://code.gsretail.com — GS Retail 자체 호스팅 Bitbucket Data Center. GitHub와 다른 API 구조를 사용합니다.

인증 설정

# 환경변수로 PAT 저장 (절대 echo하거나 로그에 출력하지 말 것)
export BITBUCKET_TOKEN="your-http-access-token"

# 모든 요청에 Bearer 헤더 사용
curl -sS \
  -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  -H "Content-Type: application/json" \
  "https://code.gsretail.com/rest/api/latest/projects"
보안 주의: curl -v 대신 -w '%{http_code}'를 사용해 헤더(토큰 포함)가 로그에 노출되지 않도록 합니다. PAT는 절대 소스 코드나 로그에 포함하지 마세요.

API 루트

core/rest/api/latest/ — repos, PRs, commits, files, comments, activities 등 대부분의 작업
branch/rest/branch-utils/latest/ — 브랜치 생성/삭제 (/rest/api/latest/가 아님에 주의)
search/rest/search/latest/ — 코드 검색 (GET이 아닌 POST 사용)
insights/rest/insights/latest/ — Code Insights (CI 결과, 정적 분석 결과 게시)

프로젝트 · 레포 탐색

# 모든 프로젝트 목록
curl -sS -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  "https://code.gsretail.com/rest/api/latest/projects?limit=50"

# 프로젝트 내 레포 목록
# 프로젝트 키: UPPERCASE, 레포 슬러그: lowercase
curl -sS -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  "https://code.gsretail.com/rest/api/latest/projects/GSR/repos?limit=50"

# 현재 git remote에서 프로젝트 키와 레포 슬러그 추출
git remote get-url origin
# https://code.gsretail.com/scm/GSR/my-repo.git
# → PROJECT_KEY=GSR, REPO_SLUG=my-repo

파일 브라우징

BASE="https://code.gsretail.com/rest/api/latest/projects/GSR/repos/my-repo"

# 디렉토리 내용 조회
curl -sS -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  "$BASE/browse/src/components?at=main"

# 파일 내용 조회
curl -sS -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  "$BASE/browse/src/components/Button.tsx?at=main" | jq -r '.lines[].text'

# 특정 커밋의 파일
curl -sS -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  "$BASE/browse/package.json?at=abc123"

PR 읽기

BASE="https://code.gsretail.com/rest/api/latest/projects/GSR/repos/my-repo"

# PR 목록 (OPEN 상태)
curl -sS -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  "$BASE/pull-requests?state=OPEN&limit=25" | jq '.values[] | {id,title}'

# 특정 PR 상세
curl -sS -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  "$BASE/pull-requests/42" | jq '{id,title,state,author}'

# PR diff
curl -sS -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  "$BASE/pull-requests/42/diff"

# PR activities (코멘트, 승인, 커밋 등 전체 히스토리)
curl -sS -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  "$BASE/pull-requests/42/activities?limit=50"

PR 쓰기 · 코멘트

# PR 생성
curl -sS -X POST \
  -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "feat: 장바구니 기능 추가",
    "description": "## 요약\n...",
    "fromRef": {"id": "refs/heads/feat/cart", "repository": {"slug": "my-repo", "project": {"key": "GSR"}}},
    "toRef":   {"id": "refs/heads/main",      "repository": {"slug": "my-repo", "project": {"key": "GSR"}}},
    "reviewers": [{"user": {"name": "reviewer1"}}]
  }' \
  "https://code.gsretail.com/rest/api/latest/projects/GSR/repos/my-repo/pull-requests"

# 일반 코멘트 게시
curl -sS -X POST \
  -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"text": "LGTM!"}' \
  "https://code.gsretail.com/rest/api/latest/projects/GSR/repos/my-repo/pull-requests/42/comments"

# 인라인 코멘트 (파일의 특정 라인)
curl -sS -X POST \
  -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "이 함수는 에러 케이스를 처리하지 않습니다.",
    "anchor": {
      "line": 42,
      "lineType": "ADDED",
      "fileType": "TO",
      "path": "src/cart/service.ts"
    }
  }' \
  "https://code.gsretail.com/rest/api/latest/projects/GSR/repos/my-repo/pull-requests/42/comments"
PUT은 완전 교체입니다. Bitbucket Server에는 PR용 PATCH 엔드포인트가 없습니다. PR 수정 시 반드시 먼저 GET으로 읽고, 변경할 필드만 수정한 후 전체를 PUT으로 보내야 합니다.

브랜치 관리

# 브랜치 생성 (branch-utils 루트 사용!)
curl -sS -X POST \
  -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "feat/new-feature",
    "startPoint": "main"
  }' \
  "https://code.gsretail.com/rest/branch-utils/latest/projects/GSR/repos/my-repo/branches"

# 브랜치 목록 (api 루트 사용)
curl -sS -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  "https://code.gsretail.com/rest/api/latest/projects/GSR/repos/my-repo/branches?limit=25"
# 코드 검색 — POST 사용 (GET이 아님!)
curl -sS -X POST \
  -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "createUser",
    "entities": {"code": {"scopes": [{"type": "REPOSITORY", "key": "GSR/my-repo"}]}}
  }' \
  "https://code.gsretail.com/rest/search/latest/search"

페이지네이션

# 응답 구조 — start+size 방식이 아닌 isLastPage+nextPageStart 사용
{
  "values": [...],
  "isLastPage": false,
  "nextPageStart": 25,   # 다음 요청에 start= 파라미터로 사용
  "size": 25,
  "limit": 25
}

# 다음 페이지 요청
curl -sS -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  "$BASE/pull-requests?limit=25&start=25"

# 전체 결과 수집 셸 스크립트
START=0
while true; do
  RESP=$(curl -sS -H "Authorization: Bearer $BITBUCKET_TOKEN" \
    "$BASE/pull-requests?limit=25&start=$START")
  echo "$RESP" | jq '.values[]'
  IS_LAST=$(echo "$RESP" | jq -r '.isLastPage')
  [ "$IS_LAST" = "true" ] && break
  START=$(echo "$RESP" | jq -r '.nextPageStart')
done

Code Insights

# CI 결과를 Code Insights로 Bitbucket에 게시
curl -sS -X PUT \
  -H "Authorization: Bearer $BITBUCKET_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "My CI Pipeline",
    "reporter": "my-ci",
    "result": "PASS",
    "details": "All 142 tests passed",
    "data": [
      {"title": "Tests", "type": "NUMBER", "value": 142},
      {"title": "Coverage", "type": "PERCENTAGE", "value": 87.5}
    ]
  }' \
  "https://code.gsretail.com/rest/insights/latest/projects/GSR/repos/my-repo/commits/abc123/reports/my-ci"

주요 함정 (Gotchas)

PUT은 완전 교체

PR 업데이트는 PATCH가 없음. 항상 GET → 수정 → PUT 전체 전송.

브랜치 생성은 별도 루트

branch-utils 루트 사용. /rest/api/latest/로는 브랜치 생성 불가.

코드 검색은 POST

/rest/search/latest/search는 GET이 아닌 POST로 요청.

타임스탬프는 Unix 밀리초

모든 날짜가 ms 단위. 읽을 때 1000으로 나눠야 함. date -r $((ts/1000))

/users/me 없음

현재 사용자 정보 API 없음. 신원은 PAT에 암시적으로 포함.

blocker = BLOCKER severity comment

별도 /tasks 엔드포인트 없음. blocker 코멘트는 severity=BLOCKER인 comment로 처리.

프로젝트 키는 대문자

GSR (UPPERCASE). 레포 슬러그는 소문자 kebab-case.

curl -v 금지

verbose 모드는 Authorization 헤더(토큰)를 터미널에 출력함. 항상 -w '%{http_code}' 사용.

엔드포인트 빠른 참조

작업Method엔드포인트
프로젝트 목록GET/rest/api/latest/projects
레포 목록GET/rest/api/latest/projects/{key}/repos
파일 내용GET/rest/api/latest/projects/{key}/repos/{slug}/browse/{path}
커밋 목록GET/rest/api/latest/projects/{key}/repos/{slug}/commits
PR 목록GET/rest/api/latest/projects/{key}/repos/{slug}/pull-requests
PR 생성POST/rest/api/latest/projects/{key}/repos/{slug}/pull-requests
PR 수정PUT/rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}
PR diffGET/rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/diff
PR activitiesGET/rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/activities
코멘트 게시POST/rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/comments
브랜치 생성POST/rest/branch-utils/latest/projects/{key}/repos/{slug}/branches
브랜치 목록GET/rest/api/latest/projects/{key}/repos/{slug}/branches
코드 검색POST/rest/search/latest/search
Code InsightsPUT/rest/insights/latest/projects/{key}/repos/{slug}/commits/{hash}/reports/{key}