二〇二六年の OpenClaw はローカルゲートウェイDashboardSlack/Discord 等の多チャネル通知へ寄せる流れが定着しつつ、CI との接続点は引き続き署名付き Webhook と最小権限が中心です。本稿では、そのゲートウェイ上に Bundler プリフライトを直列化し、Gemfile.lock の差分要約汎用 HTTP エンドポイントへ返す手順だけを切り出します。関連として CircleCIJenkinsGitHub Checks の各記事や、インストール排障LaunchAgent ヘルスを併読してください。

つまずきの型

共有クローンにそのまま bundle install するとロックが汚れ、Webhook 戻し先のトークンがプロキシで欠落すると 401 が再現しにくいまま本番だけ失敗します。イベントごとに空に近い沙箱へ浅い git clone から入るのが再現性の鍵です。

判断表:直列・沙箱・戻し

観点推奨避ける
直列check → outdated →(任意)lock --checkinstall だけで成功扱い
沙箱ビルド ID ごとの TMP 配下恒久ワークスペース共有
差分lock の git diff 冒頭を文字列化巨大 diff をそのまま POST
戻しJSON+Bearer+指数バックオフ成功ログのみで失敗を隠す

ミラー・並列・キャッシュ鍵の網羅は Bundler×Git 決定表 を参照してください。

ステップ 1:インストール・daemon・トークンとヘルス

Node 22.16 以上または 24 系を対話シェルと LaunchAgent の PATH で一致させ、公式ドキュメントに沿って CLI を入れて openclaw doctor を通します。Dashboard 用トークンはキーチェーン等に閉じ、外向き公開はリバースプロキシ+トンネルに限定します。daemon は LaunchAgent 健康診断 のパターンで curl -fsS http://127.0.0.1:<port>/health を定期取得し、落ちたら launchctl kickstart で再起動します。

ステップ 2:作業ディレクトリ沙箱

ハンドラ内でビルド ID またはコミット SHA ごとに専用ディレクトリを切り、毎回クリーンに近い状態から開始します。

export RUN_ROOT="${TMPDIR:-/tmp}/oc-bundle-${BUILD_ID:-$(date +%s)}" mkdir -p "$RUN_ROOT" && cd "$RUN_ROOT" git clone --depth 1 "$REPO_URL" repo && cd repo

umask と所有者を CI ユーザーに揃え、失敗時はこのツリーごと削除できるようにします。

ステップ 3:スキル雛形で bundle check/outdated を走らせる

まずロック整合を bundle check で確認し、続けて更新候補一覧を bundle outdated --parseable で取得します。厳格モードでは bundle lock --check を追加し、差分本文は git diff -- Gemfile.lock | head -c 4000 のように上限付きで文字列化して JSON に載せます。終了コードと標準エラー末尾はそのまま要約フィールドへ写します。

bundle check bundle outdated --parseable || true bundle lock --check 2>/dev/null || true git diff -- Gemfile.lock | head -c 4000 > /tmp/lock_snip.txt

ステップ 4:失敗リトライとログ退避

ネットワーク揺らぎは 失敗リカバリ の考え方に合わせ、指数バックオフで最大三回まで再試行します。各試行の標準出力末尾を ~/Logs/oc-bundle/$(date +%Y%m%d-%H%M%S).log へ追記し、ディスク圧迫時は find … -mtime +7 -delete でローテーションします。

for i in 1 2 3; do bundle check && break sleep $((2**i)) done

ステップ 5:汎用 HTTP Webhook へ JSON で要約回帰

status(success/failed)・elapsed_msbundler_exitlock_diff_excerptoutdated_lines を 1 つの JSON にまとめ、社内ゲートウェイやサーバーレス受口へ POST します。CircleCI/Jenkins 固有の署名がある場合は各記事の HMAC 節を流用し、本稿のペイロードは自前の Bearerで足りる想定です。

jq -n \ --arg st "failed" \ --argjson exit 1 \ --rawfile diff /tmp/lock_snip.txt \ '{status:$st,bundler_exit:$exit,lock_diff_excerpt:$diff}' > summary.json curl -sS -X POST "$CALLBACK_URL" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $CALLBACK_TOKEN" \ -d @summary.json

FAQ:切り分け短答

bundle check が常に失敗する

ロックと Gemfile の不整合、または企業プロキシ経由で gem メタデータが欠けるケースがあります。BUNDLE_MIRROR__HTTPS://RUBYGEMS__ORG/ 等を決定表どおり固定し、沙箱を毎回新規にします。

jq が無い

ハンドラ言語側で辞書を組み立てても構いません。重要なのは UTF-8 とペイロード上限、およびタイムアウト付き HTTP クライアントです。

Webhook は 204 だが CI が拾えない

受口側が本文を読まずステータスだけ見ている場合、本文キーを合わせるか、受口のサンプル JSON をこの雛形に合わせてください。

まとめ:ゲートウェイでヘルスとトークンを閉じ、沙箱で Bundler を直列実行し、差分要約+終了コードを JSON で戻すと、CI 側は汎用 HTTP だけで拾えます。常駐ホストが必要なら MacPull購入ページ や地域別の 日本向け購入、運用疑問は ヘルプセンター(いずれもログイン不要)をご利用ください。

Bundler プリフライト常駐向け

リモート Mac で OpenClaw ゲートウェイと Ruby CI を安定ホストする

ヘルプセンター購入ページホームはログイン不要です。料金は 料金ページ からご確認ください。

複数リージョン
SSH
柔軟な契約
サポート