首页 文章

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

提问于
浏览
72

随着Xcode 8的发布,Apple推出了一种管理签名配置的新方法 . 现在您有两个选项 ManualAutomatic .

根据WWDC 2016 Session 关于代码签名(WWDC 2016 - 401 - What's new in Xcode app signing),当您选择 Automatic 签名时,Xcode将:

  • 创建签名证书

  • 创建和更新应用程序ID

  • 创建和更新配置文件

但根据Apple在该会话中的说法, Automatic Signing 将使用 Development signing ,并将仅限于Xcode创建的配置文件 .

当您尝试在CI环境(如Travis CI或Jenkins)上使用 Automatic Signing 时,会出现此问题 . 我无法找到一种简单的方法来继续使用自动和签署分发(因为Xcode强制您使用开发和Xcode创建的配置文件) .

新的"Xcode-created provisioning profiles"没有显示在开发人员门户中,虽然我可以在我的机器中找到...我应该将这些配置文件移动到CI机器,构建 Development 并导出 Distribution ?有没有办法使用 xcodebuild 覆盖 Automatic Signing

8 回答

  • 1

    我使用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>
    

    Example of an 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)

    无论如何,这个过程更接近你手动使用Xcode,而不是像Jenkins Xcode插件那样 .

    Note: The .xcarchive file will always be develpment signed, but selecting "app-store" as method in the 2nd step will do the correct distribution signing and also include the distribution profile as "embedded.mobileprovision".

    希望这可以帮助 .

  • 2

    尝试了几个选项后,这些是我能够在CI服务器上使用的解决方案:

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

    使用 Automatic signing 强制您使用 Developer 证书和 auto-generated provisioning profiles . 一种选择是将开发证书和私钥(应用程序 - >实用程序 - >密钥链访问)和自动生成的配置文件导出到CI计算机 . 找到自动生成的配置文件的方法是导航到 ~/Library/MobileDevice/Provisioning\ Profiles/ ,将所有文件移动到备份文件夹,打开Xcode并存档项目 . Xcode将创建自动生成的开发配置文件,并将它们复制到 Provisioning Profiles 文件夹 .

    xcodebuild archive ... 将为 Development 创建一个 .xcarchive 签名 . xcodebuild -exportArchive ... 然后可以为 Distribution 重新构建构建

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

    在调用 xcodebuild 之前,解决方法是在项目文件中用 ProvisioningStyle = Manual 替换 ProvisioningStyle = Automatic 的所有实例 . 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 ,它们将覆盖项目中设置的代码签名标识和/或配置文件 .

    编辑:使用Xcode 9,xcodebuild有一个新的构建设置参数CODE_SIGN_STYLE,可以在自动和手动之间进行选择,因此无需在项目文件中查找和替换自动和手动的实例,WWDC 2017中的更多信息会话403签名的新内容用于Xcode和Xcode Server

    切换到手动签名

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

    要了解有关使用Xcode 8进行代码签名的更多信息,我真的推荐这个article以及WWDC2016会话401 - What's new in Xcode app signing

  • 59

    我正在考虑另一种我尚未在此提及过的选择 . 设置两个相同目标,只有他们的签名设置不同 .

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

    • CI Target 使用手动签名

    缺点是您必须管理两个相同的目标 . 好处是获得自动签名开发的好处,并且不必维护可能在构建时间之前修改项目的脆弱脚本 .

  • 0

    如果您使用Xcode 8.x和Jenkins进行CI . 那么可能你会遇到“签署”你的项目名称的问题“需要一个开发团队 . 在项目编辑器中选择一个开发团队 .

    SDK“iOS 10.1”中的产品类型“应用”需要代码签名 . 运行作业时 Build 失败 .

    解决办法是什么? .

    解决方案是:

    • 在Xcode项目构建设置中将供应配置文件设置为无 .

    • 在jenkins中,在Xcode设置之前创建一个执行shell并编写以下命令

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

    记住:在jenkins的Build部分中的Xcode设置之前保持执行shell .

    这有效 .

  • 2

    对我来说,没有任何效果 . 我通过更改Mac Mini(带Jenkins的CI服务器)上安装的Xcode应用程序中的文件解决了我的问题,如以下链接所示:
    https://www.jayway.com/2015/05/21/fixing-your-ios-build-scripts/
    另外,我关闭了Xcode的自动签名 .

    全部完成!终于有效!

  • 0

    我注意到我的Unity构建从未向我的XCode项目添加ProvisioningStyle键 . 然后我找到了一种使用“PostProcessBuild”构建脚本手动添加ProvisioningStyle的方法 . 即在Unity构建IOS XCode项目之后调用的代码单元 .

    首先,我看一下project.pbxproj文件应该是什么样子 - 当它设置为Manual Provisioning时:

    /* Begin PBXDictionary section */
        29B97313FDCFA39411CA2CEA /* Project object */ = {
            isa = PBXProject;
            attributes = {
                TargetAttributes = {
                    1D6058900D05DD3D006BFB54 /* Unity-iPhone */ = {
                        ProvisioningStyle = Manual;
                    };
                    5623C57217FDCB0800090B9E /* Unity-iPhone Tests */ = {
                        TestTargetID = 1D6058900D05DD3D006BFB54 /* Unity-iPhone     */;
                    };
                };
            };
    

    然后我创建了我的代码来复制上面看到的文件的"structure" . (使用此处的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 "";
    }
    
  • 0

    为我修好的是:http://code-dojo.blogspot.jp/2012/09/fix-ios-code-signing-issue-when-using.html

    ...将证书从登录钥匙串复制到系统钥匙串 . 您可能还希望将所有开发证书设置为“允许所有应用程序访问此项目”(右键单击/获取信息/访问控制) .

  • 35

    有一个名为fastlane的工具,它使得使用xcodebuild变得更加容易,并且维护它意味着新的更新将继续为xcode的更改提供支持 . 它使创建脚本和配置变得更加容易,可以在其支持的许多其他xcode自动化工具中构建和协调您的应用程序 . 我建议你去看看吧 .

相关问题