ナイトリリース
Tideclaw/OpenClaw アルファ/ナイトリリースの自動化、手動アルファトリガー、ベータ準備、リリースブランチ修復、リリース後のフォワードポートに使用します。Tideclaw ホストパス、cron ID、Discord ルーティング ID を使用する前に、$release-private が存在する場合は読み込んでください。
ポリシー
- アルファ/ナイトは12時間ごと、または手動トリガーで実行されます。
- ベータは、実績のあるアルファ/リリースブランチから、人間がDiscordでトリガーします。
- 安定版/最新版は常に明示的な人間の確認が必要です。
- ダーティチェックアウトや
mainから直接公開しないでください。 - Main はビジーまたは壊れている可能性があります。アルファ作業は隔離する必要があり、main の一時的な障害が利用可能なナイトをブロックしないようにします。
- リリースブランチの証明が成功してからのみ公開してください。
- アルファが成功したら、リリースブランチのコミットを
mainにフォワードポートし、main のCIが成功することを確認します。 - フォワードポートPRには、ナイト/リリースチェックを通過させるために必要な再利用可能な修正のみを含めます。アルファバージョンのバンプ、リリースノート、変更履歴のリリースエントリ、タグ、生成されたアーティファクト、状態ファイルの更新を含めてはいけません。
- 過去3日間のアルファ/ナイトブランチと、実行中のアクティブなRun、オープンPR、リリースタグのあるブランチのみを保持します。
- 広範なenv/トークンダンプを実行しないでください。Tideclaw ホストでのGitHub書き込みには、以下の Tideclaw
gh書き込みラッパーを使用してください。
アイデンティティ
Tideclaw は、リリースブランチとフォワードポートブランチで、自身のマシンアイデンティティでコミットする必要があります。
git config user.name "Tideclaw"
git config user.email "[email protected]"
コミットが明らかに機械作成であり、CIによってゲートされている場合、これは監査性に優れています。保護された main への直接プッシュは避け、PR/自動マージを介してフォワードポートします。ただし、リポジトリポリシーが、グリーンチェック後にボットがプッシュすることを明示的に許可している場合を除きます。人間がパッチまたは明示的なコミットテキストを提供した場合にのみ、人間の Co-authored-by を含めます。
ブランチ形状
- ブランチプレフィックス:
tideclaw/alpha/ - ブランチ名:
tideclaw/alpha/YYYY-MM-DD-HHMMZ - ベース: トリガー時の現在の
origin/mainSHA。 - 状態ファイル: Tideclaw ホスト上の
$release-privateから解決します。 - リリースタグ:
vYYYY.M.PATCH-alpha.N - npm dist-tag:
alpha
PATCH は連続した月次リリーストレイン番号であり、カレンダーの日付ではありません。安定版とベータリリースからアルファトレインを決定します。次のトレインを選択するときは、アルファのみのパッチ番号を無視します。その月の最も高い安定版/ベータパッチより1大きい値を使用し、そのトレインでナイトを繰り返す場合は alpha.N のみをインクリメントします。次のパッチにベータが存在する場合は、アルファを次のトレインに移動します。パッチ番号が膨らんだ従来のアルファのみのタグは、ベータ/安定版の番号を進めません。
新しいRunのために古いアルファブランチを再利用しないでください。同じベースSHAを再実行する場合は、新しいタイムスタンプ付きブランチを作成し、その理由を記録してください。
開始
$release-privateから Tideclaw ホストチェックアウトで作業します。- 最初にフェッチします。
git fetch origin main --tags --prune
git switch main
git merge --ff-only origin/main
BASE_SHA="$(git rev-parse origin/main)"
BRANCH="tideclaw/alpha/$(date -u +%Y-%m-%d-%H%MZ)"
git switch -c "$BRANCH" "$BASE_SHA"
- 何かを変更する前に、リポジトリのリリースドキュメント/スクリプトを読んでください。
AGENTS.mddocs/の下のリリースドキュメントscripts/の下のリリーススクリプト.github/workflows/*release*
$BASE_SHAを最後に成功したアルファ状態および現在の git/npm/GitHub アルファタグと比較します。すでにリリースされている場合は、スキップを報告し、公開しないでください。
手動トリガー:
CRON_ID="<from release-private>"
OPENCLAW_ALLOW_ROOT=1 openclaw cron run "$CRON_ID" --expect-final --timeout 21600000
Discord アルファトリガー
Tideclaw は、メンテナーが #releases または #maintainers で Tideclaw に言及した場合、Discord からすぐにアルファを実行できます。
受け入れられる形状:
@Tideclaw run alpha now
@Tideclaw alpha release from main now
@Tideclaw trigger alpha
ルール:
- これをアルファcronジョブと同等の手動アルファトリガーとして扱います。
- 現在の
origin/mainから開始し、新しいtideclaw/alpha/YYYY-MM-DD-HHMMZブランチを作成します。 - 通常のアルファワークフローに従います:以前の修正を再利用し、ローカルチェックを実行し、アルファブランチで修正し、リリースCIを実行し、グリーンゲート後にアルファを公開し、修正のみのPRを介して再利用可能な修正をフォワードポートします。
- 別のアルファ/ベータ/安定版リリースRunがすでにアクティブな場合は、アクティブなブランチ/Runを報告して停止します。
#maintainersトリガーには明示的なTideclawの言及が必要です。そこでのリリースに関する言及のないチャットには反応しないでください。- Discordのロール/ユーザーIDとライブホットフィックスノートは
$release-privateから解決します。
Discord ベータトリガー
Tideclaw は、メンテナーが明示的なベータトリガーを送信した場合にのみ、#releases または言及された #maintainers コマンドからベータリリースを実行できます。これは、ベータに対する人間の承認として扱い、安定版/最新版に対しては扱いません。
受け入れられる形状:
@Tideclaw beta release from vYYYY.M.PATCH-alpha.N
@Tideclaw beta release from tideclaw/alpha/YYYY-MM-DD-HHMMZ
@Tideclaw beta release from latest proven alpha
ルール:
beta releaseという単語と、ソースアルファタグ/ブランチ、またはlatest proven alphaが必要です。- ソースが不明な場合は、
#releasesで1つ明確な質問をして停止します。 - 最初にソースアルファを確認します:GitHubリリース、npm
alphaパッケージ、リリースCI、記録された状態ファイル、ブランチ/タグSHA。 - 実績のあるアルファソースから新しいベータブランチ
tideclaw/beta/YYYY-MM-DD-HHMMZを作成します。移動するmainから直接作成しないでください。 - すでにアルファで実績のある安定化修正のみを再利用/スカッシュします。ベータリリースドキュメントで特に要求されていない限り、無関係なアルファリリースメカニズムをインポートしないでください。
- ベータを
vYYYY.M.PATCH-beta.Nとして計算し、npm--tag betaに一致させます。ベータトレインを選択するときは、アルファのみのパッチ番号を無視します。 - ベータリリース検証/事前チェック/フルリリースCIを実行し、ベータブランチで失敗を修正します。
- ベータゲートが成功した場合のみベータを公開します。GitHub Actions/OIDC を使用し、ホストから直接 npm 公開しないでください。
- 最終的なDiscordサマリーには、ソースアルファ、ベータタグ/バージョン、ブランチ、修正コミット、ワークフローRun ID、npm/GitHub の証明、およびスキップ/ブロックされた理由を含める必要があります。
- ベータ公開後、以下の修正のみのPRルールと同じルールを使用して、再利用可能な修正を
mainにフォワードポートします。
以前の修正の再利用
チェックを実行する前に、最近の Tideclaw アルファブランチから、以前のリリース試行中に行われた修正をマイニングします。
$release-privateから、最後に成功したアルファブランチと修正コミットSHAの Tideclaw 状態ファイルを読み取ります。- 最近のリモートブランチを一覧表示します。
git for-each-ref refs/remotes/origin/tideclaw/alpha --format='%(refname:short) %(committerdate:iso-strict)'
- 過去3日間の Tideclaw アルファブランチと、最後に成功したアルファブランチのみを考慮します。
- 各候補ブランチについて、現在の
origin/mainにないコミットを検査します。
git log --no-merges --reverse --format='%H%x09%s' origin/main..origin/tideclaw/alpha/YYYY-MM-DD-HHMMZ
- 新しいアルファブランチにまだ適用可能な、実際の安定化修正のみをチェリーピックします。状態ファイルに
fixCommitShasとして記録されているコミットを優先します。 - バージョンバンプ、変更履歴のリリースエントリ、タグアーティファクト、生成されたリリースノート、状態ファイルのみのコミット、および一回限りのデバッグインストルメンテーションをスキップします。
- チェリーピックが競合した場合は、現在の main に同等の修正がすでに含まれているかどうかを検査します。含まれていない場合は、最小限に解決し、コミットメッセージを明確に保ちます。
- 再利用されたコミットSHAは、新しい作成の修正SHAとは別に、アルファ状態と最終的なDiscordサマリーに記録します。
git cherry、git range-diff、および対象を絞ったテストの再実行を使用して、main にすでに存在する修正の重複を避けます。
修復ループ
ブランチをリリース候補の修復面として使用します。
- 最初に狭いローカルチェックを実行します:変更されたテスト、リリース事前チェック、リリースドキュメントで必要な型/リント/ビルドゲート。
- ローカルチェックが失敗した場合は、最小限のコミットでアルファブランチで修正します。
- 各一貫した修正を Tideclaw としてコミットします。
- 各修正の後、失敗したローカルチェックを再実行します。
- ベースライン、期待失敗リスト、無視ファイル、またはリリースインベントリを編集して失敗を隠さないでください。ただし、リリースドキュメントが明示的にそれを要求し、差分が正当である場合を除きます。
- 失敗がflakyの場合は、一度再実行します。それでも失敗する場合は、実際の失敗として扱います。
- 修正が明らかにmainに役立つ場合は、小さく保ち、フォワードポート可能にします。アルファ安定化中に広範なリファクタリングは避けてください。
コミット例:
git add <files>
git commit -m "fix: stabilize alpha release preflight"
git push -u origin "$BRANCH"
リリースCI
ローカル証明後:
- 既存の git タグ、npm バージョン、GitHub リリースから次の
vYYYY.M.PATCH-alpha.Nを計算します。日付や最も高いアルファのみのパッチではなく、安定版/ベータトレインからPATCHを選択します。同じアルファトレインを再利用し、alpha.Nをインクリメントします。そのパッチにベータが存在するまで続けます。ベータが存在した後は、新しいアルファビルドには次のパッチを使用します。 - アルファブランチのパッケージバージョンとリリースメタデータをそのタグに一致させ、コミットし、ブランチをプッシュします。
- GitHub CLI を使用して、ブラウザ/フェッチツールではなく、アルファブランチからリリース検証を実行します。Tideclaw ホストでは、生の
ghは読み取り専用のCodexサンドボックスラッパーです。workflow run、run cancel、公開ディスパッチなどの書き込み可能なコマンドには/usr/local/bin/gh-tideclaw-writeを使用します。
GH="/usr/local/bin/gh-tideclaw-write"
SHA="$(git rev-parse HEAD)"
TAG="v$(node -p "require('./package.json').version")"
BRANCH="$(git branch --show-current)"
"$GH" workflow run full-release-validation.yml --repo openclaw/openclaw --ref "$BRANCH" \
-f ref="$BRANCH" \
-f release_profile=beta \
-f rerun_group=all
"$GH" workflow run openclaw-npm-release.yml --repo openclaw/openclaw --ref "$BRANCH" \
-f tag="$SHA" \
-f preflight_only=true \
-f npm_dist_tag=alpha
gh run list、gh run view、gh apiで正確なワークフローRun ID とヘッドSHAを監視します。読み取り専用のghはポーリングには問題ありません。コマンドがGitHubを変更する場合のみ$GHを使用します。GitHub API ポーリングに Codex ブラウザ/フェッチを使用しないでください。以前の Tideclaw Run は、事前チェックが成功した後そこで失敗しました。- アルファの場合、ブロッキングゲートは、Tideclaw が直接修復できるか、パッケージの安全性を証明するものです:通常CI、プラグインリリース前、npm事前チェック、パッケージ準備、インストールスモーク、タグ/到達可能性、公開検証。クロスOS、ライブチャンネル、QAラボ、パッケージ承認、長時間Docker E2E、TelegramパッケージE2Eの失敗はアドバイザリとして扱います。Discordで報告し、ブロッキングゲートが成功していれば続行します。
rerun_group=allがアドバイザリレーンのみでスタックしていて、CI、プラグインリリース前、npm事前チェック、パッケージ準備、インストールスモークが成功している場合は、同じヘッドで-f rerun_group=install-smokeを使用して、対象を絞った Full Release Validation をディスパッチします。その成功した対象を絞った Full Release Validation Run を公開証明として使用し、別のCI/プラグイン/フルアドバイザリRun ID をDiscordサマリーに含めます。
- ブロッキングゲートが失敗した場合は、アルファブランチで修正し、プッシュし、失敗したか必要なリリースCIのみを再実行します。コミットが変更された場合は、古い事前チェック/フル検証Run IDを破棄し、新しいヘッドに対してそれらを再実行します。
- 同じブランチヘッドでフル検証とnpm事前チェックが成功した後、その正確なコミットからリリースタグを作成してプッシュします。
git tag -a "$TAG" "$SHA" -m "openclaw ${TAG#v}"
git push origin "$TAG"
- 同じアルファブランチから公開ラッパーをディスパッチします。成功したnpm事前チェックRun IDと、同じヘッドSHAからのフルリリース検証Run IDと正確な試行を使用します。
FULL_RELEASE_VALIDATION_RUN_ATTEMPT="$(gh api \
"repos/openclaw/openclaw/actions/runs/${FULL_RELEASE_VALIDATION_RUN_ID}" \
--jq .run_attempt)"
"$GH" workflow run openclaw-release-publish.yml --repo openclaw/openclaw --ref "$BRANCH" \
-f tag="$TAG" \
-f preflight_run_id="$NPM_PREFLIGHT_RUN_ID" \
-f full_release_validation_run_id="$FULL_RELEASE_VALIDATION_RUN_ID" \
-f full_release_validation_run_attempt="$FULL_RELEASE_VALIDATION_RUN_ATTEMPT" \
-f npm_dist_tag=alpha \
-f plugin_publish_scope=all-publishable \
-f publish_openclaw_npm=true \
-f release_profile=beta \
-f wait_for_clawhub=false
- 公開ラッパーと子Runを監視します。
openclaw-npm-release.ymlがnpm-release環境を待機しており、Tideclaw が承認できない場合は、それを唯一のブロッカーとして報告します。リリースが完了したとは呼ばないでください。 - ホストから直接 npm を公開しないでください。GitHub Actions/OIDC を使用してください。
重要: preflight_only=true の openclaw-npm-release.yml はアーティファクトのみを準備します。公開はしません。成功したアルファには、後続の openclaw-release-publish.yml ラッパー、プッシュされた git タグ、npm alpha dist-tag の証明、および GitHub プレリリースが必要です。
公開されたアルファの確認
以下がすべて真になるまでリリースは完了しません。
- GitHub タグが存在する。
- GitHub リリースが存在し、プレリリースとしてマークされている。
- リリース本文が npm バージョンページ、レジストリ tarball、整合性、CI/証明にリンクしている。
npm view openclaw@<version>が正確なバージョン、dist-tagalpha、tarball、整合性、公開時間を示している。- インストール済み/パッケージスモークがリポジトリリリースドキュメントに従っている。
$release-privateの Tideclaw 状態ファイルが、バージョン、タグ、ベースSHA、ブランチ、修正コミットSHA、ワークフローRun ID、npm整合性、タイムスタンプを記録している。
#releases での最終Discordサマリー:
- タグ/バージョン
- ベースSHA
- ブランチ
- 修正コミット
- ワークフローRun ID
- npm/GitHub の証明
- リリースされていない場合はスキップ/ブロックされた理由
角括弧ターゲットを使用した Discord セーフな Markdown リンクを使用します。シークレットを決して印刷しないでください。
フォワードポート
成功したアルファの後、main に修正のみのPRを作成します。
- 現在の
origin/mainからフォワードポートブランチを作成/更新します。
git fetch origin main --prune
git switch -c "tideclaw/forward-port/$(date -u +%Y-%m-%d-%H%MZ)" origin/main
- ナイト/リリースチェックを通過させるために必要な実際の修正であるリリースブランチコミットのみをチェリーピックします。
- アルファバージョンのバンプ、変更履歴のリリースエントリ、リリースノート、タグアーティファクト、生成されたリリースアセット、状態ファイルのみのコミット、および公開が唯一の目的であるコミットを除外します。
- コミットが実際の修正とリリース/バージョン変更を混合している場合は、分割します。修正ハンクのみを新しいコミットに再生し、残りを破棄します。
- チェリーピックが空の場合は、修正がすでに
mainに存在することを意味するため、そのコミットをスキップします。 - チェリーピックの競合は、main にすでに同等の変更があるかどうかを検査して解決するか、アルファから修正意図を維持しながら最小限に解決します。
- フォワードポートブランチをプッシュし、
gh書き込みラッパーを使用してPRを作成します。
"$GH" pr create \
--base main \
--head "$BRANCH" \
--title "fix: forward-port alpha stabilization fixes $(date -u +%Y-%m-%d)" \
--body "Automated forward-port of reusable fixes from $(BRANCH).\n\n## Changes\n\n$(git log origin/main..HEAD --no-merges --reverse --oneline)\n\n**Not included**: version bumps, changelog entries, release notes, tags, artifacts, state-file updates." \
--label automated \
--label forward-port
- PRがCIに合格するのを待ちます。失敗した場合は、フォワードポートブランチで修正します。これには、main の最新の変更に合わせるための追加の調整コミットが必要になる場合があります。
- 自動マージが設定されている場合は、それを有効にします。設定されていない場合は、メンテナーに
#releasesでPRを確認してマージするように依頼します。ボットとして直接マージしないでください。 - フォワードポートの状態をアルファリリースサマリーと一緒にDiscordに報告し、PRリンクとCIステータスを含めます。