在CI(Travis / Jenkins)环境中使用xcodebuild(Xcode 8)和自动签名


73

随着Xcode 8的发布,Apple引入了一种管理签名配置的新方法。现在,您有两个选择ManualAutomatic

根据有关代码签名的WWDC 2016会议(WWDC 2016-401-Xcode应用程序签名的新增功能),当您选择Automatic签名时,Xcode将执行以下操作:

  • 创建签名证书
  • 创建和更新应用程序ID
  • 创建和更新配置文件

但是根据苹果在那届会议上所说,它将被Automatic Signing使用,Development signing并且将仅限于Xcode创建的配置文件。

当您尝试Automatic Signing在CI环境(例如Travis CI或Jenkins)上使用时,就会出现问题。我无法找出一种简单的方法来继续使用“自动”并签署分发文件(因为Xcode会迫使您使用Development和Xcode创建的配置文件)。

新的“ Xcode创建的配置文件”未显示在开发人员门户中,尽管我可以在自己的计算机中找到……我是否应该将这些配置文件移至CI机器,为其构建Development并导出Distribution?有没有办法覆盖Automatic Signing使用xcodebuild


8
我遇到了同样的问题,这使我发狂。
nebulus

2
我创建了一个简单的ruby脚本,使您可以在自动和手动签名之间切换。您可以切换到“手动签名”并使用PROVISIONING_PROFILE_SPECIFIERCODE_SIGN_IDENTITY组合。请注意,它使用的是xcodeprojgem,您必须首先安装它gem install xcodeproj。我希望这能帮到您。
thelvis

太棒了,我最终还是这样做了。就我而言,简单的查找和替换就可以了。我将分享我的发现。
pablobart

问题仍然存在,即使您切换到Manual signing您,也必须找到一种将证书和配置文件(开发或生产)共享到所有CI服务器的方法(因为cli xcodebuild命令不会像xcode那样管理这些文件)。话虽这么说,您又回到了手动管理某些配置文件的方式(例如,使用fastlane),而自动功能则失去了它的兴趣。
Nicolas Braun

事实是,只要您使用Xcode,自动签名就是一个很棒的功能。终于成功了!可悲的是,如果您不打开Xcode(例如在CI中),它将无法正常工作。因此,我们最终在开发时使用了自动签名,并使用上面针对Jenkins Builds的脚本切换为手动。但是,如果xcodebuild可以自己进行自动签名,那就太好了。我们希望在下一个版本的Xcode中可以完全自动执行签名。^^
thelvis

Answers:


62

我基本上使用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:是的一个developmentapp-storead-hocenterprise
  • teamID:您的10位开发人员团队ID(类似于A1B2C3D4E5)

无论如何,此过程比Jenkins Xcode插件所完成的过程更接近于您手动使用Xcode进行的过程。

注意:.xcarchive文件将始终进行开发签名,但是在第二步中选择“ app-store”作为方法将进行正确的分发签名,并且还将分发配置文件包括为“ embedded.mobileprovision”。

希望这可以帮助。


2
当签名设置为AutomaticXcode时iPhone Developer,即使设置了DEVELOPMENT_TEAM和之后,仍在使用CODE_SIGNING_IDENTITY='Phone Distribution'。如果查看日志,则xcodebuild可以看到该代码签名正在使用Signing Identity: "iPhone Developer: XXXX (XXXXX)",因此您的CI环境需要开发人员证书和自动生成的配置文件,您使用的是Manual还是Automatic
pablobart 2016年

4
基本上,如果您尝试强制使用,CODE_SIGNING_IDENTIY但已Automatic启用了签名,则会收到此错误:<YourTarget> has conflicting provisioning settings. <YourTarget> is automatically signed, but code signing identity iPhone Distribution: ... has been manually specified. Set the code signing identity value to "iPhone Developer" in the build settings editor, or switch to manual signing in the project editor.
pablobart

实际上,我正在使用Unity3D创建Xcode项目,但是当我打开该项目时,我看到勾选了“自动管理签名”。我只是尝试使用它iPhone Distribution(直到现在我才使用Developer)。但这对我有用。命令行输出: Build settings from command line: CODE_SIGNING_IDENTITY = iPhone Distribution DEVELOPMENT_TEAM = MY_TEAM_ID是否可以粘贴您实际使用的命令(当然,您可以混淆团队ID或其他任何私有的东西)。
d4Rk '16

如果尝试CODE_SIGNING_IDENTITY= 'iPhone Distribution',我可以看到与您看到的输出相同的输出,但是如果您检查构建日志的完整输出并检查CodeSign实际使用的阶段Signing Identity: "iPhone Developer:....(请尝试使用保存xcodebuild终端输出> build.log)。因此,如果您与代码签名身份名称不完全匹配,它仍在使用开发。如果匹配您的代码签名身份名称(CODE_SIGNING_IDENTITY= 'iPhone Distribution: My Company Name'),则将看到另一个错误
pablobart

2
而且恐怕您当前无法使用工具在自动签名和手动签名之间切换。我想它可以工作,如果你找到一个方法来编辑project.pbxproj文件,并添加ProvisioningStyle = Manual;TargetAttributes你的目标。但是,这似乎很棘手,如果您想在CI环境中构建证书,则手动管理证书和配置文件似乎是一种更直接的方法。
thelvis

37

在尝试了一些选项之后,这些是我可以在CI服务器上使用的解决方案:

  • 在CI环境中包括开发人员证书和私钥以及自动生成的配置文件:

