gpt4 book ai didi

macos - macOS:在脚本中公证?

转载 作者:行者123 更新时间:2023-12-03 23:31:36 51 4
gpt4 key购买 nike

由于Xcode的代码签名和存档非常耗时,枯燥且有问题,因此我一直通过自己的脚本使用命令行工具xcodebuildcodesign等对我的开发人员ID签名的macOS应用进行代码签名,存档和交付。公证看起来将是一个巨大的痛苦。可以在我的脚本中添加公证吗?

最佳答案

是。不幸的是,official answer留下了一些松散的末端,例如this important tidbit from Quinn "the Eskimo"。这是操作方法:

一次性设置

获取特定于应用程序的密码

确定公证应用的“应用”的名称。我使用产品运输脚本的名称SSYShipProduct.pl,因为这是将使用此密码的“应用程序”。我们将把您撰写的任何名称都称为your-notarizing-name。

浏览到https://appleid.apple.com/account/manage,滚动到“安全性”>“特定于应用程序的密码”,然后为名为your-notarizing-name的应用程序生成特定于应用程序的密码。复制它提供给您的密码。我们将其称为应用专用密码。

将特定于应用程序的密码添加到您的macOS钥匙串(keychain)

运行以下命令以将刚刚创建的密码添加到钥匙串(keychain)中:
security add-generic-password -a "your-apple-ID-email" -w "app-specific-password" -s "your-notarizing-name"-s参数是此项目将在您的钥匙串(keychain)中使用的名称。我认为您实际上可以使用其他名称,但是在我看来,在此处也使用your-notarizing-name是有意义的。

您可以通过在“钥匙串(keychain)访问”应用程序中搜索来验证它是否有效。但是,请注意,直到退出并重新启动后,新项目才会在“钥匙串(keychain)访问”中列出。

也许,获取相关的itc提供者

如果您的Apple ID与一个以上的Apple Developer Connection团队相关联(例如,如果您从事契约(Contract)工作),则需要该应用程序经过公证的团队的itc_provider。

要找到您团队的itc_provider,请执行以下命令:
/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/itms/bin/iTMSTransporter -m provider -u "your-apple-ID-email" -p "app-specific-password"
滚动到此命令输出的输出的末尾,然后查看提供者列表。复制所需团队的简称。我们将其称为“developer-team-itc-provider”。

对于每次装运(可编写脚本!)

如果您使用/usr/bin/codesign命令行工具对应用程序的组件进行签名,则每次对codesign的调用都必须具有以下新的parameter参数,该参数告诉codesign使用所谓的强化运行时进行签名:

 `--options runtime`

相反,如果您的应用程序已在Xcode中签名,则必须在所有可执行组件目标中将Xcode 10或更高版本中可用的“Build Setting Hardened”运行时设置为"is"。

除此之外,与公证前的日子一样,您的脚本应在发布配置中创建应用的构建并对其进行代码签名。

上载到Apple公证服务

然后,您的脚本应将您的应用程序归档到.zip或.dmg。请注意,这是一个临时文件,仅会上传到Apple Notary服务,而不附带。

然后,您的脚本应组成一个主要的 bundle 包ID值,该值将是您应用程序的 bundle 包标识符,并附加了 .zip.dmg。例如:your-pbid-value = com.mycompany.YourApp.zip

接下来,您的脚本将使用 altool,这是Apple的Application Loader Tool的名称。

然后,您的脚本应运行以下命令以对.zip或.dmg进行公证:
/usr/bin/xcrun altool --notarize-app --primary-bundle-id "your-pbid-value" --username "your-apple-id-email" --password "@keychain:your-notarizing-name" -itc_provider "developer-team-itc-provider" --file /path/to/YourApp.zip/or/YourApp.dmg --output-format "xml"
(请注意,在上面的命令中,奇怪的是,所有参数名称都以两个破折号开头,但 -itc_provider仅以一个破折号开头。此外,如果您使用的脚本语言在字符串中内插 @字符,请对其进行编码以防止对 @keychain进行内插)。

大约一分钟后, xcrun将退出并打印到标准输出一些XML,如果您的提交被接受(注意:尚未批准),它将类似于以下示例:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>notarization-upload</key>
<dict>
<key>RequestUUID</key>
<string>2ab59b26-19ec-4a30-84cf-6d2cb8d3c97e</string>
</dict>
<key>os-version</key>
<string>10.15.0</string>
<key>success-message</key>
<string>No errors uploading 'path/to/YourApp.zip'.</string>
<key>tool-path</key>
<string>/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework</string>
<key>tool-version</key>
<string>1.1.1138</string>
</dict>
</plist>

