在 CI (Travis/Jenkins) 环境中使用 xcodebuild (Xcode 8) 和自动登录
Use xcodebuild (Xcode 8) and automatic signing in CI (Travis/Jenkins) environments
随着 Xcode8 的发布,Apple 引入了一种管理签名配置的新方法。现在你有两个选项 Manual
和 Automatic
.
根据 WWDC 2016 Session 关于代码签名 (WWDC 2016 - 401 - What's new in Xcode app signing),当您 select Automatic
签名时,Xcode 将:
- 创建签名证书
- 创建和更新 App ID
- 创建和更新配置文件
但根据 Apple 在 session 中的说法,Automatic Signing
将使用 Development signing
并且仅限于 Xcode-created 配置文件。
当您尝试在 CI 环境(如 Travis CI 或 Jenkins)上使用 Automatic Signing
时,问题就出现了。我想不出一个简单的方法来继续使用自动和签名分发(因为 Xcode 强制您使用开发和 Xcode-created 配置文件)。
新的 "Xcode-created provisioning profiles" 没有出现在开发者门户中,尽管我可以在我的机器上找到...我应该将这些配置文件移动到 CI 机器上,为 Development
并导出为 Distribution
?有没有办法使用 xcodebuild
覆盖 Automatic Signing
?
我基本上 运行 使用 Jenkins CI 和 Xcode 插件遇到了同样的问题。
我最终使用 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 位开发人员团队 ID(类似于 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 位开发人员团队 ID(类似于 A1B2C3D4E5)
与 Jenkins Xcode 插件等程序相比,此过程更接近您手动使用 Xcode 进行的操作。
注意:.xcarchive 文件将始终进行开发签名,但在第 2 步中选择“app-store”作为方法将进行正确的分发签名,并将分发配置文件包含为“embedded.mobileprovision".
希望对您有所帮助。
尝试了几个选项后,这些是我能够在我的 CI 服务器上使用的解决方案:
在CI环境中包含开发者证书和私钥以及自动生成的配置文件:
使用 Automatic signing
会强制您使用 Developer
证书和 auto-generated provisioning profiles
。一种选择是将您的开发证书和私钥(应用程序 -> 实用程序 -> 钥匙串访问)和自动生成的配置文件导出到 CI 机器。找到自动生成的配置文件的一种方法是导航到 ~/Library/MobileDevice/Provisioning\ Profiles/
,将所有文件移动到备份文件夹,打开 Xcode 并存档项目。 Xcode 将创建自动生成的开发配置文件并将它们复制到 Provisioning Profiles
文件夹。
xcodebuild archive ...
将创建一个 .xcarchive
签名 Development
。 xcodebuild -exportArchive ...
然后可以退出 Distribution
的构建
在 CI 环境中构建时将 'Automatic' 替换为 'Manual'
在调用 xcodebuild
之前,解决方法是在项目文件中将 ProvisioningStyle = Automatic
的所有实例替换为 ProvisioningStyle = Manual
。 sed
可用于在 pbxproj
文件中进行简单的查找替换:
sed -i '' 's/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/' <ProjectName>.xcodeproj/project.pbxproj
@thelvis 还使用 xcodeproj
gem 创建了一个 Ruby script 来执行此操作。该脚本使您可以更好地控制更改的内容。
xcodebuild
将使用项目中设置的代码签名身份 (CODE_SIGN_IDENTITY
) 以及配置文件 (PROVISIONING_PROFILE_SPECIFIER
)。这些设置也可以作为参数提供给 xcodebuild
,它们将覆盖项目中设置的代码签名身份 and/or 配置文件。
EDIT: with Xcode 9, xcodebuild
has a new build settings parameter CODE_SIGN_STYLE
to select between Automatic
and Manual
so there's no need to find and replace instances of automatic with manual in the project file, more info in WWDC 2017 Session 403 What's New in Signing for Xcode and Xcode Server
切换到手动签名
手动签名将提供对所使用的代码签名身份和配置文件的完全控制。它可能是最干净的解决方案,但缺点是失去了自动签名的所有好处。
要了解有关使用 Xcode 8 进行代码签名的更多信息,我真的推荐这个 article as well as the WWDC2016 session 401 - What's new in Xcode app signing
对我来说,没有任何效果。我通过更改安装在 Mac Mini(CI 服务器与 Jenkins)上的 Xcode 应用程序中的文件解决了我的问题,如此 link:
所示
https://www.jayway.com/2015/05/21/fixing-your-ios-build-scripts/
此外,我关闭了 Xcode 的自动签名。
大功告成!终于成功了!
我正在考虑这里尚未提及的另一种选择。设置两个相同的目标,只是签名设置不同。
- 开发目标 使用自动签名在添加新设备/开发人员时获得所有这些好处
- CI 目标 使用手动签名
缺点是您必须管理两个相同的目标。好处是可以获得开发自动签名的好处,并且不必维护在构建时间之前修改项目的潜在脆弱脚本。
如果您使用 Xcode 8.x 和 CI 的 Jenkins。那么您可能会遇到 "Signing for “YourProjectName" 需要开发团队的问题。 Select项目编辑器中的开发团队。
SDK“iOS 10.1”中的产品类型 'Application' 需要代码签名。** 构建失败 ** 当 运行 作业时。
有什么解决办法?
解决方法是:
在 Xcode 项目构建设置中将配置文件设置为 None。
在 jenkins 中,在 Xcode 设置之前创建一个 execute shell 并编写以下命令
sed -i '' 's/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/' ProjectName.xcodeproj/project.pbxproj
记住:在 jenkins 的构建部分中的 Xcode 设置之前保持执行 shell。
这有效。
我注意到我的 Unity 构建从未向我的 XCode 项目添加 ProvisioningStyle 密钥。然后,我找到了一种使用 "PostProcessBuild" 构建脚本手动添加 ProvisioningStyle 的方法。即在 Unity 构建 IOS XCode 项目后调用的代码单元。
首先,我查看了 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 */;
};
};
};
然后我创建了我的代码来复制上面看到的文件的 "structure"。 (使用此处找到的 XCode 编辑器项目: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 "";
}
为我解决的问题是:http://code-dojo.blogspot.jp/2012/09/fix-ios-code-signing-issue-when-using.html
... 正在将证书从登录钥匙串复制到系统钥匙串。
您可能还想将所有开发证书设置为 'Allow all applications to access this item'(Right-click/Get Info/Access 控制)。
有一个名为 fastlane 的工具,它使 xcodebuild 的使用变得更加容易,它得到维护意味着新的更新将继续为 xcode 的更改提供支持。它可以更轻松地创建脚本和配置,以在它支持的许多其他 xcode 自动化工具中构建和联合签名您的应用程序。我建议您看一看。
随着 Xcode8 的发布,Apple 引入了一种管理签名配置的新方法。现在你有两个选项 Manual
和 Automatic
.
根据 WWDC 2016 Session 关于代码签名 (WWDC 2016 - 401 - What's new in Xcode app signing),当您 select Automatic
签名时,Xcode 将:
- 创建签名证书
- 创建和更新 App ID
- 创建和更新配置文件
但根据 Apple 在 session 中的说法,Automatic Signing
将使用 Development signing
并且仅限于 Xcode-created 配置文件。
当您尝试在 CI 环境(如 Travis CI 或 Jenkins)上使用 Automatic Signing
时,问题就出现了。我想不出一个简单的方法来继续使用自动和签名分发(因为 Xcode 强制您使用开发和 Xcode-created 配置文件)。
新的 "Xcode-created provisioning profiles" 没有出现在开发者门户中,尽管我可以在我的机器上找到...我应该将这些配置文件移动到 CI 机器上,为 Development
并导出为 Distribution
?有没有办法使用 xcodebuild
覆盖 Automatic Signing
?
我基本上 运行 使用 Jenkins CI 和 Xcode 插件遇到了同样的问题。
我最终使用 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 位开发人员团队 ID(类似于 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 位开发人员团队 ID(类似于 A1B2C3D4E5)
与 Jenkins Xcode 插件等程序相比,此过程更接近您手动使用 Xcode 进行的操作。
注意:.xcarchive 文件将始终进行开发签名,但在第 2 步中选择“app-store”作为方法将进行正确的分发签名,并将分发配置文件包含为“embedded.mobileprovision".
希望对您有所帮助。
尝试了几个选项后,这些是我能够在我的 CI 服务器上使用的解决方案:
在CI环境中包含开发者证书和私钥以及自动生成的配置文件:
使用 Automatic signing
会强制您使用 Developer
证书和 auto-generated provisioning profiles
。一种选择是将您的开发证书和私钥(应用程序 -> 实用程序 -> 钥匙串访问)和自动生成的配置文件导出到 CI 机器。找到自动生成的配置文件的一种方法是导航到 ~/Library/MobileDevice/Provisioning\ Profiles/
,将所有文件移动到备份文件夹,打开 Xcode 并存档项目。 Xcode 将创建自动生成的开发配置文件并将它们复制到 Provisioning Profiles
文件夹。
xcodebuild archive ...
将创建一个 .xcarchive
签名 Development
。 xcodebuild -exportArchive ...
然后可以退出 Distribution
在 CI 环境中构建时将 'Automatic' 替换为 'Manual'
在调用 xcodebuild
之前,解决方法是在项目文件中将 ProvisioningStyle = Automatic
的所有实例替换为 ProvisioningStyle = Manual
。 sed
可用于在 pbxproj
文件中进行简单的查找替换:
sed -i '' 's/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/' <ProjectName>.xcodeproj/project.pbxproj
@thelvis 还使用 xcodeproj
gem 创建了一个 Ruby script 来执行此操作。该脚本使您可以更好地控制更改的内容。
xcodebuild
将使用项目中设置的代码签名身份 (CODE_SIGN_IDENTITY
) 以及配置文件 (PROVISIONING_PROFILE_SPECIFIER
)。这些设置也可以作为参数提供给 xcodebuild
,它们将覆盖项目中设置的代码签名身份 and/or 配置文件。
EDIT: with Xcode 9,
xcodebuild
has a new build settings parameterCODE_SIGN_STYLE
to select betweenAutomatic
andManual
so there's no need to find and replace instances of automatic with manual in the project file, more info in WWDC 2017 Session 403 What's New in Signing for Xcode and Xcode Server
切换到手动签名
手动签名将提供对所使用的代码签名身份和配置文件的完全控制。它可能是最干净的解决方案,但缺点是失去了自动签名的所有好处。
要了解有关使用 Xcode 8 进行代码签名的更多信息,我真的推荐这个 article as well as the WWDC2016 session 401 - What's new in Xcode app signing
对我来说,没有任何效果。我通过更改安装在 Mac Mini(CI 服务器与 Jenkins)上的 Xcode 应用程序中的文件解决了我的问题,如此 link:
所示
https://www.jayway.com/2015/05/21/fixing-your-ios-build-scripts/
此外,我关闭了 Xcode 的自动签名。
大功告成!终于成功了!
我正在考虑这里尚未提及的另一种选择。设置两个相同的目标,只是签名设置不同。
- 开发目标 使用自动签名在添加新设备/开发人员时获得所有这些好处
- CI 目标 使用手动签名
缺点是您必须管理两个相同的目标。好处是可以获得开发自动签名的好处,并且不必维护在构建时间之前修改项目的潜在脆弱脚本。
如果您使用 Xcode 8.x 和 CI 的 Jenkins。那么您可能会遇到 "Signing for “YourProjectName" 需要开发团队的问题。 Select项目编辑器中的开发团队。
SDK“iOS 10.1”中的产品类型 'Application' 需要代码签名。** 构建失败 ** 当 运行 作业时。
有什么解决办法?
解决方法是:
在 Xcode 项目构建设置中将配置文件设置为 None。
在 jenkins 中,在 Xcode 设置之前创建一个 execute shell 并编写以下命令
sed -i '' 's/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/' ProjectName.xcodeproj/project.pbxproj
记住:在 jenkins 的构建部分中的 Xcode 设置之前保持执行 shell。
这有效。
我注意到我的 Unity 构建从未向我的 XCode 项目添加 ProvisioningStyle 密钥。然后,我找到了一种使用 "PostProcessBuild" 构建脚本手动添加 ProvisioningStyle 的方法。即在 Unity 构建 IOS XCode 项目后调用的代码单元。
首先,我查看了 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 */;
};
};
};
然后我创建了我的代码来复制上面看到的文件的 "structure"。 (使用此处找到的 XCode 编辑器项目: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 "";
}
为我解决的问题是:http://code-dojo.blogspot.jp/2012/09/fix-ios-code-signing-issue-when-using.html
... 正在将证书从登录钥匙串复制到系统钥匙串。 您可能还想将所有开发证书设置为 'Allow all applications to access this item'(Right-click/Get Info/Access 控制)。
有一个名为 fastlane 的工具,它使 xcodebuild 的使用变得更加容易,它得到维护意味着新的更新将继续为 xcode 的更改提供支持。它可以更轻松地创建脚本和配置,以在它支持的许多其他 xcode 自动化工具中构建和联合签名您的应用程序。我建议您看一看。