Jenkins - Работает сценарий сборки кода Xcode
Ниже приведена моя сборка script (не используя плагин xcodebuild).
- Выполнение шагов сборки
- Я создал отдельный брелок с требуемыми сертификатами и закрытыми ключами, и они видны в Keychain Access
- команды keychain не работают в script
- список безопасности-keychains показывает их как действительные связки ключей
Это действие, как команда разблокировки, действительно не выполняется.
Когда я пытаюсь запустить код из командной строки через
codesign -f -s "iPhone Developer: mycert" -v sample.app/ --keychain /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain
Я получаю
CSSM_SignData returned: 000186AD
sample.app/: unknown error -2070=fffffffffffff7ea
хотя я не уверен, что я эмулирую из командной строки правильно, так как вы можете в лучшем случае
sudo -u jenkins bash
xcodebuild ONLY_ACTIVE_ARCH="NO" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" -scheme "MySchemeName" CONFIGURATION_BUILD_DIR="`pwd`"
security list-keychains -s /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain
+ security default-keychain -d user -s /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain
+ security unlock-keychain -p jenkins /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain
+ security list-keychains
"/Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain"
"/Library/Keychains/System.keychain"
+ security default-keychain
"/Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain"
+ codesign -f -s '$IDENTITY_GOES_HERE.' -v sample.app/
sample.app/: User interaction is not allowed.
Любая помощь очень ценится.
Ответы
Ответ 1
Мы не используем Jenkins, но я видел это в нашей автоматизации сборки раньше. Вот как мы это решили:
1) Создайте свой брелок для ключей. Это будет содержать закрытый ключ/сертификат, используемый для кодирования:
security create-keychain -p [keychain_password] MyKeychain.keychain
Keychain_password зависит от вас. Вы будете использовать это позже, чтобы разблокировать брелок во время сборки.
2) Импортируйте закрытый ключ (*.p12) для вашего идентификатора CodeSign:
security import MyPrivateKey.p12 -t agg -k MyKeychain.keychain -P [p12_Password] -A
Ключ здесь - флаг "-A". Это позволит получить доступ к цепочке ключей без предупреждения. Вот почему вы видите ошибку "Пользовательское взаимодействие не допускается". Если вы пытаетесь создать эту сборку через интерфейс Xcode, это тот момент, когда вы предложите "Разрешить доступ" к вашей цепочке ключей.
3) Однако вы сохраняете брелок (например, проверяя его в исходном элементе управления), убедитесь, что он доступен для записи и выполнимости вашим пользователем сборки.
Когда вы будете готовы к созданию, добавьте следующее до запуска xcodebuild:
# Switch keychain
security list-keychains -s "/path/to/MyKeyhain.keychain"
security default-keychain -s "/path/to/MyKeychain.keychain"
security unlock-keychain -p "[keychain_password]" "/path/to/MyKeychain.keychain"
Если вы работаете локально, вам может понадобиться добавить что-то в конце сборки script, которая вернется к цепочке ключей входа (~/Library/Keychains/login.keychain), например:
# Switch back to login keychain
security list-keychains -s "~/Library/Keychains/login.keychain"
security default-keychain -s "~/Library/Keychains/login.keychain"
Попробуйте. Мы создаем отдельный брелок для каждой используемой нами идентичности (наш собственный плюс строится от имени клиентов). В нашем случае у нас есть как учетная запись AppStore, так и Enterprise. Это может привести к конфликтам именования при кодовом кодировании (например: разрешения обеих учетных записей на "iPhone Distribution: ACME Corporation" ). Сохраняя эти идентичности в отдельных цепочках ключей, мы избегаем этого конфликта.
Ответ 2
Перемещение сертификатов в системную цепочку ключей, и, ссылаясь на нее, исправлена проблема
Ответ 3
Требуется, чтобы разблокировать брелок перед тем, чтобы подписать
"разблокировка безопасности-keychain -p"
Ответ 4
В этом ответе мы добавляем/удаляем ваш iOS-сертификат без манипуляций с цепочкой ключей для входа в систему или без изменения ключевого слова по умолчанию:
- Использовать временную цепочку ключей
- Добавить временную цепочку ключей в список поиска (не заменяя)
- Разблокировать временную цепочку ключей без тайм-аута
- Импортируйте сертификат с помощью
-T /usr/bin/codesign
- Сделайте сборку
- Удалить сертификат, удалив временную цепочку ключей
Создает временную цепочку ключей. Я добавил $$
, который является PID. Это означает, что мы разрешаем параллелизировать script, позволяя одновременно создавать несколько временных связок ключей:
# Create temp keychain
MY_KEYCHAIN="MyKeychain-$$.keychain"
MY_KEYCHAIN_PASSWORD="secret"
security create-keychain -p "$MY_KEYCHAIN_PASSWORD" "$MY_KEYCHAIN"
Добавляет временную цепочку ключей в список поиска. Будьте осторожны, чтобы использовать security list-keychains -s
, чтобы добавить цепочку ключей, иначе вы будете строить clobber в другом потоке:
# Append keychain to the search list
security list-keychains -d user -s "$MY_KEYCHAIN" $(security list-keychains -d user | sed s/\"//g)
security list-keychains
Разблокирует временную брелок без автоматического тайм-аута блокировки (security set-keychain-settings
). Если вы забудете исправить тайм-аут переадресации, сборка займет больше времени, чем тайм-аут перегрузки по умолчанию, будет вызывать запрос пароля:
# Unlock the keychain
security set-keychain-settings "$MY_KEYCHAIN"
security unlock-keychain -p "$MY_KEYCHAIN_PASSWORD" "$MY_KEYCHAIN"
Импортировать сертификат iOS и предоставить /usr/bin/codesign
доступ без запроса пароля.
# Import certificate
security import $CERT -k "$MY_KEYCHAIN" -P "$CERT_PASSWORD" -T "/usr/bin/codesign"
Поскольку мы используем временную цепочку ключей, и мы знаем, что она содержит только 1 сертификат, мы можем программным путем получить IOS_IDENTITY (необходимый для ввода шагов сборки).
# Detect the iOS identity
IOS_IDENTITY=$(security find-identity -v -p codesigning "$MY_KEYCHAIN" | head -1 | grep '"' | sed -e 's/[^"]*"//' -e 's/".*//')
IOS_UUID=$(security find-identity -v -p codesigning "$MY_KEYCHAIN" | head -1 | grep '"' | awk '{print $2}')
# New requirement for MacOS 10.12
security set-key-partition-list -S apple-tool:,apple: -s -k $MY_KEYCHAIN_PASSWORD $MY_KEYCHAIN
Сделайте свою сборку сейчас
# Insert your custom build steps
Удалить временную цепочку ключей. Обратите внимание, что при этом автоматически вытащите его из списка поиска. то есть все остальные брелки будут оставаться.
# Delete the temp keychain
security list-keychains
security delete-keychain "$MY_KEYCHAIN"
security list-keychains
Ответ 5
Я скопировал все ключи certs/private в новую цепочку ключей (вы можете щелкнуть правой кнопкой мыши на элементах и просто скопировать и вставить). В новой цепочке ключей щелкните правой кнопкой мыши на каждом закрытом ключе, Get Info → Access Control и сделайте ключи доступными для всех приложений.
Важно отметить, что в левом верхнем углу приложения Keychain есть список цепочек ключей. Переупорядочивайте их так, чтобы новый брелок был первым в списке.
Другой ответ, который я нашел, дал шаг сборки, чтобы разблокировать этот брелок во время сборки:
KEYCHAIN=/Users/<you>/Library/Keychains/codesign.keychain
# the -s option adds $KEYCHAIN to the search scope, while the -d option adds $KEYCHAIN to the system domain; both are needed
security -v list-keychains -d system -s $KEYCHAIN
security -v unlock-keychain -p <keychain password> $KEYCHAIN
Ответ 6
Это также может быть вызвано таймаутом по умолчанию в цепочке ключей.
Посмотрите мой ответ на "Пользовательское взаимодействие не разрешено" пытаясь подписать приложение OSX с помощью codeign
Ответ 7
Вот что сработало для меня:
- Я создал новый брелок и скопировал все записи из "входа" в него, назвал его "jenkins_ios"
- Создано новое значение keychain по умолчанию.
- Добавлен новый шаг "Выполнение оболочки" в конфигурации Jenkins, это должен быть первый шаг перед подпиской, содержащий следующее:
KEYCHAIN=/Users/<user>/Library/Keychains/jenkins_ios.keychain
security -v list-keychains -s $KEYCHAIN
security -v unlock-keychain -p <password> $KEYCHAIN
security set-keychain-settings -t 3600 -l $KEYCHAIN
Последний шаг действительно важен, так как тайм-аут разблокировки по умолчанию может оказаться недостаточным для правильного построения вашего проекта (именно это произошло с нашим проектом, поскольку он огромный, а шаг сборки занял около 5-7 минут, а keychain стал заблокирован на данный момент это требовалось для кода).
Ответ 8
Чтобы ошибка подписи кода, команда xcodebuild не может получить доступ к вашему закрытому ключу сертификата, поскольку она работает с подчиненным Jenkins с SSH.
Запустите эту строку в своей оболочке script, прежде чем запускать xcodebuild, чтобы разрешить доступ:
security set-key-partition-list -S apple-tool:,apple: -s -k <ROOT-PASSWORD> /Users/<YOUR USER NAME>/Library/Keychains/login.keychain-db
Надеюсь, что это поможет!
Ответ 9
FWIW... позвольте мне выслать еще одну возможную причину этого. У вас могут быть повторяющиеся сертификаты, и codesign
не может определить, какой из них использовать. Когда вы запускаете эту команду у своего подчиненного Jenkins, вы видите дубликаты, действительные сертификаты? Что-то вроде этого:
$ security find-identity -v -p codesigning
1) AAAAE00066DED2FE77DF43012573AD5B6188AAAA "iPhone Developer: JOHN SMITH (XAAAAFSUSJ)"
2) AAAAE00066DED2FE77DF43012573AD5B6188AAAA "iPhone Developer: JOHN SMITH (XAAAAFSUSJ)"
3) BBBB5B03DB566209964247982908D3DD74D1BBBB "iPhone Distribution: Example, Inc. (TBBBBH5HUE)"
4) BBBB5B03DB566209964247982908D3DD74D1BBBB "iPhone Distribution: Example, Inc. (TBBBBH5HUE)"
5) BBBB5B03DB566209964247982908D3DD74D1BBBB "iPhone Distribution: Example, Inc. (TBBBBH5HUE)"
6) AAAAE00066DED2FE77DF43012573AD5B6188AAAA "iPhone Developer: JOHN SMITH (XAAAAFSUSJ)"
7) AAAAE00066DED2FE77DF43012573AD5B6188AAAA "iPhone Developer: JOHN SMITH (XAAAAFSUSJ)"
8) BBBB5B03DB566209964247982908D3DD74D1BBBB "iPhone Distribution: Example, Inc. (TBBBBH5HUE)"
8 valid identities found
Если это так, я нашел полезным сделать следующее и вернуться к базовому набору подписи сертификатов:
- Удалите все сертификаты на ведомом Jenkins (и других подчиненных Jenkins, которые будут запускать вашу сборку script).
- Далее: проверьте, у вас есть
0 identifies
, снова запустив $ security find-identity -v -p codesigning
.
- В вашем репозитории приложений есть пользовательский
MyApp.keychain
с двумя действительными сертификатами. Обязательно удалите дубликаты.
- Теперь из вашей сборки script и до процесса
codesign
выполняется от разблокировать MyApp.keychain
и установить его как значение по умолчанию. Это предоставляет те сертификаты, которые доступны для codesign
.
- Наконец, снова проверьте на своем подчиненном устройстве Jenkins:
$ security find-identity -v -p codesigning
, что вы видите только сертификаты, которые вы вложили в MyApp.keychain
, и что в системе нет других идентификаторов подписи. Если вы все еще видите дубликаты после этого, у вас есть другие места, где ваш подчиненный Jenkins получает информацию об этих сертификатах.
Ответ 10
Я удалил дубликаты ключей из цепочек ключей (логин и система), и он начал работать. У меня был только один сертификат, но у меня много ключей, поэтому мне пришлось фильтровать по ним ключи, чтобы правильно их видеть.