您真正需要的就是 RequestUUID值。但是,由于我经常发布四个应用程序,并且由于我的发布脚本失败而又没有提供有用的错误信息,这毁了我的一天,并且由于(请参见下文)您将要进行另一个调用并返回有趣的XML,因此我花了一些时间在我的脚本中添加了一个子例程,该子例程带有两个参数,即XML和一个密钥路径,并在给定的密钥路径下返回XML的值。在上述情况下,我调用此子例程以获取 RequestUUID,然后再次获取 success-message

(我的脚本在Perl中。尽管CPAN中有一个名为XML::Simple的模块,可以在一两行中进行此解析,但维护人员将其标记为不用于新设计。因此,避免了需要要使用真正的XML解析器进行安装和处理,我选择使用@khuttun的注释中建议的 PlistBuddy。这有点痛苦,因为不幸的是, altool无法选择将其输出写入文件,而 PlistBuddy未记录为接受stdin。因此,我的子例程将odt_code中的stdout写入临时文件,然后将该临时文件的路径传递给PlistBuddy。有点令人作呕,但可以。)

删除未装订的zip软件包

此时,我建议您的脚本删除其上载的 altool.zip文件。原因:该文件是从尚未装订公证单的产品中存档的。在脚本的最后,您将从具有票证的修改后的应用程序中创建一个新的 .dmg.zip。立即删除文件可防止您错误地运输未装订的应用程序。

等待循环中苹果的回应

然后,通过循环运行以下命令并进行一些睡眠,您的脚本可以开始为您的最终结果困扰Apple的服务器:

