Ringkasan:
Menyiapkan Jenkins di OS X telah menjadi jauh lebih mudah dengan penginstal terbaru ( mulai 1.449 - 9 Maret 2012 ), namun mengelola proses penandatanganan kode masih sangat sulit tanpa jawaban langsung.
Motivasi:
Jalankan server CI tanpa kepala yang mengikuti praktik terbaik umum untuk menjalankan layanan di OS X ( Beberapa di antaranya dijelaskan di sini dalam bahasa sederhana ).
Latar Belakang:
- 12 Oktober 2009 - Cara mengotomatiskan pembuatan aplikasi iPhone Anda dengan Hudson
- 15 Juni 2011 - Jenkins di Mac OS X; git w / ssh kunci publik
- 23 Juni 2011 - Penerapan Berkelanjutan dari Aplikasi iOS dengan Jenkins dan TestFlight
- 26 Juli 2011 - Sertifikat dan kunci yang hilang di rantai kunci saat menggunakan Jenkins / Hudson sebagai Integrasi Berkelanjutan untuk pengembangan iOS dan Mac
- 30 Agustus 2011 - File Penyediaan Xcode tidak ditemukan di Jenkins
- 20 September 2011 - Cara mengatur Jenkins CI di Mac
- 14 September 2011 - Menjalankan Jenkins di Mac
- 12 November 2011 - Howto: Instal Jenkins di OS X dan buat Mac dibuat
- 23 Januari 2012 - Penginstal Jenkins OSX akan berubah
- 7 Maret 2012 - Terima kasih telah menggunakan OSX Installer
Proses:
Instal Jenkins CI melalui OS X paket installer . Untuk langkah "Jenis Instalasi", klik tombol Ubahsuai, dan pilih "Mulai saat boot sebagai 'jenkins.'"
Diskusi:
Harapan naif pada saat ini adalah bahwa proyek gaya bebas dengan skrip build xcodebuild -target MyTarget -sdk iphoneos
seharusnya berfungsi. Seperti yang ditunjukkan oleh judul posting ini, itu tidak dan gagal dengan:
Code Sign error: The identity 'iPhone Developer' doesn't match any valid certificate/private key pair in the default keychain
Sudah cukup jelas apa yang perlu terjadi - Anda perlu menambahkan sertifikat penandatanganan kode yang valid dan kunci pribadi ke dalam rantai kunci default. Dalam meneliti bagaimana mencapai ini, saya belum menemukan solusi yang tidak membuka sistem ke beberapa tingkat kerentanan.
Masalah 1: Tidak ada rantai kunci default untuk jenkins daemon
sudo -u jenkins security default-keychain
... menghasilkan "Gantungan kunci default tidak dapat ditemukan"
Seperti yang ditunjukkan di bawah ini oleh Ivo Dancet , UserShell diatur ke / usr / bin / false secara default untuk jenkins daemon (menurut saya ini adalah fitur, bukan bug); ikuti jawabannya untuk mengubah UserShell menjadi bash. Anda kemudian dapat menggunakan sudo su jenkins
untuk masuk sebagai pengguna jenkins dan mendapatkan prompt bash.
sudo su jenkins
cd ~/Library
mkdir Keychains
cd Keychains
security create-keychain <keychain-name>.keychain
security default-keychain -s <keychain-name>.keychain
Oke bagus. Kami punya gantungan kunci default sekarang; ayo lanjutkan kan? Tapi, pertama-tama kenapa kita malah repot-repot membuat gantungan kunci bawaan?
Hampir semua jawaban, saran, atau percakapan yang saya baca selama penelitian menyarankan bahwa seseorang sebaiknya membuang sertifikat dan kunci penandatanganan kode mereka ke dalam rantai kunci sistem. Jika Anda menjalankan security list-keychains
proyek gaya bebas di Jenkins, Anda akan melihat bahwa satu-satunya rantai kunci yang tersedia adalah rantai kunci sistem; Saya pikir di situlah kebanyakan orang muncul dengan ide untuk meletakkan sertifikat dan kunci mereka di sana. Tapi, ini sepertinya ide yang sangat buruk - terutama mengingat Anda harus membuat skrip teks biasa dengan kata sandi untuk membuka rantai kunci .
Masalah 2: Menambahkan sertifikat penandatanganan kode dan kunci pribadi
Di sinilah saya benar-benar mulai mual. Saya memiliki firasat bahwa saya harus membuat kunci publik / pribadi baru yang unik untuk digunakan dengan Jenkins. Proses pemikiran saya adalah jika jenkins daemon dikompromikan, maka saya dapat dengan mudah mencabut sertifikat di Portal Penyediaan Apple dan membuat kunci publik / pribadi lainnya. Jika saya menggunakan kunci dan sertifikat yang sama untuk akun pengguna saya dan Jenkins, berarti lebih merepotkan (rusak?) Jika layanan jenkins diserang.
Menunjuk ke jawaban Simon Urbanek Anda akan membuka kunci rantai kunci dari skrip dengan kata sandi teks biasa. Tampaknya tidak bertanggung jawab untuk menyimpan apa pun kecuali sertifikat dan kunci "sekali pakai" di gantungan kunci daemon jenkins.
Saya sangat tertarik dengan diskusi yang bertentangan. Apakah saya terlalu berhati-hati?
Untuk membuat CSR baru sebagai jenkins daemon di Terminal saya melakukan hal berikut ...
sudo su jenkins
certtool r CertificateSigningRequest.certSigningRequest
Anda akan diminta untuk hal berikut (sebagian besar dari ini saya membuat tebakan dengan jawaban yang benar; apakah Anda memiliki wawasan yang lebih baik? Silakan bagikan.) ...- Masukkan kunci dan label sertifikat:
- Pilih algoritma:
r
(untuk RSA) - Masukkan ukuran kunci dalam bit:
2048
- Pilih algoritma tanda tangan:
5
(untuk MD5) - Masukkan string tantangan:
- Lalu banyak pertanyaan untuk RDN
- Kirimkan file CSR yang dibuat (CertificateSigningRequest.certSigningRequest) ke Portal Penyediaan Apple dengan ID Apple baru
- Setujui permintaan dan unduh file .cer
security unlock-keychain
security add-certificate ios_development.cer
Ini membawa kita selangkah lebih dekat ...
Masalah 3: Menyediakan profil dan membuka kunci rantai kunci
Saya membuat profil penyediaan khusus di Provisioning Portal hanya untuk digunakan dengan CI dengan harapan jika terjadi sesuatu yang buruk, saya telah membuat dampaknya sedikit lebih kecil. Praktik terbaik atau terlalu berhati-hati?
sudo su jenkins
mkdir ~/Library/MobileDevice
mkdir ~/Library/MobileDevice/Provisioning\ Profiles
- Pindahkan profil penyediaan yang Anda siapkan di Portal Penyediaan ke folder baru ini. Sekarang kita tinggal dua langkah lagi untuk dapat menjalankan xcodebuild dari baris perintah sebagai jenkins, dan itu berarti kita juga hampir bisa mendapatkan build yang menjalankan Jenkins CI.
security unlock-keychain -p <keychain password>
xcodebuild -target MyTarget -sdk iphoneos
Sekarang kita mendapatkan pembangunan yang berhasil dari baris perintah saat masuk sebagai daemon jenkins, jadi jika kita membuat proyek gaya bebas dan menambahkan dua langkah terakhir (# 5 dan # 6 di atas) kita akan dapat mengotomatiskan pembuatan proyek iOS kami!
Ini mungkin tidak perlu, tetapi saya merasa lebih baik mengatur jenkins UserShell kembali ke / usr / bin / false setelah saya berhasil mendapatkan semua pengaturan ini. Apakah saya menjadi paranoid?
Masalah 4: Gantungan kunci default masih tidak tersedia!
( EDIT: Saya memposting hasil edit ke pertanyaan saya, melakukan boot ulang untuk memastikan solusi saya 100%, dan tentu saja, saya meninggalkan satu langkah )
Bahkan setelah semua langkah di atas, Anda harus mengubah plist Launch Daemon di /Library/LaunchDaemons/org.jenkins-ci.plist seperti yang dinyatakan dalam jawaban ini . Harap dicatat ini juga merupakan bug openrdar .
Ini akan terlihat seperti ini:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>EnvironmentVariables</key>
<dict>
<key>JENKINS_HOME</key>
<string>/Users/Shared/Jenkins/Home</string>
</dict>
<key>GroupName</key>
<string>daemon</string>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>org.jenkins-ci</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/Library/Application Support/Jenkins/jenkins-runner.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>UserName</key>
<string>jenkins</string>
<!-- **NEW STUFF** -->
<key>SessionCreate</key>
<true />
</dict>
</plist>
Dengan penyiapan ini, saya juga merekomendasikan plugin Xcode untuk Jenkins , yang membuat penyiapan skrip xcodebuild sedikit lebih mudah. Pada titik ini, saya juga merekomendasikan membaca halaman manual untuk xcodebuild - apakah Anda sudah sampai sejauh ini di Terminal, bukan?
Penyiapan ini tidak sempurna, dan semua saran atau wawasan sangat dihargai.
Saya mengalami kesulitan memilih jawaban yang "benar" karena apa yang saya gunakan untuk memecahkan masalah saya adalah kumpulan masukan dari semua orang. Saya sudah mencoba memberikan setidaknya satu suara untuk semua orang, tetapi berikan jawaban kepada Simon karena dia kebanyakan menjawab pertanyaan asli. Selanjutnya Sami Tikka layak mendapatkan banyak pujian atas upayanya membuat Jenkins bekerja melalui AppleScript sebagai aplikasi OS X biasa. Jika Anda hanya tertarik untuk membuat Jenkins aktif dan berjalan cepat dalam sesi pengguna Anda (yaitu, bukan sebagai server tanpa kepala), solusinya jauh lebih mirip Mac.
Saya berharap upaya saya memicu diskusi lebih lanjut, dan membantu orang-orang malang berikutnya yang datang untuk berpikir bahwa mereka bisa mendapatkan pengaturan Jenkins CI untuk proyek iOS mereka di akhir pekan karena semua hal luar biasa yang telah mereka dengar tentangnya.
Pembaruan: 9 Agustus 2013
Dengan begitu banyak suara positif dan favorit, saya pikir saya akan kembali ke ini 18 bulan kemudian dengan beberapa pelajaran singkat yang dipetik.
Pelajaran 1: Jangan paparkan Jenkins ke internet publik
Pada WWDC 2012, saya mengajukan pertanyaan ini kepada teknisi Xcode dan OS X Server. Saya menerima hiruk-pikuk "jangan lakukan itu!" dari siapa pun yang saya tanya. Mereka semua setuju bahwa proses pembuatan otomatis sangat bagus, tetapi server seharusnya hanya dapat diakses di jaringan lokal. Para insinyur OS X Server menyarankan untuk mengizinkan akses jarak jauh melalui VPN.
Pelajaran 2: Ada opsi penginstalan baru sekarang
Saya baru-baru ini memberikan ceramah CocoaHeads tentang pengalaman Jenkins saya, dan saya sangat terkejut karena saya menemukan beberapa metode pemasangan baru - Homebrew dan bahkan versi Bitnami Mac App Store . Ini pasti patut untuk dicoba. Jonathan Wright memiliki inti yang merinci bagaimana Homebrew Jenkins bekerja .
Pelajaran 3: Tidak, sungguh, jangan biarkan build box Anda ke internet
Cukup jelas dari posting asli bahwa saya bukan administrator sistem atau pakar keamanan. Akal sehat tentang hal-hal pribadi (gantungan kunci, kredensial, sertifikat, dll) membuat saya merasa tidak nyaman meletakkan kotak Jenkins saya di internet. Nick Arnott dari Neglected Potential dapat mengonfirmasi heebie-jeebies saya dengan cukup mudah di artikel ini .
TL; DR
Rekomendasi saya kepada orang lain yang ingin mengotomatiskan proses build mereka telah berubah selama satu setengah tahun terakhir. Pastikan mesin Jenkins Anda berada di belakang firewall Anda. Instal dan atur Jenkins sebagai pengguna Jenkins khusus baik menggunakan penginstal, versi Bitnami Mac App Store, AppleScript Sami Tikka, dll; ini menyelesaikan sebagian besar sakit kepala yang saya jelaskan di atas. Jika Anda membutuhkan akses jarak jauh, menyiapkan layanan VPN di OS X Server hanya membutuhkan waktu sepuluh menit. Saya telah menggunakan pengaturan ini selama lebih dari setahun dan saya sangat senang dengannya. Semoga berhasil!