بنقرة واحدة
release
kaji の release 作業(version bump / CHANGELOG / tag / GitHub Release ページ)を進め、PyPI publish workflow へ引き継ぐ。
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
kaji の release 作業(version bump / CHANGELOG / tag / GitHub Release ページ)を進め、PyPI publish workflow へ引き継ぐ。
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
設計書(draft/design/)に基づき、TDD(テスト駆動開発)アプローチを用いて機能を実装する。
実装完了後の成果物に対し、設計整合性とコード品質の観点から厳格なレビューを実施する
Issue 作成後・workflow 起動前に人間が明示起動する要件 interview。one-way door を含みうる重要な Issue で、未決の decision tree を 1 問ずつ推奨案付きで確認し、決定事項と provenance を Issue に固定するときだけ使用する。軽微な Issue や workflow 実行中には自動起動しない。
第2層のインシデント調査レビュー収束サイクルを 1 コマンドで手動起動する slash command wrapper。kaji run .kaji/wf/official/incident.yaml <incident_issue_id> を Bash 経由で起動し、exit code を verdict に縮約する。
Issue要件に基づき、draft/design/に設計書を作成する。worktree内での作業が前提。
ワークフローを手動実行して検証し、失敗時は継続せず原因を調査して Issue に記録する。成功時も気づきや詰まりどころを Issue に記録する。
| description | kaji の release 作業(version bump / CHANGELOG / tag / GitHub Release ページ)を進め、PyPI publish workflow へ引き継ぐ。 |
| name | release |
kaji の release を maintainer の手元で進める skill。
各 step で user 承認を挟みながら version bump → CHANGELOG → tag → GitHub Release ページ作成まで進める。
PyPI publish は GitHub Release 公開後に .github/workflows/publish-pypi.yml が
GitHub Actions + PyPI Trusted Publisher で実行する。
| タイミング | このスキル |
|---|---|
| kaji の release(version bump + tag + Release ページ)を切る | ✅ 必須 |
| dry-run(push / Release ページ作成手前まで確認したい) | ✅ --dry-run 経路 |
| PyPI publish | ✅ GitHub Release 公開後、publish-pypi.yml へ引き継ぐ |
.github/workflows/release-please.yml の再有効化 | ❌ 対象外(本 skill は maintainer 手元実行前提) |
/release # 通常実行(push と Release ページ作成まで進める)
/release --dry-run # ローカル状態のみ更新(push / gh release create はスキップ)
引数なしで起動し、skill 側で git / pyproject の状態を読んで判定する。
gh CLI を使う(GitHub 運用)git remote -v の URL から動的に抽出する。.kaji/config.toml の provider.github.git_remote 値と整合する remote 名であることが前提git push できる権限を maintainer が持っていることuv / make check が走る環境(kaji 開発環境セットアップ済み)pypi が作成済みで approval rule が設定されていることkaji の Trusted Publisher(初回は Pending Trusted Publisher)が設定済みであること
apokamokajipublish-pypi.ymlpypiNote: 現状 skill は
git remote -vの URL grep でのみ remote を解決し、.kaji/config.tomlのprovider.github.git_remoteは直接読まない。config 値を変えただけでは動作は変わらない点に注意。将来kaji config git-remote相当の CLI を追加する余地あり。
以下を順に確認する。1 つでも失敗した時点で停止し、user に復旧手順を提示する。
# 1-0. GitHub remote 名を解決
# `git remote -v` から URL に github.com を含む push remote を動的抽出する。
# `.kaji/config.toml` の `provider.github.git_remote` 値と整合する
# remote 名であることが前提(skill は config を直接読まない)。
GITHUB_REMOTE=$(git remote -v | awk '/github\.com.*\(push\)/{print $1; exit}')
# 上記で見つからない場合、`origin` が GitHub を指していれば fallback
if [ -z "$GITHUB_REMOTE" ]; then
if git remote get-url origin 2>/dev/null | grep -q github; then
GITHUB_REMOTE=origin
else
echo "ABORT: no git remote pointing to github.com found"
exit 1
fi
fi
echo "Resolved GitHub remote: $GITHUB_REMOTE"
# 1-1. main checkout 状態
git rev-parse --abbrev-ref HEAD # → "main" であること
# 1-2. working tree clean
git status --porcelain # → 空であること
# 1-3. 上流 sync
git fetch "$GITHUB_REMOTE"
git rev-list --left-right --count "$GITHUB_REMOTE/main"...HEAD
# → "0\t0"(ahead/behind ともに 0)であること
# 1-4. 解決した remote が GitHub を指していることを再確認
git remote get-url "$GITHUB_REMOTE" # → github.* を含むこと
# 1-5. gh CLI 認証済み
gh auth status # → "Logged in" 表示
失敗時のガイド例:
.kaji/config.toml の provider.github.git_remote および git remote -v 出力を user に提示し、追加方法を相談(git remote add origin <github-url>)git checkout main && git pull --ff-only "$GITHUB_REMOTE" maingit pull --ff-only "$GITHUB_REMOTE" mainupstream 等) を見るべきか user に確認# 直近 tag を取得
LAST_TAG=$(git describe --tags --abbrev=0)
# tag 以降の commit を取得(マージ commit 含む / メッセージ全文)
git log "${LAST_TAG}..HEAD" --pretty=format:'%H%n%B%n---END---'
取得した commit list を Conventional Commits で分類し、以下のルールで bump 種別を判定する。
| 検出 | bump |
|---|---|
commit message body に BREAKING CHANGE: 行 / footer / <type>!: 形式 | major |
feat: / feat(...) が 1 件以上 | minor |
fix: / fix(...) / その他 (docs: / chore: / refactor: / test:) のみ | patch |
| commit が 0 件(tag 以降変更なし) | ABORT — release する変更が無い |
判定根拠(どの commit が major / minor の決定打になったか)を必ず user に提示する。
user 承認待ち: 提案 version (例: v0.9.1 → v0.10.0) と判定根拠を出力し、user の承認を待つ。
user が異なる version を希望する場合はそちらを採用する(初期運用では Conventional Commits 解釈ミスを警戒し、必ず承認を挟む)。
release 必要性の追加確認: 候補 commit が docs: / test: / chore: のみで feat: / fix: / BREAKING CHANGE を一切含まない場合、patch bump 候補となるが consumer 側 lockfile を無用に更新させるため SemVer 的には冗長になりがち。Step 2 の user 承認時に「今回の bump 候補は docs/test/chore のみ。本当に release するか」と明示的に問いかけ、user 判断で release skip / continue を決める。
CHANGELOG.md の ## [Unreleased] セクションを基に、新 version のエントリを作成する。
## [X.Y.Z] - YYYY-MM-DD
### BREAKING CHANGE
- **壊れる契約**: 何を前提にしていた何が動かなくなるか
- **影響の判定方法**: 下流 repo が影響を受けるかを確認する手段(grep 等の 1 コマンドが理想)
- **適用指針**: 未カスタマイズなら再コピーで可の旨。カスタマイズ済み repo 向けには契約変更点の説明と上流 commit / PR への参照
### Added
- feat: ... entries
### Fixed
- fix: ... entries
### Changed / Docs / Internal
- その他 (docs / refactor / chore / test) entries
BREAKING エントリの 3 要素(ADR 008 決定 2・必須): ### BREAKING CHANGE に記載する
各項目は、壊れる契約 / 影響の判定方法 / 適用指針 の 3 要素を必ず含める。kaji は
後方互換レイヤを提供しない(ADR 008)ため、破壊的変更の伝達は release notes 側の責務で
あり、この 3 要素が下流 repo の唯一の移行ガイドになる。3 要素が揃わない BREAKING
エントリのまま release を進めてはならない(参照:
docs/adr/008-no-backward-compat-layer.md /
docs/dev/shared_skill_rules.md § 後方互換(共通))。
進め方:
## [Unreleased] 配下の既存記述を新 version セクションへ移動### BREAKING CHANGE に項目がある場合、各項目が 3 要素(壊れる契約 / 影響の判定方法 / 適用指針)を満たすか確認し、欠けていれば補うCHANGELOG.md の diff を user に提示 して承認待ちuser 承認待ち: user が文面修正を希望する場合は再 edit → 再提示。
# 4-1. pyproject.toml の version を編集(Edit tool 経由で 1 箇所のみ書き換え)
# version = "X.Y.Z"
# 4-2. lockfile 同期
uv lock
# 4-3. 品質チェック
source .venv/bin/activate && make check
make check が失敗した場合は Step 5 に進まず停止。原因を user に提示し、修正方針を相談する。
# 5-1. ステージング
git add pyproject.toml uv.lock CHANGELOG.md
# 5-2. release commit
git commit -m "chore(release): vX.Y.Z"
# 5-3. tag 付与(annotated tag を推奨)
git tag -a vX.Y.Z -m "Release vX.Y.Z"
--dry-run 経路の場合、ここまでで停止し、後述の dry-run 終了処理 を案内する。
Step 1 で解決した $GITHUB_REMOTE に対して、main と tag を atomic push する。
# main と tag を 1 トランザクションで push(どちらか失敗すれば両方拒否される)
git push --atomic "$GITHUB_REMOTE" main vX.Y.Z
--atomic を使うことで、main は push 成功 / tag push 失敗のような 片方だけ remote に反映された中途半端な状態 を防ぐ。
push 失敗時:
non-fast-forward → main が他者 push で進んでいる。--atomic のため tag も remote には残らない。force push は禁止。一旦 stop し、user に状況を共有 → 必要なら Step 1 から再実行(commit と tag を一度ローカルで rollback、後述)git tag -d vX.Y.Z で local tag を消し、原因確認後に再試行公開 notes には starter sync runbook の
managed starters 表から repository 別状態表を作り、全行を PENDING で初期化する。各行は
独立に PASS または N/A へ遷移し、単一の集約 status は置かない。
## Starter repositories
| repository | status | tracking Issue | starter Release / N/A 理由 |
|---|---|---|---|
| apokamo/kaji-starter-python | PENDING | - | - |
# CHANGELOG の該当 section を抜粋し、--notes に渡す
gh release create vX.Y.Z \
--title "vX.Y.Z" \
--notes "<CHANGELOG.md の [X.Y.Z] section 本文>"
完了後、gh release view vX.Y.Z で URL を取得し user に提示する。
GitHub Release の published event により .github/workflows/publish-pypi.yml が起動する。
workflow は GitHub environment pypi の approval 後、Trusted Publisher で uv publish を実行する。
通常運用では PyPI API token を local 端末、.pypirc、GitHub Secrets に保存しない。
--dry-run では本 step を実行しない。
gh run list --workflow publish-pypi.yml --limit 3
確認すること:
pypi environment approval 待ち、または approval 後に実行中であるBuild distributions / Check package metadata / Smoke test wheel entry point / Publish to PyPI が失敗していない失敗時は PyPI project / Pending Trusted Publisher / GitHub environment pypi の設定値が
workflow と一致しているか確認する。特に workflow filename は publish-pypi.yml であること。
user に以下を提示して終了:
uv tool install kaji && kaji --helpuv lock --upgrade-package kaji を案内する一文(kamo2 等の dependency consumer 向け)/update-starter <tracking_issue_id> 案内starter の追随・review・公開は kaji 本体 release とは独立したトランザクションとする。
starter が PENDING または失敗しても、公開済み kaji tag / GitHub Release / PyPI を rollback しない。
--dry-run)Step 1 → 5 まで実行し、Step 6 (push)、Step 7 (Release ページ)、Step 7.5 (PyPI publish workflow 確認) を スキップ。 dry-run では tag push / GitHub Release 作成を行わないため、PyPI publish workflow も起動しない。
dry-run 終了時に skill が必ず提示する内容:
作成された commit と tag: git show vX.Y.Z --stat の要点
rollback 手順(dry-run のみ。本番経路では使わない):
⚠️ 以下は
git reset --hardを含む破壊操作。skill が自動実行してはならない(ガードレール § も参照)。 必ず user の明示承認を取ってから実行する。コピペで一度に流す前提のブロックではない。
git tag -d vX.Y.Z
git reset --hard HEAD~1 # release commit を破棄(破壊操作: user 承認後のみ)
# CHANGELOG.md / pyproject.toml / uv.lock の変更を確認後、必要なら git restore で戻す
本番実行への進み方:
git push --atomic "$GITHUB_REMOTE" main vX.Y.Z を手で実行 → Step 7 を手で実行、/release(dry-run なし)で再実行各 step ごとに、失敗 → 復旧の流れを以下に集約する。
# tag を作る前に commit が失敗した場合
git restore --staged pyproject.toml uv.lock CHANGELOG.md
git restore pyproject.toml uv.lock CHANGELOG.md
# commit はできたが tag 付与で失敗した場合
git tag -d vX.Y.Z # 失敗していれば存在しない
git reset --hard HEAD~1
git push --atomic を使うため、reject 時は main と tag のどちらも remote には反映されていない。ローカル side だけ巻き戻せばよい。
# 状況確認
git fetch "$GITHUB_REMOTE"
git log --oneline "$GITHUB_REMOTE/main"..HEAD # 自分のローカル commits を確認
git log --oneline HEAD.."$GITHUB_REMOTE/main" # 他者の commits を確認
# 他者 commits を取り込む必要がある場合(force push 禁止):
# 1. tag を一旦削除
git tag -d vX.Y.Z
# 2. release commit を一旦巻き戻す
git reset --hard "$GITHUB_REMOTE/main"
# 3. main を最新化してから /release を再実行
git pull --ff-only "$GITHUB_REMOTE" main
絶対禁止:
git push --force "$GITHUB_REMOTE" main/git push --force "$GITHUB_REMOTE" vX.Y.Z。 tag を上書き push (--force) すると consumer 側の lockfile / cache 整合が壊れる。tag は不変前提で運用する。
tag と main commit は既に push 済み。rollback ではなく Release ページのみ再試行する:
gh release view vX.Y.Z 2>/dev/null || \
gh release create vX.Y.Z --title "vX.Y.Z" --notes "<本文>"
それでも作成できない場合、GitHub UI から手動で Release ページを作る選択肢を user に提示する。
main commit / tag / GitHub Release は作成済みなので、release commit を rollback しない。 以下を確認してから、失敗した workflow を GitHub UI で rerun する:
publish-pypi.ymlapokamo / kaji / pypipypi が存在し、approval rule が意図どおりpermissions.id-token: write があるuvx twine check --strict dist/* の失敗なら README / metadata を修正し、次の patch release で再 publish するPyPI API token による local uv publish は emergency fallback のみ。使用する場合も token を
.pypirc、shell history、Issue コメント、docs、repo 内ファイルに残さない。
kaji 本体 tag / GitHub Release / PyPI は公開済みのため rollback しない。GitHub Release の対象行を
PENDING のまま維持し、tracking Issue 作成または状態表リンク更新だけを再試行する。starter の
具体的な復旧は starter sync runbook に従う。
原則として撤回しない。撤回する場合は別 issue で意思決定を残し、以下を user の明示同意付きで行う:
# tag をリモートから削除
git push "$GITHUB_REMOTE" --delete vX.Y.Z
# Release ページを削除
gh release delete vX.Y.Z
# 必要なら revert commit を main に乗せる(force push はしない)
git revert <release-commit-sha>
git push "$GITHUB_REMOTE" main
git push --force / tag の force push を skill 側からは絶対に実行しないmake check を pass しないまま Step 5 以降に進まない---VERDICT---
status: PASS | ABORT
reason: |
release を完了した(または dry-run を完了した)
evidence: |
- 採番 version: vX.Y.Z
- commit sha: ...
- tag URL / Release ページ URL(本番経路のみ)
- dry-run の場合: 作成済み commit/tag と rollback 手順を提示済み
suggestion: |
consumer 側で `uv lock --upgrade-package kaji` を実行するよう案内(本番経路のみ)
---END_VERDICT---
ABORT を返すケース:
make check が失敗し、user が修正を保留した