tfx-ship
Skill7 starsChanged 13 days agoMITView on GitHub
triflux 전용 릴리즈 자동화. **GitHub Actions(버전 증가 PR 머지 / release.yml dispatch / npm-publish.yml) 기반 CI 릴리즈가 기본 경로 - npm publish 는 OIDC Trusted Publishing 으로 CI 가 수행하므로 로컬 npm login 불필요.** scripts/release/* 래퍼 + AskUserQuestion 기반 버전 선택 + CHANGELOG 편집 게이트 + Co-Authored-By/AI trailer 금지 강제. 'ship', '배포', '릴리즈', 'release', 'tfx-ship', 'publish' 같은 요청에 반드시 사용.
- Deletes or force-pushes
- Installs packages
- Commits and pushes
In this repository12 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- tfx-autoSkill
- tfx-doctorSkill
- tfx-harnessSkill
- tfx-leadSkill
- tfx-liveSkill
- tfx-remoteSkill
- tfx-researchSkill
- tfx-reviewSkill
- tfx-setupSkill
- tfx-wtSkill
The file
Files
tfx-ship - triflux 릴리즈 자동화
ARGUMENTS 처리: ARGUMENTS 가 있으면 첫 토큰을 version bump 타입 또는 명시 버전으로 해석. 플래그는
--skip-tests,--no-publish,--dry-run지원.
하드 룰 (절대 위반 금지):
- Commit 메시지에
Co-Authored-By:trailer 금지🤖 Generated with Claude Code/AI-assisted등 AI 공저자 언급 금지--no-verify,--no-gpg-sign,--amend금지 (사용자 명시 요청 전까지)git reset --hard,git push --force,git clean -f는 사용자 명시 승인 후에만- 버전 동기화:
scripts/release/version-manifest.json이 정한 8개 파일 전부 같은 버전 (release:check-sync가 강제).release:bump --write가 한 번에 갱신하므로 손으로 일부만 고치지 않는다
배포 채널
triflux 는 아래 3채널로 동시 배포. 각 채널의 버전은 반드시 동기화 상태 유지.
| # | 채널 | 명령 | 우선순위 |
| 1 | GitHub Releases | gh release create vX.Y.Z --notes-file <notes> | 공지 + changelog 공식 소스 |
| 2 | npm registry | CI npm-publish.yml (v* 태그 push 자동 / OIDC Trusted Publishing) | primary distribution |
| 3 | Claude Code marketplace | .claude-plugin/marketplace.json (source: npm 참조) | claude plugin add triflux |
- npm publish 는 로컬에서 하지 않는다 - 버전을 올린 PR 머지 후 ci 성공,
release.ymldispatch 또는v*태그 push 시npm-publish.yml이 OIDC 로 발행한다. 로컬publish.mjs --execute는 CI 불가 시 폴백 전용. - marketplace 는 자체 publish 명령이 없음. marketplace.json 의 version 만 갱신하면 git push 로 반영됨 (GitHub 호스팅).
release:check-sync가version-manifest.json의 8개 파일(package.json,packages/{core,remote,triflux}/package.json,.claude-plugin/plugin.json,mods/triflux/.claude-plugin/plugin.json,.claude-plugin/marketplace.json,package-lock.json) version 일치를 강제한다.
전제 조건
~/.claude/scripts/tfx-route.sh불필요 (CLI 워커 호출 없음)ghCLI 인증됨 (gh auth status) -release.ymldispatch / GitHub release 에 필요. 깨졌으면 웹 UI 대체- npm 인증 불필요 - npm publish 는 CI(
npm-publish.yml)가 OIDC 로 수행 (로컬npm login필요 없음) - 릴리즈할 커밋이
origin/main에 포함되어 있을 것. 자동 경로는 ci 의 head_sha, 수동 경로는 dispatch 시점의 github.sha 를 checkout 한다.
기본 경로 - CI 릴리즈 (권장)
PR 에서 npm run release:bump -- --version X --write 로 버전을 올려 main 에 머지하면,
같은 커밋의 ci 통과 뒤 release.yml 이 자동으로 실행된다. 버전을 안 올린 머지는 릴리즈하지 않는다.
자동 경로는 해당 커밋과 첫 번째 부모의 package.json 버전을 비교한다. 버전이 같거나 이미 태그가 있으면 건너뛰고, prerelease 는 수동 dispatch 로 진행한다.
main 이 앞서 있어도 해당 커밋이 origin/main 의 조상이면 릴리즈한다. 강제 푸시로 main 에서 사라진 커밋은 건너뛰고, 최신 안정 태그 이하로 버전이 역행하면 실패한다.
resolve 잡은 동시성 제한 없이 판정하고, 실제 release 잡만 release concurrency 그룹에서 직렬 실행한다. 자동 경로만 publish.mjs --allow-ancestor 를 사용하며 수동 경로는 기존 HEAD 동등성 검사를 유지한다.
버전을 올린 커밋 두 개가 거의 동시에 들어오면 앞의 대기 릴리즈가 취소될 수 있다. 해당 커밋의 ci 를 Re-run 하거나 release.yml 을 수동 dispatch 해 복구한다.
npm publish 는 로컬에서 하지 않는다. GitHub Actions 가 OIDC(Trusted Publishing)로 발행한다. 워크플로우:
.github/workflows/{release,npm-publish,ci}.yml
release.yml(workflow_run+workflow_dispatch, inputs:version,channel): prepare → 태그 + GitHub release(publish.mjs --skip-npm) → 태그 ref 와 channel 에 따른 npm_tag(stable=latest, canary=canary)로npm-publish.ymldispatch → 반환 URL의 run ID로 npm publish 완료 대기 →verify.mjs까지 CI(ubuntu, node 24)에서 수행한다. 자동 경로는 같은 커밋의 ci 가 전체 테스트를 통과했으므로 prepare 에서 테스트만 생략한다. 수동 dispatch 는 기존대로 테스트한다. npm 레지스트리 반영은 20초 간격으로 최대 900초 기다리고, 기대 버전이 아직 보이지 않으면 pending 경고를 남기고 통과한다. 구버전 gh 가 실행 URL을 반환하지 않으면 dispatch 직전 저장한 기존 실행 ID를 제외해 새 실행을 고른다.npm-publish.yml(on: push tags ['v*']+ dispatch):v*태그가 push 되면 자동 npm publish (--provenance --access public --tag "$NPM_TAG", OIDC 전용). dispatch 의 선택 입력npm_tag가 있으면 사용하고, 없으면 버전에-가 있을 때 canary, 그 밖에는 latest 로 게시한다. latest 와 canary 외의 값은 거부한다.@triflux/core,@triflux/remote,triflux3패키지 각각, 이미 게시된 버전은 skip. 세 패키지 모두 Trusted Publisher 등록이 필요하며npm trust list <패키지>로 확인한다.
수동 실행 - release.yml 디스패치
gh workflow run release.yml --ref main -f version=<X.Y.Z> -f channel=stable
# 진행 관찰
gh run list --workflow release.yml -L1
gh run watch "$(gh run list --workflow release.yml -L1 --json databaseId -q '.[0].databaseId')"- gh 인증이 없는 환경(예: SSH 로 들어간 원격 세션, gh 토큰 만료)이면 gh 가 정상인 머신에서 dispatch 하거나 GitHub 웹 UI(Actions → release → Run workflow)로 대체.
- CHANGELOG 가 필요하면 dispatch 전에 main 에 별도 커밋으로 반영(아래 로컬 플로우 Step 4 양식 참조).
경량 경로 - 태그만 push
이미 검증된 hotfix 등 prepare/verify 없이 npm publish 만 트리거하려면:
# main 에서 bump 커밋(버전 8개 파일 동기화) 후
git tag v<X.Y.Z> && git push origin v<X.Y.Z> # → npm-publish.yml 자동 발동⚠️ 이 경로는 GitHub release / verify 를 건너뛴다. 버전 동기화(
npm run release:check-sync통과)는 직접 보장.
로컬 수동 플로우 (폴백 - CI 불가 시에만)
CI 가 정석이다. 아래는 Actions 가 막혔거나 로컬 디버깅 시의 수동 절차다. Step 10 의 로컬
npm publish는 CI 와 중복이므로 평상시 실행 금지.
진행 체크리스트 (복사해서 진행 표시)
- [ ] 0 환경 확인 (main, clean, gh 인증, Node 22+)
- [ ] 1 버전 선택
- [ ] 2 release:check-sync 통과
- [ ] 3 release:bump --write
- [ ] 4 CHANGELOG 게이트 (사용자 승인)
- [ ] 5 pack.mjs 미러 + release:check-mirror 통과
- [ ] 6 release:prepare (테스트, lint, pack dry-run)
- [ ] 7 커밋 + 태그 (AI trailer 없음 확인)
- [ ] 8 push (사용자 확인)
- [ ] 9 GitHub release
- [ ] 10 CI npm-publish 성공 확인
- [ ] 11 release:verify -- --execute
- [ ] 12 사용자 알림실패하면 아래 단계로 돌아간다. 이미 push 한 뒤(Step 8 이후)에는 되돌리지 말고 사용자에게 보고한다.
| 실패 지점 | 돌아갈 단계 |
| Step 2, 3 동기화 불일치 | Step 2 다시 |
| Step 5 미러 불일치 | npm run release:check-mirror:fix 후 Step 5 다시 |
| Step 6 테스트/lint 실패 | 코드 수정 후 Step 6 다시. 미러 대상 파일을 고쳤다면 Step 5 부터 |
| Step 7 trailer 검출 | 커밋 재작성 후 Step 7 다시 |
| Step 8 push 거부 | git pull --rebase origin main 후 Step 2 부터 |
Step 0 - 환경 확인
cd "$REPO_ROOT"
git rev-parse --abbrev-ref HEAD # main 이어야 함
git status --porcelain # uncommitted 있으면 경고
git log --oneline origin/main..HEAD # unpushed 커밋 목록
gh auth status # gh 인증
node --version # Node 22+ 확인 (package.json engines >=22)조건:
- main 이 아닌 브랜치 → STOP. 사용자에게
git checkout main지시 또는 PR 플로우 안내 - uncommitted 있음 → AskUserQuestion: "먼저 커밋할까? / ship 에 포함 / 취소"
- behind origin →
git pull origin main먼저 실행
Step 1 - 버전 선택
ARGUMENTS 에 version 있으면 그 값 사용. 없으면 AskUserQuestion:
현재: v{CURRENT}
어떤 버전으로 올릴까요?
A) patch (v{CURRENT +0.0.1}) - bug fix / small refactor
B) minor (v{CURRENT +0.1.0}) - 새 기능, backward compatible
C) major (v{CURRENT +1.0.0}) - breaking change
D) custom - 직접 입력선택된 버전을 TARGET_VERSION 으로 저장.
Step 2 - 버전 동기화 사전 체크
npm run release:check-sync불일치 시:
- 자동 수정 제안:
npm run release:check-sync:fix - 사용자 승인 후 실행
Step 3 - 버전 bump
npm run release:bump -- --version "$TARGET_VERSION" --write이 스크립트가 package.json + .claude-plugin/marketplace.json + package-lock.json 을 갱신한다.
MANDATORY
--write: 플래그가 없으면 CLI가 경고를 출력하고 변경 없이 종료한다. 버전을 갱신하려면 반드시--write를 지정한다.
Step 4 - CHANGELOG 초안 생성
git log --oneline <previous-tag>..HEAD 로 범위 커밋 나열 후, Claude 가 아래 섹션 구조로 초안 작성:
## [{TARGET_VERSION}] - {YYYY-MM-DD}
### Fixed
- **[#<issue>]** <commit subject 에서 추출>
### Added
- **[#<issue>]** <subject>
### Changed
- ...
### Tests
- ...초안 → CHANGELOG.md 최상단 항목 위에 삽입 → AskUserQuestion:
CHANGELOG 초안 (미리보기)
A) 이대로 저장 후 계속
B) 편집하고 계속 (사용자가 에디터에서 수정 후 진행)
C) 취소Step 5 - pack.mjs 미러
release:prepare 의 npm pack --dry-run 이 packages/triflux 를 검사하므로 미러를 먼저 만든다.
node scripts/pack.mjs all
npm run release:check-mirror주의:
- CRLF→LF 변환 경고 대량 발생 가능
git status로 실제 변경 파일만 선별 스테이징- 예:
git add packages/triflux/(구체 경로 지정) check-mirror가 실패하면npm run release:check-mirror:fix
Step 6 - 테스트 + 빌드 검증
npm run release:prepare -- --execute --version "$TARGET_VERSION" --allow-dirty
--allow-dirty사실상 필수: Step 3 의release:bump --write가package.json/marketplace.json/package-lock.json을 갱신해 working tree 를 dirty 상태로 만든다.--allow-dirty없으면 prepare 의 working tree 검사가 거부한다. bump 와 prepare 사이에 commit 단계가 없으므로 항상 필수.
이 스크립트가 수행:
assertVersionSyncensureGitClean- 테스트:
scripts/test-lock.mjs로tests/**와scripts/__tests__/**를 실행 (10분 timeout) npm run lintnpm pack --dry-run(packages/triflux에서)- 릴리즈 노트 생성 →
.omx/plans/release-notes-v{VERSION}.md
--skip-tests 플래그 있으면 테스트 건너뜀 (위험, stderr 에 npm-test:skipped 단계만 남는다).
실패 시 → STOP. 사용자에게 에러 보여주고 위 체크리스트의 돌아갈 단계를 안내한다.
Step 7 - Commit + Tag
커밋 메시지 (절대 Co-Authored-By 등 포함 금지):
git add package.json package-lock.json .claude-plugin/marketplace.json CHANGELOG.md packages/
git commit -m "chore(release): bump version to v${TARGET_VERSION}"
git tag "v${TARGET_VERSION}"MANDATORY: HEREDOC 으로 커밋 메시지 전달. Co-Authored-By 트레일러 절대 금지. AI 공저자 언급 금지.
.gitmessage 템플릿이 AI trailer 를 자동 주입하는 경우 제거. Claude-Session: 같은 세션 꼬리표도 넣지 않는다.
Step 8 - Push
AskUserQuestion (릴리즈 전 마지막 확인):
준비 완료. push 하시겠습니까?
A) git push origin main --tags (권장)
B) tag 없이 push (수동 tag 후처리)
C) 중단 - 로컬에만 유지선택 A 시:
git push origin main
git push origin "v${TARGET_VERSION}"Step 9 - GitHub Release
NOTES_PATH=".omx/plans/release-notes-v${TARGET_VERSION}.md"
gh release create "v${TARGET_VERSION}" \
--title "v${TARGET_VERSION}" \
--notes-file "$NOTES_PATH"주의:
- 노트 본문 검증: Co-Authored-By / AI trailer 포함되었는지 grep 후 제거
--draft로 초안 생성 후 수동 publish 도 가능 (안전 모드)
Step 10 - npm publish (= CI 가 수행, 로컬 금지가 기본)
평상시 로컬에서
npm publish하지 않는다. Step 8 에서git push origin v<X.Y.Z>로 태그가 올라가면npm-publish.yml이 OIDC 로 자동 발행한다. CI run 관찰:gh run list --workflow npm-publish.yml -L1→gh run watch <id>
CI 가 완전히 불가능한 비상시에만, npm 인증을 갖춘 환경에서 수동 폴백. 이 명령은 세 패키지 npm publish, 태그 생성과 push, git push origin HEAD, GitHub release 생성까지 한 번에 수행하므로 Step 7 의 태그, Step 8, Step 9 를 이미 했다면 쓰지 않는다 (--skip-npm, --skip-gh-release, --tag-only, --allow-existing 으로 일부 생략 가능). 플래그는 임의로 더하지 않는다:
node scripts/release/publish.mjs --execute # 비상 폴백 전용Step 11 - 사후 검증 (3채널 전부)
npm run release:verify -- --version "$TARGET_VERSION" --execute --npm-wait-seconds 900 --npm-pending-ok--execute 가 없으면 verify 는 실행할 명령만 출력하고 아무것도 확인하지 않는다.
verify 가 확인하는 것: 버전 동기화, npm view 로 @triflux/core, @triflux/remote, triflux 세 패키지의 새 버전, gh release view v${TARGET_VERSION}. 아래는 직접 확인한다:
- GitHub tag 존재 (
git ls-remote --tags origin | grep "v${TARGET_VERSION}") - marketplace.json version 일치 (
npm run release:check-sync)
Step 12 - 사용자 알림
RELEASE COMPLETE ✓
version: v${TARGET_VERSION}
tag: v${TARGET_VERSION}
npm: published
github: https://github.com/tellang/triflux/releases/tag/v${TARGET_VERSION}
다음:
- Claude Code 에서 plugin update: claude plugin update triflux
- 또는 npm: npm i -g triflux@${TARGET_VERSION}에러 처리
| 단계 | 에러 | 복구 |
| Step 0 | 브랜치가 main 아님 | git checkout main 또는 PR 플로우 |
| Step 0 | unpushed 커밋 있음 (ship 전 확인) | 정상 - 릴리즈 대상 |
| Step 0 | uncommitted 변경 | 먼저 커밋 / ship 에 흡수 / 취소 선택 |
| Step 2 | 버전 동기화 실패 | npm run release:check-sync:fix 실행 |
| Step 5 | 미러 불일치 | npm run release:check-mirror:fix |
| Step 6 | 테스트 실패 | 수정 후 재시도. --skip-tests 는 위험 |
| Step 6 | lint 실패 | npm run lint:fix 후 재시도 |
| Step 7 | commit 메시지에 AI trailer 감지 | 하드 차단 + 재작성 요청 |
| Step 8 | push 거부 (remote 변경됨) | git pull --rebase origin main 후 재시도 |
| Step 9 | gh release create 실패 | gh auth status 확인, 수동 재시도 |
| Step 10 | npm publish(CI) 실패 | gh run view <id> --log-failed 로 npm-publish.yml 로그 확인. 세 패키지의 OIDC Trusted Publisher 설정 점검 |
플래그
| 플래그 | 동작 |
--skip-tests | Step 6 의 테스트 건너뜀. 긴급 hotfix 전용 |
--no-publish | 태그를 push 하지 않아 npm-publish.yml 미발동. main 커밋 + (수동) GitHub release 만 |
--dry-run | 모든 git push / publish 호출을 출력만 하고 skip. 검증 전용 |
AI trailer 방지 상세
커밋 메시지 작성 시 절대 포함하지 말 것:
❌ Co-Authored-By: Claude <noreply@anthropic.com>
❌ 🤖 Generated with Claude Code
❌ AI-assisted by Claude
❌ Authored by AI커밋 직전 git log -1 --format=%B 로 메시지 검증. 위 패턴 감지 시 git reset HEAD~ 후 재작성.
.gitmessage / .git/hooks/prepare-commit-msg 에 AI trailer 자동 주입 훅이 있으면 해당 훅 제거 제안.
참고
- 기존 릴리즈 스크립트:
scripts/release/{bump-version,check-sync,check-packages-mirror,prepare,publish,resolve-auto-release,verify,lib}.mjs - version 동기화 manifest:
scripts/release/version-manifest.json - 이전 릴리즈 커밋 패턴:
git log --oneline | grep "chore(release): bump version"
Troubleshooting
- 버전 불일치:
npm run release:check-sync:fix - pack CRLF 경고: 실제 변경 파일만 선별
git add packages/triflux/... - gh CLI 미인증:
gh auth login(또는 gh 정상인 머신/웹 UI 로 release.yml dispatch) - npm publish 는 CI(
npm-publish.yml, OIDC)가 수행 - 로컬npm login불필요. CI 실패 시gh run view <id> --log-failed
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

