Skip to content
Back to skills

Yd Git Ship

ASecurity

doksam GitLab 레포에 에이전트(Claude Code·Codex·Antigravity)가 작업을 올리는 절차 — 이슈 등록, batch/<agent>-<날짜>-<8자리 hex> 브랜치, "[<model>] <type>: <desc> (#N)" 커밋, Closes MR, merge commit(squash 금지), CI 추적, commit-msg hook 설치. "커밋", "푸시", "MR", "머지", "올려", "이슈 등록", "ship" 등 git/GitLab 에 뭔가 남길 때마다 사용.

  • 12 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 4, 2026
ai-agentspythonbashgitapi

Works with

  • claude code
  • api

Security analysis

A100/100

Pro scans all 12 files and shows the line behind each finding

Scanned October 5, 2026

npx -y skills add LeeYudok/doksam-skills --skill yd-git-ship --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Yd Git Ship?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Yd Git Ship
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/leeyudok-yd-git-ship/badge)](https://www.skillsdirectory.com/skills/leeyudok-yd-git-ship)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: yd-git-ship
description: 'doksam GitLab 레포에 에이전트(Claude Code·Codex·Antigravity)가 작업을 올리는 절차 — 이슈 등록, batch/<agent>-<날짜>-<8자리 hex> 브랜치, "[<model>] <type>: <desc> (#N)" 커밋, Closes MR, merge commit(squash 금지), CI 추적, commit-msg hook 설치. "커밋", "푸시", "MR", "머지", "올려", "이슈 등록", "ship" 등 git/GitLab 에 뭔가 남길 때마다 사용.'
---

# yd-git-ship — 에이전트 작업을 GitLab 에 올리기

규칙 원본은 `~/.claude/ref-git-agents.md` (세 에이전트 공통, agents-mem 의 공통본을 각 호스트에 동기화). 이 스킬은 그 규칙을 따르는 **절차와 도구**다. 규칙과 이 문서가 다르면 원본이 우선한다. 원본 파일이 없는 환경(새 머신, 외부 설치)에서는 이 문서의 절차가 곧 규칙이다.

스크립트 위치: 이 스킬 폴더의 `scripts/` (Claude `~/.claude/skills/yd-git-ship`, Codex `~/.agents/skills/yd-git-ship`, Antigravity `~/.gemini/config/skills/yd-git-ship` — 모두 doksam-skills `install.sh` 가 건 같은 원본의 심링크).

## 0. 내 값 정하기

| | Claude Code | Codex | Antigravity |
|---|---|---|---|
| `AGENT` | `claude` | `codex` | `agy` |
| 커밋 `-c` | `user.name=claude-ai user.email=claude-ai@doksam.com` | `codex-ai` / `codex-ai@doksam.com` | `agy-ai` / `agy-ai@doksam.com` |
| 모델 태그 | 지금 도는 모델 이름, 예 `[Claude Opus 5.5]` | 예 `[GPT-6 Sol]` | 예 `[Gemini 3.8 Flash]` |

모델 태그는 추측하지 말고 자기 시스템 정보에 적힌 실제 모델명을 쓴다.

```bash
SK=~/.claude/skills/yd-git-ship/scripts      # 에이전트별 경로로
GL="$SK/glab-as.sh claude"                  # 토큰을 출력하지 않고 자기 계정으로 glab 실행
REPO=gitlab.doksam.com/<ns>/<repo>          # -R 에는 호스트까지 붙인다. 명령은 그 레포 폴더 안에서
$GL api user | grep '"username"'            # claude-ai 인지 확인
```

`glab-as.sh` 는 Python 3.11 미만(tomllib 없음)에서도 요청한 계정 섹션의 토큰만 읽는다. 호출한 셸의 PATH 에 따라 시스템 Python 3.9 가 잡혀도 동작한다.

## 1. 시작 전 점검

```bash
git status -sb; git branch --show-current
$GL api "projects/<ns>%2F<repo>/merge_requests?state=opened&author_username=claude-ai"   # 내 열린 MR 있으면 그것부터 머지
$GL api "projects/<ns>%2F<repo>" | python3 -c 'import json,sys;p=json.load(sys.stdin);print(p["squash_option"],p["merge_method"])'
$SK/install-hook.sh --check || $SK/install-hook.sh   # 없으면 설치 → scripts/commit-msg.sh 를 첫 커밋에 포함
```

- `squash_option` 이 `always` 면 squash 금지 규칙과 충돌하니 사용자에게 알린다. `merge_method` 가 `ff` 면 merge commit 이 안 생기니 역시 알린다.
- 레포 AGENTS.md 에 "squash 머지" 같은 옛 문구가 있으면 원본 규칙이 우선이고, 이번 배치에서 같이 고친다.
- hook 은 본문의 `Co-Authored-By: Claude` 와 `Generated with Claude Code` 줄을 사람 커밋이어도 거부한다. `Merge` 로 시작하는 제목은 형식 검사에서 뺀다.
- jj 레포(`.jj/`)는 `jj commit` 이 git hook 을 안 돌린다. 커밋 제목을 직접 맞추고 push 전 `git log` 로 확인한다.

## 2. 이슈

작업 단위마다 이슈. 본문은 파일로 쓰고 "누가 판정하나"를 넣는다.

```bash
$GL issue create -R $REPO --title "..." --description "$(cat body.md)" --yes
```

## 3. 배치 브랜치 · 커밋 · push

```bash
git switch main && git pull -q
git switch -c "batch/claude-$(date +%Y%m%d)-$(openssl rand -hex 4)"   # 배치마다 새 8자리 hex
BR=$(git branch --show-current)                    # 셸 상태가 안 이어지면 쓸 때마다 이렇게 다시 읽는다
git add <명시 파일만>                               # -A 금지, .env 금지
if git diff --cached | grep -iE 'glpat-|ghp_|password[[:space:]]*[:=]|secret[[:space:]]*[:=]|token[[:space:]]*[:=]'; then
  echo "시크릿 의심 — 커밋하지 않고 멈춘다(값을 확인하고 스테이징에서 뺀다)"
else
  git -c user.name=claude-ai -c user.email=claude-ai@doksam.com commit -m "[Claude Opus 5.5] docs: ... (#N)" \
    && git push -u origin HEAD                     # 수시로 push, MR 은 아직
fi
```

- 브랜치는 `batch/<agent>-<YYYYMMDD>-<8자리 hex>` 다. hex 는 배치를 시작할 때 `openssl rand -hex 4` 로 한 번 만들고 MR·정리까지 같은 이름을 쓴다.
  날짜 뒤 `-2`·`-3` 순번은 쓰지 않는다. 같은 에이전트의 세션 둘이 같은 순번을 골라 겹친다(아래 Learned warnings).
- 머지하며 지운 브랜치 이름을 다시 push 하지 않는다. 다음 배치는 새 hex 로 시작한다.
- 이슈별로 커밋을 나눈다(merge commit 으로 합쳐도 이슈 단위 `git revert` 가 되게).
- hook 이 막으면 메시지를 고친다. `--no-verify` 로 우회하지 않는다(오타 수준만 `YD_TRIVIAL=1`).

## 4. MR · 머지

```bash
$GL mr create -R $REPO --source-branch "$(git branch --show-current)" --target-branch main \
  --title "[Claude Opus 5.5] <요약>" --description "$(cat mr.md)" --remove-source-branch --yes
# mr.md 에 반드시: Closes #a #b ...   (Refs 만 쓰지 않는다)
$GL mr merge <iid> -R $REPO --remove-source-branch --yes        # --squash 붙이지 않는다
```

- push 직후 `mr merge` 가 `405 Method Not Allowed` 면 GitLab 이 아직 mergeability 를 계산 중이다(`detailed_merge_status: checking`). `mergeable` 이 될 때까지 몇 초 기다렸다가 다시 머지한다.
- 이슈를 닫으면 안 되는 부분 작업이면, 그 부분만 다루는 이슈를 새로 만들어 `Closes` 한다.
- 다른 에이전트가 먼저 머지해 충돌나면 `git merge origin/main` 으로 풀고 push (rebase·force push 금지).
- glab 은 **그 레포 폴더 안에서** 실행하고 출력을 `| tail` 로 자르지 않는다. `mr create` 는 현재 폴더의 remote 를 source 로 잡아서, 다른 폴더에서 돌리면 `422 Source project is not a fork` 가 나는데 `tail` 이 그걸 가린다. 실패하면 `--recover` 로 재시도.

## 5. 머지 후

```bash
$GL api "projects/<ns>%2F<repo>/merge_requests/<iid>" | python3 -c 'import json,sys;m=json.load(sys.stdin);print(m["state"],m["merge_commit_sha"],m["squash"])'
python3 $SK/ci_wait.py --agent claude <ns>/<repo> <merge_commit_sha>   # run_in_background 로. 배포 잡까지 끝나야 완료
$GL api "projects/<ns>%2F<repo>/issues/<N>" | grep '"state"'   # opened 면 note + close
BR=$(git branch --show-current); git switch main && git pull -q && git branch -d "$BR"
git log -1 --format='%an %s'                                   # 작성자·태그 확인
```

`ci_wait.py` 종료 코드는 0 성공(또는 파이프라인 없음), 1 실패·취소, 2 시간 초과, 3 도구 오류(glab 실패·토큰 없음)다. 3 을 CI 실패로 읽지 말고 토큰·네트워크부터 확인한다.

`m["squash"]` 가 true 면 규칙 위반이다. 사용자에게 보고한다(되돌리려면 force push 가 필요하므로 임의로 고치지 않는다).

## 메모리 미러처럼 코드 없는 운영 갱신

main 직접 커밋이 허용되는 예외지만 제목 규칙은 지킨다: `[Claude Opus 5.5] chore: sync memory mirror (#N)`.

## Learned warnings

- (2026-10-05) 같은 에이전트(claude)의 세션 두 개가 같은 날 각자 `batch/claude-20261005-8` 을 골랐다. 한쪽이 llmgw#57 을 머지하며 브랜치를 지웠다. 직후 다른 쪽이 같은 이름으로 같은 기능을 push 했다. 작업이 중복되고 MR(!46)이 충돌로 남았다. 날짜 뒤 순번 대신 배치마다 `openssl rand -hex 4` 8자리를 붙인다 (#205).

Files in this skill

  • SKILL.md6.5 KB
  • scripts/ci_wait.py2.4 KB
  • scripts/commit-msg.sh1.9 KB
  • scripts/glab-as.sh1 KB
  • scripts/install-hook.sh1.6 KB
  • scripts/read_token.py2.2 KB
  • tests/claims.json4.3 KB
  • tests/test_ci_wait.py5.5 KB
  • tests/test_commit_msg.py4 KB
  • tests/test_glab_as.py3.1 KB
  • tests/test_glab_as_fallback.py3.2 KB
  • tests/test_install_hook.py3.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.