使用会Automatic signing强制您使用Developer证书和auto-generated provisioning profiles。一种选择是将开发证书和私钥(应用程序->实用程序->钥匙串访问)以及自动生成的配置文件导出到CI机器。定位自动生成的配置文件的一种方法是导航至~/Library/MobileDevice/Provisioning\ Profiles/,将所有文件移动到备份文件夹,打开Xcode并存档项目。Xcode将创建自动生成的开发配置文件,并将其复制到该Provisioning Profiles文件夹中。

xcodebuild archive ...将为创建一个.xcarchive签名Developmentxcodebuild -exportArchive ...然后可以将构建辞职Distribution

  • 在CI环境中构建时,将“自动”替换为“手动”

在调用xcodebuild一个解决方法是更换的所有实例ProvisioningStyle = AutomaticProvisioningStyle = Manual在项目文件。sed可用于在pbxproj文件中简单查找替换:

sed -i '' 's/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/' <ProjectName>.xcodeproj/project.pbxproj

@thelvis还创建了一个 使用xcodeprojgemRuby脚本来完成此任务。该脚本使您可以更好地控制更改。

xcodebuild 然后将使用代码签名身份(CODE_SIGN_IDENTITY项目中设置)以及供应配置文件(PROVISIONING_PROFILE_SPECIFIER)。这些设置也可以作为参数提供xcodebuild,它们将覆盖项目中设置的代码签名标识和/或供应配置文件。

编辑:使用Xcode 9,xcodebuild有一个新的生成设置参数CODE_SIGN_STYLE之间进行选择AutomaticManual因此不需要在项目文件中查找和替换手动实例的自动实例,更多信息 WWDC 2017 Session 403中的Xcode和Xcode Server签名中的新增功能

  • 切换到手动签名

手动签名将完全控制所使用的代码签名标识和配置文件。这可能是最干净的解决方案,但缺点是失去了自动签名的所有优点。

要了解有关使用Xcode 8进行代码签名的更多信息,我真的推荐这篇文章以及WWDC2016会议401-Xcode应用程序签名中的新增功能


关闭所有目​​标的手动签名后,我仍然遇到问题,Jenkins控制台输出中的错误是:### Codesigning''with'iPhone Distribution'+ / usr / bin / codesign --force --preserve-metadata =标识符,权利,资源规则-签署iPhone发行版。--resource-rules = / var / folders / 9v /.../ Payload / YourApp.app / ResourceRules.plist --entitlements /var/folders/9v/.../entitlements_plistHBx8AyjS / var / folders / 9v /。。 ./Payload/YourApp.app程序/ usr / bin / codesign返回1:[警告:--preserve-metadata与选项“ resource-rules”一起使用(在Mac OS X> = 10.10中已弃用!)!
C0D3'9

如果您使用的是Automatic无法使用iPhone Distribution的版本,则需要执行上述选项之一,使用“开发”进行签名,然后使用分发或“强制”手动签名进行导出
pablobart

抱歉,我写错了,我的意思是关闭自动签名后
C0D3

您的问题似乎与新的签名没有关系,新的签名是与该网站链接的快速Google搜索,它可能会对有所帮助jayway.com/2015/05/21/fixing-your-ios-build-scripts另外,由于Xcode 7,xcrun PackageApplication不建议使用using ,而应xcodebuild -exportArchive改为使用
pablobart

1
PROVISIONING_PROFILE_SPECIFIER如果您切换到手动配置...,将无法使用...
wolffan

2

我正在考虑这里没有提到的另一种选择。设置两个相同的目标,只是它们的签名设置不同。

  • 当添加新设备/开发人员时,Development Target使用自动签名来获得所有这些好处。
  • CI Target使用手动签名

缺点是您必须管理两个相同的目标。好处是可以得到自动签名进行开发的好处,而不必维护可能脆弱的脚本,这些脚本会在构建之前就修改您的项目。


2

如果您将Xcode 8.x和Jenkins用于CI。然后,您可能会遇到“为“ YourProjectName”签名”需要开发团队的问题。在项目编辑器中选择一个开发团队。

SDK'iOS 10.1'中产品类型为'Application'的用户必须进行代码签名。**运行失败时,构建失败**。

解决办法是什么?。

解决方法是:

  1. 在Xcode项目构建设置中将Provisioning配置文件设置为None。

  2. 在jenkins中,在Xcode设置之前创建执行外壳,并编写以下命令

    sed -i '' 's/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/' ProjectName.xcodeproj/project.pbxproj 
    

    切记:请在jenkins的Build部分中的Xcode设置之前保留该执行外壳。

这有效。



0

我注意到我的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     */;
                };
            };
        };

然后,我创建了代码以复制上面看到的文件的“结构”。(使用此处找到的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 "";
}


-1

有一个名为fastlane的工具,它使使用xcodebuild更加容易并且得到维护,这意味着新的更新将继续为对xcode的更改提供支持。在支持的许多其他xcode自动化工具中,它使创建用于构建和对应用程序进行代码签名的脚本和配置变得更加容易。我建议您仔细看看。


3
fastlane以及声称可以自动消除所有这些复杂性的任何其他工具,都会给您带来一个您不了解的黑匣子。它们可以正常工作,直到它们中断为止,然后您需要弄清楚代码签名和Fastlane流程如何工作。
铝箔

任何搜索两秒钟的人都知道快速通道,比赛和体育馆,这些都是非常复杂的解决方案,会带来很多自己的问题。我在Fastlane和Match中的经验是,您的项目需要设置为本地手动签名,这在许多情况下是不可接受的。
乌鸦
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.