Используйте xcodebuild (Xcode 8) и автоматическое подписание в средах CI (Travis/Jenkins)
С выпуском Xcode 8 Apple представила новый способ управления конфигурацией подписи. Теперь у вас есть две опции Manual
и Automatic
.
В соответствии с сессией WWDC 2016 о подписании кода (WWDC 2016 - 401 - Что нового в подписании приложения Xcode), когда вы выбираете Automatic
подписание, Xcode собирается:
- Создание сертификатов подписи
- Создание и обновление идентификаторов приложений
- Создание и обновление профилей подготовки
Но в соответствии с тем, что Apple говорит в этом сеансе, Automatic Signing
собирается использовать Development signing
и будет ограничиваться профилями, создаваемыми Xcode.
Проблема возникает, когда вы пытаетесь использовать Automatic Signing
в среде CI (например, Travis CI или Jenkins). Я не могу найти простой способ продолжать использовать Автоматический и подписывать для распространения (поскольку Xcode заставляет вас использовать профили подготовки, созданные для разработки и Xcode).
Новые профили подготовки, созданные Xcode, не отображаются на портале разработчиков, хотя я могу найти их на своей машине... я должен перенести эти профили на машину CI, построить для Development
и экспортировать для Distribution
? Есть ли способ переопределить Automatic Signing
с помощью xcodebuild
?
Ответы
Ответ 1
После нескольких вариантов, это решения, которые я смог использовать на моем сервере CI:
-
Включите сертификат разработчика и закрытый ключ, а также автогенерированные профили обеспечения в среде CI:
Использование Automatic signing
заставляет вас использовать сертификат Developer
и auto-generated provisioning profiles
. Один из вариантов заключается в том, чтобы экспортировать свой сертификат разработки и закрытый ключ (Application → Utilities → Keychain Access) и автогенерированные профили подготовки к машине CI. Чтобы найти автогенерируемые профили обеспечения, перейдите к ~/Library/MobileDevice/Provisioning\ Profiles/
, переместите все файлы в папку резервного копирования, откройте Xcode и заархивируйте проект. Xcode создаст профили обеспечения автоматической генерации профилей и скопирует их в папку Provisioning Profiles
.
xcodebuild archive ...
создаст .xcarchive
, подписанный для Development
. xcodebuild -exportArchive ...
может отменить сборку для Distribution
-
Заменить "Автоматически" на "Руководство" при построении среды CI
Перед вызовом xcodebuild
обходным решением является замена всех экземпляров ProvisioningStyle = Automatic
на ProvisioningStyle = Manual
в файле проекта. sed
можно использовать для простого поиска замены в файле pbxproj
:
sed -i '' 's/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/' <ProjectName>.xcodeproj/project.pbxproj
@thelvis также создал Ruby script, чтобы сделать это, используя драгоценный камень xcodeproj
. script дает вам лучший контроль над тем, что изменилось.
xcodebuild
будет использовать идентификатор подписи кода (CODE_SIGN_IDENTITY
), заданный в проекте, а также профили подготовки (PROVISIONING_PROFILE_SPECIFIER
). Эти параметры также могут предоставляться как параметры xcodebuild
, и они переопределяют идентификатор подписи кода и/или профиль подготовки, установленные в проекте.
EDIT: с Xcode 9, xcodebuild
имеет новый параметр настроек сборки CODE_SIGN_STYLE
для выбора между Automatic
и Manual
, поэтому нет необходимости находить и заменять экземпляры автоматического с помощью руководства в файле проекта, больше info in WWDC 2017 Сессия 403 Что нового в подписи для Xcode и Xcode Server
-
Переключиться на подписку вручную
Подписание вручную обеспечит полный контроль над идентификаторами подписи кода и используемыми профилями. Это, вероятно, самое чистое решение, но с недостатком потери всех преимуществ автоматической подписи.
Чтобы узнать больше о подписи кода с помощью Xcode 8, я действительно рекомендую эту статью, а также сеанс WWDC2016 401 - Что нового в подписании приложения Xcode
Ответ 2
В основном я сталкиваюсь с той же проблемой, используя Jenkins CI и Xcode Plugin.
Я закончил работу с компоновкой и настройкой кода, используя xcodebuild
.
0. Предпосылки
Чтобы успешно выполнить следующие шаги, вам необходимо установить необходимые профили и сертификаты подготовки. Это означает, что ваша подпись кода уже должна работать в целом.
1. Создание .xcarchive
xcodebuild -project <path/to/project.xcproj> -scheme <scheme-name> -configuration <config-name> clean archive -archivePath <output-path> DEVELOPMENT_TEAM=<dev-team-id>
-
DEVELOPMENT_TEAM
: ваш 10-значный идентификатор группы разработчиков (что-то вроде A1B2C3D4E5)
2. Экспорт в .ipa
xcodebuild -exportArchive -archivePath <path/to/your.xcarchive> -exportOptionsPlist <path/to/exportOptions.plist> -exportPath <output-path>
Пример exportOptions.plist
:
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>development</string>
<key>teamID</key>
<string> A1B2C3D4E5 </string>
</dict>
</plist>
-
method
: один из development
, app-store
, ad-hoc
, enterprise
-
teamID
: ваш 10-значный идентификатор группы разработчиков (что-то вроде A1B2C3D4E5)
Этот процесс в любом случае ближе к тому, что вы делаете с Xcode вручную, чем то, что делает Jenkins Xcode Plugin.
Примечание. Файл .xcarchive всегда будет подписан, но выбор "app-store", как метод на втором этапе, сделает правильное подписание рассылки, а также включит профиль распространения как "embedded.mobileprovision".
Надеюсь, что это поможет.
Ответ 3
Я рассматриваю еще один вариант, о котором я еще не упоминал. Установите две идентичные цели, которые отличаются только в настройках их подписания.
- Цель разработки использует автоматическое подписание для получения всех этих преимуществ при добавлении новых устройств/разработчиков.
- Цель CI использует ручную подпись
Даунсайд - это то, что вам придется управлять двумя идентичными целями. Потенциал роста заключается в том, что вы получаете преимущества автоматического подписания для разработки и не должны поддерживать потенциально хрупкие сценарии, которые изменяют ваш проект непосредственно перед временем сборки.
Ответ 4
Если вы используете Xcode 8.x и Jenkins для CI. Вероятно, вы столкнулись бы с проблемой "Подписание для" YourProjectName "требует команды разработчиков. Выберите команду разработчика в редакторе проекта.
Подписание кода необходимо для типа продукта "Приложение" в SDK "iOS 10.1". ** BUILD FAILED ** при выполнении задания.
Какое решение?
Решение:
-
установите профиль Provisioning в None в настройках сборки проекта Xcode.
-
В jenkins создайте оболочку выполнения перед настройкой Xcode и напишите следующую команду
sed -i '' 's/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/' ProjectName.xcodeproj/project.pbxproj
Помните: держите эту оболочку перед настройками Xcode в разделе Build jenkins.
Это работает.
Ответ 5
Для меня ничего не получилось. Я решил свою проблему, изменив файл в приложении Xcode, установленном на вашем Mac Mini (CI-сервер с Jenkins), как показано в этой ссылке:
https://www.jayway.com/2015/05/21/fixing-your-ios-build-scripts/
Кроме того, я отключил автоматическое подписание с Xcode.
Все сделано! Наконец работает!
Ответ 6
Я заметил, что моя сборка Unity никогда не добавляла ключ ProvisioningStyle к моему проекту XCode. Затем я нашел способ вручную добавить ProvisioningStyle с помощью сборки PostProcessBuild script. то есть блок кода, который вызывается после того, как проект IOS XCode был создан Unity.
Сначала я посмотрел, как должен выглядеть файл project.pbxproj - когда он настроен на "Ручное обеспечение":
/* Begin PBXDictionary section */
29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject;
attributes = {
TargetAttributes = {
1D6058900D05DD3D006BFB54 /* Unity-iPhone */ = {
ProvisioningStyle = Manual;
};
5623C57217FDCB0800090B9E /* Unity-iPhone Tests */ = {
TestTargetID = 1D6058900D05DD3D006BFB54 /* Unity-iPhone */;
};
};
};
Затем я создал свой код для репликации "структуры" файла, описанного выше. (используя проект XCodeEditor, найденный здесь: XCodeEditor)
[PostProcessBuild]
public static void OnPostProcessBuild(BuildTarget target, string path)
{
// Create a new project object from build target
XCProject project = new XCProject(path);
if (target == BuildTarget.iOS)
{
//Add Manual ProvisioningStyle - this is to force manual signing of the XCode project
bool provisioningSuccess = AddProvisioningStyle(project, "Manual");
if (provisioningSuccess)
project.Save();
}
}
private static bool AddProvisioningStyle(XCProject project, string style)
{
var pbxProject = project.project;
var attr = pbxProject.data["attributes"] as PBXDictionary;
var targetAttributes = attr["TargetAttributes"] as PBXDictionary;
var testTargetIDGuid = FindValue(targetAttributes, "TestTargetID");
if (!string.IsNullOrEmpty(testTargetIDGuid))
{
var settings = new PBXDictionary();
//here we set the ProvisioningStyle value
settings.Add("ProvisioningStyle", style);
targetAttributes.Add(testTargetIDGuid, settings);
var masterTest = FindValue(targetAttributes, "ProvisioningStyle");
if (masterTest == style)
{
return true;
}
}
return false;
}
private static string FindValue(PBXDictionary targetAttributes, string key)
{
foreach (var item in targetAttributes)
{
var ma = item.Value as PBXDictionary;
foreach (var di in ma)
{
var lookKey = di.Key;
if (lookKey == key)
{
return di.Value.ToString();
}
}
}
return "";
}
Ответ 7
Для меня это было исправлено: http://code-dojo.blogspot.jp/2012/09/fix-ios-code-signing-issue-when-using.html
... копирование сертификатов из ключевого слова Login в системную цепочку ключей.
Вы также можете установить для всех сертификатов разработчика "Разрешить всем приложениям доступ к этому элементу" (щелкните правой кнопкой мыши /Get Info/Access Control).
Ответ 8
Существует инструмент под названием fastlane, который упрощает использование xcodebuild и поддерживается, что означает, что новые обновления будут продолжать поддерживать изменения в xcode. Это упрощает создание сценариев и конфигов для создания и кодовое сопоставление вашего приложения среди многих других инструментов автоматизации xcode, которые он поддерживает. Я бы порекомендовал взглянуть на него.