`/ usr / bin / xcrun altool --notarization-info --username“your-apple-id-email” --password“@keychain:your-notarizing-name”-输出格式“xml”

如果您的脚本立即运行此命令,它将在stdout中返回一些xml,看起来像下面的示例:
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>notarization-info</key>
<dict>
<key>Date</key>
<date>2019-08-07T01:17:37Z</date>
<key>RequestUUID</key>
<string>4ba71353-9d99-4b52-b579-37f384717130</string>
<key>Status</key>
<string>in progress</string>
</dict>
<key>os-version</key>
<string>10.15.0</string>
<key>success-message</key>
<string>No errors getting notarization info.</string>
<key>tool-path</key>
<string>/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework</string>
<key>tool-version</key>
<string>1.1.1138</string>
</dict>
</plist>

其中的重要密钥路径是 .dmg,其值 notarization-info:Status表示Apple仍在处理您的提交。通常在几分钟后(Apple说“应该少于一个小时”,但是我在2019年7月4日美国假日下午经历了长达三个半小时的时间), in progress将以不同的方式返回到您的脚本xml在stdout中,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>notarization-info</key>
<dict>
<key>Date</key>
<date>2019-08-06T23:28:25Z</date>
<key>LogFileURL</key>
<string>https://osxapps-ssl.itunes.apple.com/itunes-assets/Enigma113/v4/f6/09/be/f609bee3-b031-323a-0987-d1f620a78758/developer_log.json?accessKey=1565410613_1722173034418364591_TvycjBAzd6FRTYGKZEFU6EwDfsws8Wa1MV%2FYnTiJ1zyOZamc%2FoeO5RMeIzZN669ZQJgO2Q4W48ipKNFO%2BQGuq%2FITXN8MQAetbNe90w9ogzqXbrzTHg%2FgYK89yvEFmiiRxhaVlZqLI93NBpY0hwBqXv2bvvlg%2FRCc%2BVaCNRJ%2BrnE%3D</string>
<key>RequestUUID</key>
<string>07fc3745-b0ff-4d1a-9b15-37f384717130</string>
<key>Status</key>
<string>success</string>
<key>Status Code</key>
<integer>0</integer>
<key>Status Message</key>
<string>Package Approved</string>
</dict>
<key>os-version</key>
<string>10.15.0</string>
<key>success-message</key>
<string>No errors getting notarization info.</string>
<key>tool-path</key>
<string>/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework</string>
<key>tool-version</key>
<string>1.1.1138</string>
</dict>
</plist>

经过一些反向工程后,您会看到,在每个循环迭代中,只要 altool的值不是 Status,或者如果愿意,则在定义 in progress时,脚本应该解析XML并退出循环。或者,如果您更喜欢电子邮件触发器,则脚本可以查找主题行来自Apple的电子邮件。现在,您可以分发Mac软件。

更新2019-11-02

在最后几批发货中以及今天再次遇到问题后,我现在确认了Apple的Notary Service中的错误。该错误是 LogFileURL命令将在1-5小时内失败,返回非零退出代码,并且在stdout中显示错误代码1519“找不到RequestUUID”,如以下示例stdout中所示:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>os-version</key>
<string>10.15.1</string>
<key>product-errors</key>
<array>
<dict>
<key>code</key>
<integer>1519</integer>
<key>message</key>
<string>Could not find the RequestUUID.</string>
<key>userInfo</key>
<dict>
<key>NSLocalizedDescription</key>
<string>Could not find the RequestUUID.</string>
<key>NSLocalizedFailureReason</key>
<string>Apple Services operation failed.</string>
<key>NSLocalizedRecoverySuggestion</key>
<string>Could not find the RequestUUID.</string>
</dict>
</dict>
</array>
<key>tool-path</key>
<string>/Applications/Xcode.app/Contents/SharedFrameworks/ContentDeliveryServices.framework/Versions/A/Frameworks/AppStoreService.framework</string>
<key>tool-version</key>
<string>4.00.1181</string>
</dict>
</plist>

这是一个错误,因为我的脚本当然确实提交了刚刚从Apple Notary Service收到的Request UUID,Apple应该能够找到它,此外,当我不断手动发送命令后,大约2个小时后,该命令返回 altool --notarization-info,并继续使用后续命令返回 Success,我从Apple收到了成功电子邮件。今天发生的延迟有7个不同的良好Request UUID,最长为5小时。可能在这时,Apple Notary Service创建和向您发送请求UUID之间存在1-5小时的延迟,并且该延迟出现在数据库中,Apple Notary Service用于响应 Success请求,因此您会收到此错误消息。很伤心

由于无法控制Apple何时分配人员来修复错误,因此我修改了脚本的这一阶段,以解析Apple的响应,并且仅在命令返回非零退出状态以及第一个(index = 0) notarization-infocode时死亡数组条目不是1519。如果您使用PlistBuddy照原样解析XML,则其关键路径是code应当是 product-errors。每当收到错误1519时,脚本中的循环都会打印,因此我可以看到发生了什么,当然,我修改了它的 product-errors:0:code条件,以使错误代码为1519时不退出。

修改完脚本后,我发布了几个应用程序。 Apple Notary Service很好地对待了第一个:No Error 1519,大约两分钟后成功。但是,下一个需要我脚本的新功能。在时间09:54(HH:mm),我的脚本收到了Apple的Request UUID。 20秒后,它发送了第一个 while查询。响应是错误的错误1519。后续查询也返回错误的错误1519,持续了将近3个小时,直到12:44。然后,在12:45,它突然收到了 altool --notarization-info响应。经过5次 in progress响应后,终于在12:47成功。

离开本主题之前的另一件事:该请求成功执行一个小时,没有出现错误1519,一个小时前的先前请求突然开始返回 in progress,然后几分钟后返回成功。结论:绕开到错误1519困惑中的请求UUID不会与以后的请求UUID一起排队在FIFO中,后者可能会避免错误1519绕道。因此,更好的解决方法可能是在收到另一个错误1519响应后放弃请求UUID,然后通过将应用程序重新上载到Apple Notary Service重新开始,并获取另一个您希望更好的请求UUID。当然,在接下来的几个小时内,您将收到许多电子邮件,因为您放弃的所有请求UUID最终都会成功。

无论如何,现在,继续执行脚本的下一步……

检查苹果的日志文件

您的脚本应该解析 in progress的值,以便可以检查日志,因为即使公证成功,Apple创建的日志文件也可能包含警告。要获取日志文件,您的脚本当然应该
curl <LogFileURL-Value>

日志文件显然是JSON。警告或错误以数组形式显示,它是键 LogFileURL的值。因此,您的脚本应使用JSON解析器解析该 issues输出,并且如果键 curl的值是JSON空值或空数组,请继续发货。

订票到您的应用程序

这一步很容易...
xcrun stapler staple /path/to/YourApp.app

运行此命令会将一个新文件添加到您的应用程序包中: issues。这显然是您的公证单。请注意,此文件是 YourApp.app/Contents/CodeResources文件的补充,后者仍然存在,并且包含代码签名,与公证前的日期相同。

验证票证装订

但是,有一种更好的方法来验证您的应用程序现在是否具有良好的票证。您的脚本现在应该运行(或重新运行)Gatekeeper检查:
spctl -a -v /path/to/YourApp.app

在stderr中,结果应该是,
/path/to/YourApp.app: accepted
source=Notarized Developer ID

除了插入经过公证的文件外,这与预公证的结果相同。如果未检测到上述单词,则精明脚本将解析该stderr并中止发货。

邮递

现在已经添加了票证,您的脚本可以再次对.app进行zip或dmg的管理,但这一次,将其发送出去。

关于macos - macOS:在脚本中公证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56890749/

51 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com