Skip to main content
Lingkungan self-hosted berada dalam beta publik pada paket Team dan Enterprise; Ketersediaan dan batasan mencakup jalur pengaktifan. Halaman ini adalah resep uji CI; lihat quickstart untuk setup dan Deploy ke production untuk resep fleet.
Dalam lingkungan self-hosted, Claude Code cloud sessions berjalan pada gambar runner yang Anda bangun dan pertahankan. Sebelum meluncurkan gambar baru ke lingkungan produksi Anda, jalankan sesi lengkap terhadap lingkungan uji dari skrip: buat sesi, baca balasan Claude, kirim follow-up, dan baca balasan itu juga. Ini adalah bentuk uji smoke CI yang memverifikasi gambar runner Anda, akses git, dan alat kustom apa pun sebelum Anda mempromosikan perubahan. Resep ini mengasumsikan Anda telah menyiapkan lingkungan dan runner, dan bahwa pekerjaan CI Anda memulai proses runner pada host yang sama dengan skrip uji, setup alami untuk menguji gambar runner baru. Hook Stop yang Anda instal pada runner menulis balasan akhir setiap giliran ke file lokal, dan skrip membacanya dari sana, jadi satu-satunya panggilan ke API Anthropic adalah dua dispatch itu sendiri. Jika runner uji Anda berada pada infrastruktur terpisah, lihat Remote test runners.

Instal hook capture pada runner uji Anda

Pembacaan kembali bekerja melalui Claude Code Stop hook: ketika Claude menyelesaikan giliran, hook menerima pesan asisten akhir sebagai last_assistant_message dalam JSON stdin-nya dan menambahkannya ke $E2E_REPLY_DIR/<session_id>.txt. Instal dengan cara yang sama seperti commit-nudge Stop hook, pada ~/.claude/ host runner, yang runner semai ke dalam setiap sesi.

Simpan file hook

Simpan dua file di bawah pada host runner:
  • Blok settings: gabungkan ke ~/.claude/settings.json pada host runner
  • Skrip: simpan sebagai ~/.claude/hooks/e2e-stop-hook-capture.sh pada host runner dan buat dapat dieksekusi

Sebelum Anda memulai runner

Dua hal yang hook bergantung pada:
  • Instal sebelum Anda memulai runner. Runner mengambil snapshot ~/.claude/ sekali saat startup, jadi hook yang ditambahkan ke runner yang berjalan hanya berlaku setelah restart.
  • Ekspor E2E_REPLY_DIR ke proses runner. Hook adalah no-op ketika variabel tidak diatur atau direktori tidak ada, jadi atur di mana pun Anda memulai runner, seperti unit systemd, pod spec, atau langkah CI. Skrip uji di bawah juga memerlukan itu.
Instal hook ini hanya pada runner yang melayani lingkungan uji Anda. Ini menulis balasan akhir setiap sesi ke disk kapan pun E2E_REPLY_DIR ada, yang tidak berbahaya pada runner CI yang dapat dibuang tetapi bukan sesuatu yang dibawa ke gambar runner lingkungan produksi di mana variabel mungkin diatur secara tidak sengaja.

Jalankan loop uji

Flag dispatch --environment dan --ref memerlukan Claude Code v2.1.224 atau lebih baru pada mesin yang menjalankan skrip, lantai yang sama dengan runner itu sendiri. Dengan hook di tempat dan runner dimulai pada host ini, skrip uji:
  1. Membuat sesi pada lingkungan uji dengan claude -p "<prompt>" --environment <environment-id> --output-format json, dijalankan dari checkout git sehingga CLI dapat auto-detect repositori dari remote origin. --ref <branch> opsional mendasarkan checkout sesi pada ref bernama daripada HEAD lokal. Perintah membuat sesi, mencetak satu baris JSON yang berisi session_id, dan keluar tanpa menunggu balasan Claude.
  2. Menunggu balasan muncul di $E2E_REPLY_DIR/<session_id>.txt, ditulis oleh hook Stop pada runner setelah giliran selesai.
  3. Mengirim follow-up dengan claude -p "<message>" --cloud <session_id> --output-format json (lihat Kirim pesan follow-up ke sesi yang berjalan), yang memposting acara pengguna ke sesi yang ada dan keluar.
  4. Menunggu balasan follow-up dengan cara yang sama seperti langkah 2.

Perilaku dispatch --environment

Claude Code membuat sesi, mencetak ID sesi dan tautan ke sesi, dan keluar. Flag mengambil prioritas atas pengaturan remote.defaultEnvironmentId. Ini tidak mendukung --output-format stream-json, dan tidak dapat digabungkan dengan flag yang melanjutkan, melampirkan, atau prekonfigurasi sesi, seperti --resume, --continue, --teleport, --session-id, atau --init-only. --cloud ditolak dengan ID sesi atau URL, dan dalam run non-interaktif ketika membawa deskripsi. --cloud kosong diperlakukan sebagai tidak ada. Dari terminal, Anda dapat meneruskan tugas sebagai deskripsi --cloud daripada prompt posisional.

Skrip contoh

