| name | ship |
| description | 지금까지의 작업을 한 번에 출하한다 — 커밋 → push → PR 생성 → squash merge. "commit push pr squash merge", "ship it", "출하해줘", "PR 만들고 머지해줘", "커밋푸시 PR 스쿼시", "변경사항 commit push 후 pr 생성하고 squash merge" 등 commit+push+PR+merge를 한 번에 끝내려는 의도에서 트리거된다. 커밋만/푸시만 원하면 commit skill을 쓴다. |
ship
작업을 main(기본 브랜치)으로 squash merge 까지 한 번에 출하하는 skill.
사람의 판단이 필요한 커밋 작성은 이 본문이 처리하고, push→PR→merge
의 결정적 plumbing 은 scripts/ship.sh 가 처리한다.
안전 규칙 (어기지 말 것)
- force push 금지,
--no-verify/--no-gpg-sign 금지. 훅이 실패하면
우회하지 말고 원인을 고친다.
- 기본 브랜치(
main/master)에 직접 커밋·머지하지 않는다 — 항상 feature
브랜치 → PR.
- 검증을 약화시켜 머지하지 않는다. required check 가 막으면 auto-merge로
큐잉하거나 통과를 기다린다. check 우회(
--admin)는 사용자가 명시적으로
요청했을 때만(SHIP_ADMIN=1).
- 시크릿/대용량 산출물을 커밋하지 않는다(commit skill의 secret-scan 준수).
워크플로
1. 변경 파악 + 커밋
git status --short && git diff --stat
- 커밋할 게 없고 브랜치가 이미 base 보다 앞서 있으면 → 바로 3번(이미 커밋됨).
- 변경이 있으면 커밋한다. 프로젝트에 commit skill 이 있으면 그 규약을
따른다. 없으면 Conventional Commits (
feat:/fix:/docs:/refactor:
…), 제목은 명령형 한 줄, 본문은 왜 를 설명. 관련 변경만 스테이징.
2. 브랜치 보장
현재 브랜치가 기본 브랜치면 feature 브랜치를 먼저 만든다(커밋 전에).
DEF="$(gh repo view --json defaultBranchRef --jq .defaultBranchRef.name)"
CUR="$(git branch --show-current)"
if [ "$CUR" = "$DEF" ]; then
git checkout -b <type>/<slug>
fi
이미 feature 브랜치(예: 워크트리 브랜치)면 그대로 둔다.
3. push → PR → squash merge
bash <cc-system>/.claude/skills/ship/scripts/ship.sh
ship.sh 가 하는 일: 프리플라이트(클린 트리·non-default 브랜치·base 대비
ahead 확인) → git push -u origin HEAD → 기존 PR 재사용 또는 gh pr create
→ gh pr merge --squash. 즉시 머지가 required check 로 막히면 auto-merge
로 큐잉하고 그 사실을 정직하게 보고한다. 머지 성공 후 원격 브랜치는 따로
삭제(best-effort)한다.
옵션: --base <b>, --title, --body, --no-merge(PR만), --draft.
4. 결과 보고 (정직하게)
ship.sh 의 마지막 출력으로 상태를 그대로 전한다:
✅ MERGED — squash merge 완료.
⏳ auto-merge queued — check 통과 후 자동 머지 예정. "머지됨"이라고
말하지 말 것. check 가 끝나면 머지된다고 안내.
- auto-merge 불가(exit 3) — PR 은 열려 있음. check 통과를 기다렸다가
(필요시 polling)
gh pr merge <url> --squash 로 마무리.
여러 repo 출하
repo 마다 cwd 를 바꿔(또는 git -C) 1~4를 반복한다. ship.sh 는 cwd 의
repo 에 대해 동작하므로 repo-agnostic 하다. 한 repo 가 막혀도(검증 대기 등)
다른 repo 출하를 멈추지 말고, 막힌 항목은 상태를 기록하고 끝까지 진행한다.
worktree 주의
gh pr merge --delete-branch 는 머지 후 로컬을 base 브랜치로 전환하려 하는데,
base 가 다른 worktree 에 체크아웃돼 있으면
(fatal: '<base>' is already used by worktree …) 실패한다. 그래서 ship.sh
는 --delete-branch 를 쓰지 않고, 머지 후 원격 브랜치만 따로 삭제하며
로컬 브랜치는 건드리지 않는다. 또한 머지 판정을 exit code 가 아니라
gh pr view 의 실제 PR 상태로 한다 — gh 가 머지 성공 후 로컬 단계에서
non-zero 로 끝나도 머지 실패로 오인하지 않는다.