Skrip di bawah menjalankan loop lengkap terhadap $CLAUDE_TEST_ENVIRONMENT_ID, ID ccpool_... lingkungan uji Anda, ditampilkan dalam dialog detail lingkungan pada halaman admin atau dikembalikan oleh panggilan create-environment, dan menegaskan pada frasa sentinel di setiap balasan. Jalankan dari checkout git repositori yang ingin dikerjakan sesi, setelah memulai runner pada host ini dengan hook capture terinstal dan E2E_REPLY_DIR diekspor.
Ganti prompt TURN1/TURN2 dan sentinel EXPECT1/EXPECT2 dengan apa pun yang menjalankan setup Anda, seperti meminta Claude menjalankan salah satu alat MCP kustom Anda dan menegaskan pada outputnya.

Remote test runners

Jika runner uji Anda berada pada infrastruktur terpisah, seperti fleet Kubernetes persisten yang pekerjaan CI Anda tidak dapat berbagi filesystem dengannya, tukar penulisan file dalam hook Stop untuk POST ke endpoint yang driver Anda dengarkan:
Di sisi driver, jalankan apa pun yang menerima POST dan menahan balasan sampai uji memintanya, seperti pendengar HTTP kecil di dalam pekerjaan CI atau penerima webhook yang sudah Anda jalankan. Hook berjalan pada infrastruktur Anda, jadi endpoint hanya perlu dapat dijangkau dari runner Anda.

Autentikasi dari CI

Baik claude -p ... --environment maupun claude -p ... --cloud autentikasi dengan token OAuth claude.ai; kunci API, seperti sk-ant-xxxxx, tidak diterima untuk panggilan apa pun. Dua pendekatan membuat token tersedia di CI.

Host CI jangka panjang

Jalankan claude auth login sekali secara interaktif pada mesin yang menjalankan skrip, menggunakan akun pengguna khusus untuk otomasi. Claude Code menyimpan token di OS keychain pada macOS, atau di ~/.claude/.credentials.json pada Linux dan Windows. Pada host macOS yang Keychain-nya tidak dapat ditulis, seperti yang khas dalam sesi SSH di mana Keychain login tetap terkunci, Claude Code menyimpan token di ~/.claude/.credentials.json di sana juga. Lihat Credential management. CLI menyegarkan token akses jangka pendek secara otomatis pada setiap invokasi, tetapi hibah refresh-token yang mendasar dibatasi pada 30 hari dari login awal, jadi jalankan kembali claude auth login secara interaktif pada host itu setiap 30 hari.

Runner CI Ephemeral

Tidak ada token CI jangka panjang untuk ini hari ini. Scope yang memberikan kontrol sesi jarak jauh, user:sessions:claude_code, dibatasi server-side pada 30 hari, jadi claude setup-token, yang mencetak token inference-only satu tahun, tidak mencakupnya. Environment secret juga tidak diterima, karena hanya mengotorisasi runner untuk mendaftar dengan lingkungan, bukan untuk membuat sesi. Untuk menyediakan login yang disimpan ke runner ephemeral, atur CLAUDE_CODE_OAUTH_REFRESH_TOKEN dan CLAUDE_CODE_OAUTH_SCOPES sehingga claude auth login menukar token tanpa browser; batas 30 hari yang sama berlaku untuk hibah refresh. Hubungi tim akun Anthropic Anda jika Anda memerlukan jalur identitas mesin yang tidak terikat pada akun manusia.

Buat lingkungan uji khusus

Buat dan hapus lingkungan secara terprogram sehingga setiap run CI mendapatkan yang bersih; runner yang pekerjaan CI Anda mulai mendaftar ke lingkungan segar. Panggilan create dan delete di bawah adalah endpoint yang sama yang digunakan halaman admin Cloud environments pada claude.ai, dan mereka memerlukan header anthropic-beta: ccr-byoc-2025-07-29.

Cetak token admin

$ADMIN_TOKEN adalah token akses OAuth claude.ai untuk akun yang memegang peran Owner, dicetak dengan cara yang sama seperti Authenticate from CI:
  • Cetak itu: jalankan claude auth login dengan akun yang memegang peran Owner, kemudian baca token akses saat ini dari mana pun Long-lived CI host mengatakan Claude Code menyimpannya.
  • Baca segar setiap run: CLI memutar token akses, dan batas hibah refresh 30 hari yang sama berlaku, jadi jangan simpan salinan.
  • Teruskan melalui stdin: seperti contoh, jadi token tidak pernah mendarat di daftar argumen curl atau log build Anda.

Buat lingkungan

Tangkap respons tanpa mencetaknya: pool_secret adalah kredensial jangka panjang yang dapat mendaftarkan runner ke lingkungan, jadi simpan sebagai rahasia CI yang disembunyikan dan cetak hanya ID lingkungan. Bentuk -H @- yang membuat token keluar dari daftar proses memerlukan curl 7.55 atau lebih baru; curl yang lebih lama memperlakukan @- sebagai header literal dan mengirim permintaan tanpa otorisasi.
Sampai Owner mengaktifkan Allow self-hosted environments untuk organisasi, panggilan gagal dengan 403 permission_error membaca self-hosted runners are disabled by your organization's policy. Mulai runner pada host ini dengan SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET=$ENVIRONMENT_SECRET, ditambah hook capture dan E2E_REPLY_DIR per Install the capture hook, kemudian jalankan skrip uji.

Hapus lingkungan

Hapus lingkungan ketika run selesai, sehingga setiap run CI dimulai bersih: