使用 App Center CLI 发布 CodePush 更新

安装

  • 安装 Node.js
  • 安装 App Center CLI: npm install -g appcenter-cli

入门

  1. 创建 App Center帐户 ,或者使用 命令通过 CLI appcenter login 登录。
  2. 使用 CodePush 注册应用,并选择性地与团队 中的其他开发人员 共享应用。
  3. CodePush-ify 应用,并指向要用于 (Apache Cordova React Native) 。
  4. 发布和更新应用

帐户管理

在开始发布应用更新之前,使用现有的 CodePush 帐户登录或创建新的 App Center帐户。 安装 CLI 后,可以通过运行以下命令来完成此操作:

appcenter login

此命令将启动浏览器,要求使用 GitHub 或 Microsoft 帐户。 进行身份验证后,它将创建一个"链接到 GitHub/MSA 标识"的 CodePush 帐户,并生成一个访问密钥,你可以复制/粘贴到 CLI 中以登录。

备注

注册后,会自动使用 CLI 登录,因此,在显式注销之前,不必再次从同一台计算机登录。

身份验证

CLI 中的大多数App Center都需要身份验证,因此,在可以开始管理帐户之前,使用注册时Microsoft 帐户 GitHub 或帐户登录。 为此,可以执行以下命令:

appcenter login

此命令将启动一个浏览器窗口,要求你向 GitHub 或 Microsoft 帐户。 它将生成一个访问密钥以复制粘贴到 CLI (它会提示你输入) 。 现已成功进行身份验证,可以安全地关闭浏览器窗口。

每当要检查是否已登录时,都可以运行以下命令来显示当前身份验证会话的电子邮件地址、用户名和显示名称:

appcenter profile list

当你从 CLI 登录时,你的访问密钥将在会话期间一直保留在磁盘上,这样你就不必在每次尝试访问帐户时登录。 若要结束会话并删除此访问密钥,请执行以下命令:

appcenter logout

如果忘记从计算机注销,而不希望在 (上保留正在运行的会话,例如,朋友的便携式计算机) ,可以使用以下命令列出并删除任何当前登录会话。

appcenter tokens list
appcenter tokens delete <machineName>

访问令牌

若要在不启动浏览器的情况下对 CodePush 服务进行身份验证,或者不需要使用 GitHub 或 Microsoft 凭据 (例如,在 CI 环境) 中,你可以执行以下命令来创建 "访问令牌" (,以及描述它的) 的名称:

appcenter tokens create -d "Azure DevOps Integration"

该键只显示一次,因此,如果需要,请记住将其保存到某个位置。 创建新密钥后,可以使用命令标志指定其值 --token login ,这允许你使用 "无外设" 身份验证,而不是启动浏览器。

appcenter login --token <accessToken>

使用此方法登录时,访问令牌不会在退出时自动失效,并且可以在未来的会话中使用,直到从 App Center 服务器中显式删除。 但是,一旦会话完成,你应 signout 从磁盘中删除凭据。

应用管理

在部署更新之前,使用以下命令 App Center 创建应用程序:

appcenter apps create -d <appDisplayName> -o <operatingSystem>  -p <platform> 

如果你的应用面向 Android 和 iOS,我们强烈建议通过 CodePush 创建单独的应用。 每个平台一个。 这样一来,你可以单独管理和发布对它们的更新,这种情况下,这会使任务更简单。 大多数人会在应用名称后加上 -Android-iOS 。 例如:

appcenter apps create -d MyApp-Android -o Android -p React-Native
appcenter apps create -d MyApp-iOS -o iOS -p Cordova

备注

对 Android 和 iOS 使用相同的应用可能会导致安装异常,因为为 iOS 生成的 CodePush 更新包将与为 Android 生成的更新中的内容不同。

提示

App Center CLI 中的一个重要新功能是能够使用将应用设置为 当前应用 appcenter apps set-current <ownerName>/<appName> 。 通过将应用程序设置为当前应用程序,你无需 -a 在其他 CLI 命令中使用该标志。 例如,在 appcenter codepush deployment list -a <ownerName>/<appName> appcenter codepush deployment list 设置当前应用程序时,可以将命令缩短到。 你可以使用来检查将哪个应用设置为帐户的当前应用 appcenter apps get-current 。 设置当前应用会使键入的大多数 CLI 命令更短。

对于原始 CodePush,应用会自动 (和) 两个部署 Staging Production 。 在 App Center 中,你必须使用以下命令自行创建它们:

appcenter codepush deployment add -a <ownerName>/<appName> Staging
appcenter codepush deployment add -a <ownerName>/<appName> Production

创建部署后,你可以使用访问这两个部署的部署密钥 appcenter codepush deployment list --displayKeys ,你可以开始使用通过其各自的 sdk 来配置移动客户端 (Cordova 的详细信息以及对 本机) 做出反应

如果你决定不喜欢应用的名称,可以使用以下命令随时对其进行重命名:

appcenter apps update -n <newName> -a <ownerName>/<appName>

应用的名称仅可从管理端识别,因此,在必要时可随意将其重命名。 它不会影响正在运行的应用程序,因为通过部署密钥进行的更新查询。

如果不再需要某个应用,可以使用以下命令从服务器中删除它:

appcenter apps delete -a <ownerName>/<appName>

执行此命令时要小心,因为已配置为使用它的任何应用程序都将停止接收更新。

最后,如果想要列出已注册到 App Center 服务器的所有应用,请运行以下命令:

appcenter apps list

应用协作

如果要在同一 CodePush 应用上使用其他开发人员,则可以按照以下说明集,使用 App Center 门户将其添加为协作者:

  1. 在 App Center 门户中,选择要为其添加协作者的应用
  2. 在页面左侧的导航区域中,单击 "设置"
  3. 单击 " 协作 者" 链接
  4. 在 "协作者" 菜单中,输入要邀请的协作者的电子邮件地址。

重要

App Center协作者功能要求每个协作者已使用 App Center电子邮件地址向 用户注册。

添加后,所有协作者将立即在共享应用中具有以下权限:

  1. 查看应用、其协作者 、部署发布历史记录
  2. 发布 对应用的任何部署的更新
  3. 在任何 应用部署之间提升更新
  4. 回滚 应用的任何部署
  5. 修补 任何应用部署内的任何版本

协作者不能执行以下操作之一:

  1. 重命名或删除应用
  2. 在应用中创建、重命名或删除新部署
  3. 清除部署的发布历史记录
  4. 在应用中添加或删除协作者 (*)

备注

开发人员可以从与自己共享的应用中删除他/自己作为协作者。

随着时间的推移,如果有人不再与你在一起处理应用,则还可以在门户中使用此协作者菜单将其删除为协作者。

每当要列出已添加到应用的所有协作者时,都可以访问门户中的协作者菜单。

部署管理

从 CodePush 的角度来看,应用是一个或多个"部署"的命名分组。 虽然应用代表特定于平台的应用 (版本(例如,Foo 应用) 的 iOS 端口)的概念性"命名空间"或"范围",但应用的部署表示为开发人员发布更新 () 和同步最终用户) 更新 (的实际目标。 部署允许你在任何给定时间为每个实时应用设置多个"环境",并帮助为应用通常从开发人员的个人环境移动到测试/QA/过渡环境这一现实建模,最后进入生产环境。

备注

如下所示, releasepromoterollback 命令要求应用名称和部署名称均可供使用,因为它是唯一标识分发点的两者的组合 (例如,我想要将我的 iOS 应用程序的更新) 。

每当向 CodePush 服务注册应用时,我们建议你创建以下部署: StagingProduction 。 这样,你就可以开始向内部环境发布更新,在这种情况下,你可以在将更新推送到最终用户之前对每个更新进行全面测试。 此工作流对于确保您的发布已准备好进行大容量消耗非常重要,并且是在 web 中很长一段时间内建立的一种做法。

如果你的应用程序的过渡和生产版本足以满足你的需求,则无需执行任何其他操作。 但是,如果你想要使用 alpha、开发等部署,则可以使用以下命令轻松创建它们:

appcenter codepush deployment add -a <ownerName>/<appName> <deploymentName>

与应用类似,还可以删除和重命名部署,分别使用以下命令:

appcenter codepush deployment remove -a <ownerName>/<appName> <deploymentName>
appcenter codepush deployment rename -a <ownerName>/<appName> <deploymentName> <newDeploymentName>

无论何时想要查看特定应用包含的部署列表,你都可以运行以下命令:

appcenter codepush deployment list -a <ownerName>/<appName>

安装指标具有以下含义:

  • 活动 -当前正在运行此版本的成功安装的数目 (如果用户打开了应用,他们将看到/运行此版本) 。 最终用户升级到和离开此版本时,此数字会发生变化。 此指标显示活动用户总数以及表示的所有受众的百分比。 这样,便可以轻松确定用户当前正在运行的更新的分发情况,并回答诸如 "我的用户已收到我的最新更新有多少?" 等问题。

  • Total -此更新整体接收到的成功安装总数。 此数字只会随着新用户/设备的安装而增加,因此它始终是总活动计数的超集。 安装更新后,如果 (或) notifyApplicationReady sync 调用更新,则认为更新成功。 在下载更新并标记为成功的那一刻起,它将报告为"挂起"更新 (有关详细信息,请参阅) 。

  • 挂起 - 此版本已下载但尚未安装 (重启应用以应用更改) 。 因此,此指标会随着下载更新而增加,并随着安装这些相应的已下载更新而减少。 此指标主要适用于未配置为立即安装的更新,并且有助于为依赖于应用恢复或重启以应用更新的应用提供更广泛的版本采用情况 (例如,我想要回滚更新,并且我想知道是否有人下载了更新) 。 如果已将更新配置为立即安装,但仍看到挂起的更新被报告,则很可能未在应用启动时调用 (或) ,这是开始发送安装报告并标记为成功安装更新 notifyApplicationReady sync 的方法。

  • 回滚 - 此版本在客户端上自动回滚的时间。 理想情况下,此数字应为零,在这种情况下,甚至不会显示此指标。 但是,如果在安装过程中发布了包含崩溃的更新,则 CodePush 插件将最终用户回滚到以前的版本,并报告该问题回服务器。 这样,最终用户就可以在版本中断时保持未阻止状态,并且可以通过在 CLI 中查看此遥测数据来识别错误的发布,并在服务器上回滚来响应它们。

  • 推出 - 指示有资格接收此更新的用户的百分比。 此属性将只针对表示"主动"推出版本显示,因此推出百分比小于 100%。 此外,因为在任何给定时间,部署只能有一个活动的推出,所以此标签仅存在于部署中的最新版本。

  • 禁用 -指示发布是否已标记为已禁用,因此,最终用户可下载此版本。 仅为已禁用的发布显示此属性。

度量值单元报告时 No installs recorded ,指示服务器未发现此版本的任何活动。 这可能是因为它排除包含遥测支持的插件版本,或尚未将最终用户与 CodePush 服务器同步。 一旦安装发生,就会开始看到指标填充到发布的 CLI 中。

发布更新

一旦你的应用程序已配置为针对 App Center 服务器查询更新,你就可以开始向其发布更新。 为了同时提供简单和灵活性,App Center CLI 包含三个不同的命令用于发布更新:

  1. 常规 -发布由外部工具或生成脚本生成的 App Center 服务器的更新 (例如,Gulp 任务 react-native bundle) 。 这为在现有工作流中提供了最大的灵活性,因为它严格地处理 CodePush 特定的步骤,并将特定于应用程序的编译过程留给你。

  2. 响应本机 -使用与常规 release 命令相同的功能,但还会处理为你 (JS 束和资产) 生成更新的应用内容的任务,而不是要求你运行 react-native bundleappcenter codepush release

  3. Cordova -使用与常规 release 命令相同的功能,但还处理为你准备应用更新的任务,而不是要求你运行 cordova prepare (或 phonegap prepare) ,然后运行 appcenter codepush release

应该使用的以下命令中的哪一种是要求或首选项。 但是,我们建议使用特定于平台的相关命令来启动 (因为它极大地简化了) 体验,然后在需要更大控制时/使用常规 release 用途命令。

备注

客户端只能发现和下载部署中的 50 个最新版本。

发布常规 (更新)

appcenter codepush release -a <ownerName>/<appName> -c <updateContentsPath> -t <targetBinaryVersion> -d <deploymentName>

[-t|--target-binary-version <version>]
[-с|--update-contents-path <updateContentsPath>]
[-r|--rollout <rolloutPercentage>]
[--disable-duplicate-release-error]
[-k|--private-key-path <privateKeyPath>]
[-m|--mandatory]
[-x|--disabled]
[--description <description>]
[-d|--deployment-name <deploymentName>]
[-a|--app <ownerName>/<appName>]
[--disable-telemetry]
[-v|--version]

应用名称参数

此参数指定要发布App Center的应用的名称。 如果要查找它,可以运行 appcenter apps list 命令来查看应用列表。

更新 contents 参数

此参数指定要发布的已更新应用代码和资产的位置。 可以提供单个文件 (例如,React Native 应用) 的 JS 捆绑包,或指向目录的路径 (例如 /platforms/ios/www Cordova 应用文件夹) 。 不必压缩多个文件或目录来部署这些更改,因为 CLI 会自动压缩这些更改。

指定的路径必须引用应用特定于平台的已准备/捆绑版本。 下表概述了在发布之前应运行的命令,以及稍后可以使用 参数引用 updateContentsPath 的位置:

平台 Prepare 命令 相对于 (根目录的包)
Cordova (Android) cordova prepare android ./platforms/android/assets/www 目录
Cordova (iOS) cordova prepare ios ./platforms/ios/www 目录
React Native Android (wo/assets) react-native bundle --platform android --entry-file <entryFile> --bundle-output <bundleOutput> --dev false 选项 --bundle-output 的值。
React Native Android (中) react-native bundle --platform android --entry-file <entryFile> --bundle-output <releaseFolder>/<bundleOutput> --assets-dest <releaseFolder> --dev false 选项的值,它应表示新创建的目录,其中包括 --assets-dest 应用的资产和 JS 捆绑包
React Native iOS (wo/assets) react-native bundle --platform ios --entry-file <entryFile> --bundle-output <bundleOutput> --dev false 选项 --bundle-output 的值
React Native iOS (/assets) react-native bundle --platform ios --entry-file <entryFile> --bundle-output <releaseFolder>/<bundleOutput> --assets-dest <releaseFolder> --dev false 选项的值,它应表示新创建的目录,其中包括 --assets-dest 应用的资产和 JS 捆绑包

目标二进制版本参数

此参数指定要发布更新的应用程序的存储区/二进制版本,以便只有运行该版本的用户才能接收更新,而运行较旧版本或较新版本的应用二进制文件的用户不会收到更新。 它很有用,原因如下:

  1. 如果用户运行的是较旧的二进制版本,则 CodePush 更新中可能会存在与正在运行的内容不兼容的中断性变更。

  2. 如果用户运行的是较新的二进制版本,则假定他们运行的版本较新 (并且可能与 CodePush) 不兼容。

如果希望更新以面向应用商店二进制文件的多个版本,我们还允许将 参数指定为 semver 范围表达式。 这样一来,任何运行二进制文件版本(满足范围表达式 (返回) semver.satisfies(version, range) true 都将获取更新。 有效 semver 范围 表达式的示例如下所示:

范围表达式 谁获取更新
1.2.3 仅运行应用的特定二进制 1.2.3 版本的设备
* 配置为使用 CodePush 应用更新的任何设备
1.2.x 运行主要版本 1、次要版本 2 以及应用的任何修补程序版本的设备
1.2.3 - 1.2.7 在非独占版本与非独占 (1.2.3 版本) (1.2.7 二)
>=1.2.3 <1.2.7 1.2.3 (包含) 和 1.2.7 (独占之间运行任何二进制版本的设备)
1.2 等效于 >=1.2.0 <1.3.0
~1.2.3 等效于 >=1.2.3 <1.3.0
^1.2.3 等效于 >=1.2.3 <2.0.0

备注

如果应用的 semver 表达式以特殊 shell 字符或运算符(如 >^ 或 * * *)开头,并且如果不将值括在引号中,则该命令可能无法正常执行,因为 SHELL 不会向 CLI 进程提供正确的值。 因此,在调用命令时,最好将应用的 targetBinaryVersion 参数封装在双引号中 release ,例如 appcenter codepush release -a <ownerName>/<appName> updateContents ">1.2.3"

下表概述了 CodePush 需要为每个相应的应用类型满足更新的 semver 范围的版本值:

平台 二进制版本的源
Cordova <widget version> config.xml 文件中的属性
响应本机 (Android) android.defaultConfig.versionName项目的 gradle 文件中的属性
响应本机 (iOS) CFBundleShortVersionString Info.plist 文件中的键
响应本机 (Windows) <Identity Version> Appxmanifest.xml 文件中的键

备注

如果元数据文件中的二进制版本缺少修补程序版本(例如), 2.0 则会将其视为具有补丁版本 0 ,即 2.0 -> 2.0.0

部署名称参数

此参数指定要将更新发布到的部署。 它默认为 Staging ,但当你准备好部署到 Production 或你自己的自定义部署中时,只需显式设置此参数。

提示

可以使用或设置参数 --deployment-name -d

Description 参数

此参数为部署提供可选的 "更改日志"。 值被舍入到客户端,以便在检测到更新时,应用程序可以选择将其显示给最终用户 (例如,通过 "新增功能"。 对话框) 。 此字符串接受控件字符(如 和 )以便可以在说明中包括空格格式, \n \t 以提高可读性。

提示

可以使用 设置此参数 --description

已禁用的参数

此参数指定最终用户是否可以下载更新。 如果未指定,将不会禁用更新。 相反,用户将在应用调用 时下载 sync 它。 如果要发布不会立即提供的更新,直到显式修补该更新,并且希望最终用户下载它 (例如,公告博客文章在) 。

提示

可以使用 或 设置此 --disabled 参数 -x

必需参数

此参数指定更新是否被视为必需 (例如,它包含一个关键的安全) 。 此属性会往返给客户端,然后,用户可以决定是否以及如何强制实施此属性。

备注

此参数是一个"标志",因此它的缺失指示发布是可选的,并且它的存在指示它是必需的。 可以为它提供一个值 (例如,) ,但指定 足以将发布 --mandatory true --mandatory 标记为必需。

必需属性是唯一的,因为服务器将根据需要动态修改它,以确保为最终用户维护应用发布的语义。 例如,假设你向应用发布了以下三个更新:

发布 必需?
v1
v2
v3

如果最终用户当前正在运行 ,并且他们查询服务器中的更新,则它会使用 (进行响应,因为这是最新的 v1) ,但它会将发布动态转换为强制版本,因为在这两者之间发布了强制更新。 v3 此行为非常重要,因为 中包含的代码 v3 是增量到 中包含的 v2 。 任何强制要求都继续成为任何未获取 的任何人 v2 v3 的必需项 v2

如果某个最终用户当前正在运行 v2 ,并且他们查询服务器进行更新,则该用户将做出响应 v3 ,但保留发布为可选。 这是因为它们已经收到必需的更新,因此不需要修改的策略 v3 。 此行为的原因是我们说,服务器将 "动态转换" 必需标志,因为在发布版本中,将始终使用在发布时指定的值来存储其强制属性。 仅当响应最终用户的更新检查时,它才会动态更改。

如果你发布标记为的更新,则所述的行为仅适用于你 mandatory 。 如果有混用的更新,服务器将只更改 optional 版本, mandatory mandatory 如下所示。

标记为的发布 mandatory 永远不会转换为 optional

提示

可以使用或设置此参数 --mandatory``-m*

无重复发布错误参数

此参数指定如果更新与部署上的最新版本相同,则 CLI 应生成警告而不是错误。 这对于持续集成方案非常有用,在这种情况下,小型修改可能会触发发布,而不会更改任何生产代码。

推出参数

重要

为了使此参数生效,最终用户必须运行 1.6.0-beta+ Cordova (版本) 或 1.9.0-beta+ (,以响应 CodePush 插件的本机) 。 如果发布了指定推出属性的更新,则没有任何运行较早版本的 Cordova 或对本机插件做出反应的最终用户都有资格进行更新。 除非已采用) 之前提到的特定于平台的 CodePush (插件的必要版本,否则我们不建议在应用的版本上设置推出值,因为没有人会接收到它。

此参数指定 (的用户的百分比,该百分比应为一个介于和) 之间的整数, 1 100 该整数应该符合接收此更新的条件。 如果希望与应用的一部分受众 ((例如 25%) )一起"飞行"新版本,并获取反馈,或者监视异常或崩溃,然后向所有人广泛发布,这非常有用。 如果未设置此参数,则默认为 100% 。 只需设置它,以限制将接收它的用户数。

使用推出功能时,还需要注意一些额外的注意事项:

  1. 无法对最新版本为"活动"推出部署的发布新更新, (其推出属性为非 null) 。 推出需要"完成", (属性设置为) 才能发布对部署的 rollout 进一 100 步更新。

  2. 如果回滚其最新版本为"主动"推出部署的部署,则推出值将被清除,从而有效地"停用"推出行为

  3. 与 和 字段不同,在将发布从一个部署提升到另一个部署时,它不会传播 属性,因此,如果希望目标部署) 中的 mandatory description 新版本 rollout (promote 具有推出值,则必须在调用 命令时显式设置它。

提示

可以使用 或 设置此 --rollout 参数 -r*

发布更新 (React Native)

appcenter codepush release-react -a <ownerName>/<appName> -d <deploymentName> -t <targetBinaryVersion>
[-t|--target-binary-version <targetBinaryVersion>]
[-o|--output-dir]
[-s|--sourcemap-output]
[-c|--build-configuration-name <arg>]
[--plist-file-prefix]
[-p|--plist-file]
[-g|--gradle-file]
[-e|--entry-file]
[--development]
[-b|--bundle-name <bundleName>]
[-r|--rollout <rolloutPercentage>]
[--disable-duplicate-release-error]
[-k|--private-key-path <privateKeyPath>]
[-m|--mandatory]
[-x|--disabled]
[--description <description>]
[-d|--deployment-name <deploymentName>]
[-a|--app <ownerName>/<appName>]
[--disable-telemetry]
[-v|--version]

命令是React Native"vanilla"命令的特定于 React Native 版本,它支持所有相同的参数 (例如 release-react release --mandatory 、) ,但通过执行以下附加任务简化了发布更新 --description 的过程:

  1. 运行 react-native bundle 命令以生成JS (更新内容,并) 发布给 CodePush 服务器的资产。 它尽可能使用合理的默认值 (例如,创建非开发版本,假设 iOS 条目文件名为 index.ios.js) ,但还公开了相关参数以实现灵活性 (例如 react-native bundle --sourcemap-output) 。

  2. targetBinaryVersion使用项目的 info.plist (中指定的版本名称推导此版本的,该版本名称用于 iOS) , Gradle (适用于 Android) 文件。

为了说明该命令可以进行的不同之处 release-react ,下面的示例演示了如何使用 "vanilla" 命令生成并发布响应本机应用程序的更新 release

mkdir ./CodePush

react-native bundle --platform ios \
--entry-file index.ios.js \
--bundle-output ./CodePush/main.jsbundle \
--assets-dest ./CodePush \
--dev false

appcenter codepush release -a <ownerName>/MyApp-iOS -c ./CodePush -t 1.0.0

通过命令实现等效的行为 release-react 需要以下命令,该命令不容易出错:

appcenter codepush release-react -a <ownerName>/MyApp-iOS

应用名称参数

它与 上一节中所述的参数相同。

部署名称参数

它与 上一节中所述的参数相同。

Description 参数

它与 上一节中所述的参数相同。

必需参数

它与 上一节中所述的参数相同。

无重复发布错误参数

它与 上一节中所述的参数相同。

推出参数

它与 上一节中所述的参数相同。 如果未指定,则将向所有用户提供版本。

目标二进制版本参数

它与 上一节中所述的参数相同。 如果未指定,则默认情况下会将应用的 info.plist) (中指定的确切版本设定为适用于 Android 的 gradle (,并将用于 Android) 文件。

束名称参数

此参数指定应用于生成的 JS 捆绑包的文件名。 如果未指定,则标准捆绑包名称将用于指定的平台 :main.js 捆绑包 (iOS ) 、index.android.bundle (Android) 和 index.windows.bundle (Windows) 。

提示

可以使用 或 设置此 --bundle-name 参数 -b*

开发参数

此参数指定是否生成未缩小的开发 JS 捆绑包。 如果未指定,则默认为 false 禁用警告并缩小捆绑包。

提示

可以使用 设置此参数 --development*

已禁用的参数

该参数与上一部分中所述的参数 相同

入口文件参数

此参数指定应用的根/条目 JavaScript 文件的相对路径。 如果未指定,则默认为index.ios.js (for iOS ) 、index.android.js (for Android) 或 index.windows.bundle (for Windows) (如果存在该文件)或 index.js。

提示

可以使用 或 设置此 --entry-file 参数 -e*

Gradle 文件参数 (Android)

此参数指定 CLI 在尝试自动测试发布的目标二进制文件版本时,CLI 应该使用的 build.gradle 文件的相对路径。 此参数仅适用于高级方案,因为 CLI 可以在项目"标准"中自动查找项目的 build.gradle React Native文件。 但是,如果项目的 gradle 文件位于 CLI 无法发现的任意位置,则使用此参数可以继续发布 CodePush 更新,而无需显式设置 参数。 --target-binary-version 由于 build.gradle 是必需文件名,因此指定包含文件夹的路径或文件本身的完整路径都将实现相同的效果。

appcenter codepush release-react -a <ownerName>/MyApp-Android  -g "./foo/bar/"
appcenter codepush release-react -a <ownerName>/MyApp-Android  -g "./foo/bar/build.gradle"

提示

可以使用 或 设置此 --gradle-file 参数 -g*

仅 iOS (Plist 文件)

此参数指定 info.plist 文件的相对路径,CLI 在尝试自动检测版本的目标二进制版本时应使用该文件。 此参数仅适用于高级方案,因为 CLI 可以在 "standard" 中自动找到项目的 info.plist 文件来响应本机项目,并且可以使用 --plistFilePrefix 参数支持每个环境的 info.plist 文件 (例如, info.plist) 。 但是,如果项目的 info.plist 位于任意位置,CLI 无法发现它,则使用此参数可以继续发布 CodePush 更新,而无需显式设置 --target-binary-version 参数。

appcenter codepush release-react -a <ownerName>/MyApp-iOS -p "./foo/bar/MyFile.plist"

提示

可以使用或设置此参数 --plist-file``-p*

Info.plist 文件前缀参数 (仅限 iOS)

此参数指定在尝试为版本自动检测目标二进制版本时,CLI 应使用的 info.plist 文件的文件名前缀。 如果已创建每个环境的 info.plist 文件 (例如, info.plistInfo.plist) ,并且想要发布 CodePush 更新,而无需显式设置参数,这会很有用 --target-binary-version 。 通过指定 --plist-file-prefix ,CLI 将查找名为的文件 <prefix>-Info.plist ,而不是 info.plist (这是默认行为) ,位于以下位置: ./ios./ios/<appName> 。 如果项目的 info.plist 文件不在这两个目录中 (例如,你的应用程序是具有嵌入 RN 视图的本机 iOS 应用) ,或者使用完全不同的文件命名约定,则考虑使用 --plist-file 参数。

# Autodetect the target binary version of this release by looking up the
# app version within the STAGING-Info.plist file in either the ./ios or ./ios/<APP> directories.
appcenter codepush release-react -a <ownerName>/MyApp-iOS  --plist-file-prefix "STAGING"

# Tell the CLI to use your dev plist (`DEV-Info.plist`).
# The hyphen separator can be explicitly stated.
appcenter codepush release-react -a <ownerName>/MyApp-iOS --plist-file-prefix "DEV-"

源映射输出参数

此参数指定生成的 JS 捆绑的源映射文件应写入的相对路径。 如果未指定,则不会生成源映射。

提示

可以使用或设置此参数 --sourcemap-output``-s*

生成配置名称

用于指定要面向此版本的二进制版本的生成配置的名称。 例如,"调试"或"发布" (iOS) 。

备注

使用 Xcode 11 及更高版本进行生成时,应使用此参数来替代 Xcode 使用的默认配置。

发布 Cordova (更新)

appcenter codepush release-cordova -a <ownerName>/<appName> -d <deploymentName> -t <targetBinaryVersion>
[-t|--target-binary-version <targetBinaryVersion>]
[--is-release-build-type]
[-b|--build]
[-r|--rollout <rolloutPercentage>]
[--disable-duplicate-release-error]
[-k|--private-key-path <privateKeyPath>]
[-m|--mandatory]
[-x|--disabled]
[--description <description>]
[-d|--deployment-name <deploymentName>]
[-a|--app <ownerName>/<appName>]
[--disable-telemetry]
[-v|--version]

命令是特定于 Cordova 的"vanilla"命令版本,它支持所有相同的参数 (例如 release-cordova release --mandatory 、) ,但通过执行以下附加任务简化了发布更新 --description 的过程:

  1. 运行 (或) 命令,在 cordova prepare phonegap prepare 将 (到 CodePush 服务器的 ) www 文件夹中生成更新内容。

  2. 通过使用在项目的配置文件中指定的版本名称来推断此版本 targetBinaryVersion config.xml。

为了说明该命令可以产生的差异,以下示例演示如何使用"vanilla"命令为 Cordova 应用生成和 release-cordova 发布 release 更新:

cordova prepare ios
appcenter codepush release -a <ownerName>/MyApp-iOS -c ./platforms/ios/www -t 1.0.0

使用 命令实现等效 release-cordova 行为需要以下命令,这不太容易出错:

appcenter codepush release-cordova -a <ownerName>/MyApp-iOS

应用名称参数

该参数与上一部分中所述的参数 相同

部署名称参数

该参数与上一部分中所述的参数 相同

Description 参数

该参数与上一部分中所述的参数 相同

必需参数

该参数与上一部分中所述的参数 相同

无重复发布错误参数

该参数与上一部分中所述的参数 相同

Rollout 参数

它与 上一节中所述的参数相同。 如果未指定,则将向所有用户提供版本。

目标二进制版本参数

它与 上一节中所述的参数相同。 如果未指定,则该命令默认为仅面向项目的元数据中的指定版本 (info.plist 如果此更新适用于 iOS 客户端,则为 gradle,对于 Android 客户端) 为 。

Disabled 参数

它与 上一节中所述的参数相同。

版本参数

此参数指定在 cordova build cordova prepare 生成已更新的 web 资产时,是要运行 (这是默认行为) 。 如果你的项目包含在生成挂钩之前或之后 (例如,要转译 TypeScript) 等,则运行 CodePush 并 cordova prepare 不足以创建和发布更新。 如果未指定,则默认为 false

提示

可以使用或设置此参数 --build``-b*

修补更新元数据

发布更新后,在某些情况下,你可能想要修改其一个或多个元数据特性 (例如,你忘记将关键 bug 修复标记为必需,你希望提高更新) 的推出百分比。 可以通过运行以下命令轻松完成此操作:

appcenter codepush patch -a <ownerName>/<appName> <deploymentName> <existing-release-label>
[-r|--rollout <rolloutPercentage>]
[-d|--description <description>]
[-t|--target-binary-version <targetBinaryVersion>]
[-a|--app <ownerName>/<appName>]
[--disable-telemetry]
[-v|--version]

备注

此命令不允许修改版本 (的实际更新内容,例如, www Cordova 应用) 的文件夹。 如果要对已被标识为中断的版本做出响应,则应使用 rollback 命令立即将其回滚,然后在必要时使用相应的修复程序发布新的更新(如果有)。

除了和之外 <ownerName>/<appName> deploymentName ,所有参数都是可选的,因此,你可以使用此命令一次更新单个属性或所有参数。 patch在不指定任何属性标志的情况下调用命令将导致不会操作。

# Mark the latest production release as mandatory
appcenter codepush patch -a <ownerName>/MyApp-iOS Production -m

# Increase the rollout for v23 to 50%
appcenter codepush patch -a <ownerName>/MyApp-iOS Production v23 -rollout 50%

标签参数

指示要 (部署) v23 的发布版本。 如果省略,则请求的更改将应用于指定部署中的最新版本。 若要查找要更新的发布的标签,可以运行 appcenter codepush deployment history 命令并引用 Label 列。

必需参数

该参数与上一部分中所述的参数相同,可用于更新发布是否被视为必需版本。 请注意, --mandatory --mandatory true 和 是等效的,但缺少此标志与 不等效 --mandatory false 。 如果省略 参数,则不更改目标发布的必需属性的值。 将此参数设置为 --mandatory false 可显式使发布成为可选版本。

Description 参数

该参数与上一部分中所述的参数相同,可用于更新发布 (的说明,例如,发布时输入了拼写错误,或者忘记了添加) 。 如果省略此参数,则不更改目标发布的 description 属性的值。

已禁用的参数

该参数与上一部分中所述的参数相同,可用于更新是否应禁用发布。 请注意 --disabled--disabled true 等效,但缺少此标志与 不等效 --disabled false 。 如果省略 参数,则不更改目标发布的 disabled 属性的值。 如果将此参数设置为 ,则显式使发布可要求( --disabled false 如果以前已禁用)。

Rollout 参数

该参数与上一部分中所述的参数相同,可用于增加目标发布的推出百分比。 此参数只能设置为其值大于当前推出值的整数。 此外,如果您要 "完成" 部署,并使每个用户都可以使用该发布,则可以将此参数设置为 --rollout 100 。 如果省略此参数,则不会对目标版本的推出参数的值进行任何更改。

另外,如上所述,当你在没有推出值的情况下发布更新时,它的处理方式与将部署设置为等效 100 。 如果在未进行部署的情况下发布更新,则无法通过命令更改其推出属性, patch 因为这会被视为降低推出百分比。

目标二进制版本参数

它与 上一节中所述的参数相同,并允许你更新 semver 范围,以指示版本与兼容的二进制版本。 这对于以下情况很有用:你在最初发布更新时出错 (例如,你已指定 1.0.0 但表示 1.1.0) 或者要增加或减少版本支持的版本范围 (例如,你发现在所有) 后,版本均不起作用 1.1.2 。 如果省略此参数,则不会对目标版本的版本属性的值进行任何更改。

# Add a "max binary version" to an existing release
# by scoping its eligibility to users running >= 1.0.5
appcenter codepush patch -a <ownerName>/MyApp-iOS Staging -t "1.0.0 - 1.0.5"

升级更新

测试针对特定部署的更新后 (例如 Staging) ,并且你想要将其升级为 "下游" (例如,开发 >过渡、暂存 >生产) ,你可以使用以下命令将发布从一个部署复制到另一个部署:

appcenter codepush promote -a <ownerName>/<appName> -s <sourceDeploymentName> -d <destDeploymentName>
[-s|--source-deployment-name <sourceDeploymentName>]
[-d|--destination-deployment-name <destDeploymentName>]
[-t|--target-binary-version <targetBinaryVersion>] 
[-r|--rollout <rolloutPercentage>]
[--disable-duplicate-release-error]
[--description <description>]
[-a|--app <ownerName>/<appName>] 
[--disable-telemetry] 

promote命令为目标部署创建新版本,其中包括源部署最新版本中的 确切代码和元数据 (说明、强制和目标二进制版本) 。 尽管可以使用 release 命令 "手动" 将更新从一个环境迁移到另一个环境,但该 promote 命令具有以下优势:

  1. 它更快,因为不需要重新组合要发布的发布资产,也不必记住源部署发布的说明/二进制版本。

  2. 它不太容易出错,因为提升操作可确保已在源部署中测试的确切项 (例如) 在目标部署中变为活动状态 (例如 Staging Production) 。

建议所有用户利用自动创建的 和环境,并直接对 执行所有发布,然后在适当的测试后从 到 Staging Production Staging promote Staging Production 执行所有发布。

Description 参数

它是与上一部分所述的参数相同的参数,并允许重写将用于提升版本的说明。 如果未指定,则新版本将继承正在提升的版本中的说明。

已禁用的参数

该参数与上一部分中所述的参数相同,并允许重写将用于提升发布的已禁用标志的值。 如果未指定,则新版本将继承正在提升的版本中的已禁用属性。

必需参数

该参数与上一部分中所述的参数相同,并允许重写将用于提升发布的必需标志。 如果未指定,则新版本将继承正在提升的版本中的必需属性。

无重复发布错误参数

该参数与上一部分中所述的参数 相同

Rollout 参数

该参数与上一部分中所述的参数相同,可用于指定新创建的发布是否只应提供给部分用户使用。 不同于其他版本元数据参数 (例如, description) , rollout 版本的不会作为提升的一部分进行转移/继承,因此,如果不希望新创建的版本可供所有用户使用,则必须显式设置。

目标二进制版本参数

它与 上一节中所述的参数相同,并允许您替代将用于升级后的版本的目标二进制版本。 如果未指定,则新版本将从正在升级的版本继承目标二进制版本属性。

# Promote the release to production and make it
# available to all versions using that deployment
appcenter codepush promote -a <ownerName>/MyApp-iOS -s Staging -d Production -t "*"

回退更新

部署的发布历史记录是不可变的,因此,在发布更新后,你将无法删除或删除它。 但是,如果您释放了损坏或包含意外功能的更新,则可以使用以下命令轻松地将其回滚 rollback

appcenter codepush rollback <ownerName>/<appName> <deploymentName>
appcenter codepush rollback -a <ownerName>/MyApp-iOS Production

执行此命令将为部署创建一个新发布,其中包含与最新版本之前的版本 完全相同的代码和元数据 。 例如,假设您已将以下更新发布到您的应用程序:

发布 说明 必需
v1 初始版本!
v2 新增功能
v3 Bug 修复

如果 rollback 对该部署运行该命令,则将创建一个新版本, v4 其中包含版本的内容 () v2

发布 说明 必需
v1 初始版本!
v2 新增功能
v3 Bug 修复
v4 (从 v3 回滚到 v2) 新增功能

v3 v2 当应用执行更新检查时,已获取的最终用户现在将 "移回"。 此外,任何仍在运行的用户( v2 因此从未获得)都不会 v3 收到更新,因为这些用户已在运行最新版本 (这就是我们的更新检查除发布标签外,还使用包哈希) 的原因。

如果要将部署回滚到以前的 (以外的版本,例如 v3 -> v2) ,则可以指定可选 --target-release 参数:

appcenter codepush rollback -a <ownerName>/MyApp-iOS Production --target-release v34

备注

回滚生成的版本将在该命令的输出中批注 deployment history ,以帮助更轻松地识别它们。

查看发布历史记录

可以使用以下命令查看特定应用部署的 50 个最新发布的历史记录:

appcenter codepush deployment history -a <ownerName>/<appName> <deploymentName>

历史记录将显示每个发布版本的所有属性 (例如标签、) ,以及指示是否由于升级或回滚操作而进行了任何发布。

部署历史记录

此外,历史记录显示每个发布的安装指标。 可以在上述命令文档中查看有关如何解释指标数据 deployment list 的详细信息。

清除发布历史记录

可以使用以下命令清除部署的发布历史记录:

appcenter codepush deployment clear -a <ownerName>/<appName> <deploymentName>

运行此命令后,配置为使用其关联部署密钥接收更新的客户端设备将不再接收已清除的更新。 此命令不可逆,因此不应在生产部署中使用。

代码签名

它是什么?

代码签名是一种为捆绑包创建数字签名的方法,可在安装之前在客户端进行验证。

为何需要它?

开发人员想知道,他们提供的代码就是他们编写的代码。 代码签名是提供此类保证的主要机制,可帮助缓解或消除一类中间人攻击。

它是如何工作的?

首先,开发人员生成非对称密钥对:私钥将用于对捆绑包进行签名;捆绑签名验证的公钥。 然后,CodePush CLI 在 和 命令期间使用私钥对 release release-react 捆绑 release-cordova 进行签名。 公钥随移动应用程序一起提供。 由开发人员控制密钥的生成和管理。

在发布命令结束时,CLI 计算捆绑包的内容哈希,将此值放入使用私钥签名的 JWT 中。 当 CodePush 插件将捆绑包下载到设备时,它会检查包含 JWT 的文件,并使用该公钥验证 .codepushrelease JWT 签名。 如果验证失败,则不安装更新。

使用此功能的要求

如果打算使用此功能,请执行以下步骤:

  1. 生成新的二进制更新,包括

    • 更新了支持代码签名的 CodePush 插件
    • 将你的代码推送 sdk 配置为使用你的公钥 (引用相关的响应本机 SDK (iOSAndroid) 或 Cordova sdk 部分了解详细信息)
  2. 生成面向新二进制版本的新 CodePush 更新,并指定 --privateKeyPath (或 -k) 参数值

请参阅兼容性表,以确定 SDK/CLI 中是否支持代码签名功能:

CodePush SDK 代码签名支持的版本 支持的平台 要求的最小 CodePush CLI 版本
react-native-code-push 5.1.0 Android、iOS 2.1.0
cordova-plugin-code-push 1.10.0 Android、iOS 2.1.2

密钥生成

代码签名支持 PEM 编码的 RSA 密钥 (非证书) 签名。 可以通过 openssl 生成它们,如下所示:

# generate private RSA key and write it to private.pem file
openssl genrsa -out private.pem

# export public key from private.pem into public.pem
openssl rsa -pubout -in private.pem -out public.pem

生成的密钥示例:

# public key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4moC3GsqF7YISFMQ0fnU
0rUF2xhxNqSGx9/GTxCynsQhR3hceroDXj3rAOTxnNkePB27uZfRDHrH3/LLoj9V
k2ghKRtfjDwXa85uDK8slSQDB9ZlD1TLQEJDZpKr1OTXY9VwbgtFaotSXoFmG3MO
RQeALCbrAgDxQ5Q2kJn6rfBuBoszfUz1qZqrlrY74Axerv1/UtTjL8uyF5r00Bxj
kvTveC2Pm5A3kq6QANktgfKWy9Ugs/4ykZF7fxfH+ukJW+iXwLACrdfzhegg/41H
5w06m30h0jqhIBZ3nbj5MN+qVbANHJMjz+fXqXx1Ovr1DfGtdKOku/BTWDxojCl1
iwIDAQAB
-----END PUBLIC KEY-----

# private key
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA4moC3GsqF7YISFMQ0fnU0rUF2xhxNqSGx9/GTxCynsQhR3hc
eroDXj3rAOTxnNkePB27uZfRDHrH3/LLoj9Vk2ghKRtfjDwXa85uDK8slSQDB9Zl
D1TLQEJDZpKr1OTXY9VwbgtFaotSXoFmG3MORQeALCbrAgDxQ5Q2kJn6rfBuBosz
fUz1qZqrlrY74Axerv1/UtTjL8uyF5r00BxjkvTveC2Pm5A3kq6QANktgfKWy9Ug
s/4ykZF7fxfH+ukJW+iXwLACrdfzhegg/41H5w06m30h0jqhIBZ3nbj5MN+qVbAN
HJMjz+fXqXx1Ovr1DfGtdKOku/BTWDxojCl1iwIDAQABAoIBAQCdwf/8VS8fFlbv
DfHKXKlNp5RM9Nrtl/XRjro+nQPYXBBUHClT2gg+wiXcmalAAIhwmscSqhWe/G4I
PMRmaHrYGtYALnKE49nt5AgKDoSh5lW2QExqQkrcm08bSVcxH8J0bWPJSVE0y564
+rCKr8BhmLhWC0f0PXPeAoeCeceRKYX2oDgO8A0yZRSQUdRWiXOiQ4mUQ3IPCmBc
gD1JJNZ5kR4O904PZz5pbgyvN2t5BKOgLKq+x+8Pa8Rb21rFZKMHO8W04oKaRiGs
f4xwOBAWDOfzDKJzT5xepcPyycgjxcuvyKB2g8biWnDGGOTxDgqMX+R4XeP1aISC
h9bzfRoBAoGBAPREuPhIXRJOsIgSWAAiC5vhLZ9wWELWG95eibQm2SfpY4F0sPpE
lNQJ4yzC7J4BiApFzs1yxwwRmgpVd+wF9iMb4NSzaiTM7fju/Xv4aGhBqRXEokGF
v3QxIlbAwBqeL0rJAAadjbUTTO/u6sC80LI3bfPrn/z1hupZQGR559gjAoGBAO1J
xQ2ODVS4dSH2P+Ocd9LiUBPGyV97+MFixh6z1c2Fd3bNuiIhCxkrng45Dq0CkX84
nPUvtYxEQZoFvyB7gAm0SVlLHnJwBiq+Mp9g0UXSy6rZbjhiFkQs1W/W+Z2OIDsC
y+uXZT7No/J9VyjdrWzZJaBImO8/E4NONXWn8M95AoGACH97j+e0lTZ3ncRFm3uT
u9CRrcJSz8BzJ8FSORpA48qS06YjohFQvC+734rIgJa9DN5w22Tq19ik60cd7PAo
KACISd4UC0O147ssxmtV9oqSP1ef7XehuYEcGLiL9mEadBeaEKDalToeqxo8wIfR
GuIiySGhZ0ODdhO00coL7tECgYBargddD70udDNnICj4PbJY5928QQpxr/m3RZz6
3LTHDstBnosUQdZw7wc+3jUqjsG1gZgR5wKVMPx09N8+dZPPoZMqSZfAGelxajAE
UkaHTXBBwUfqyilCMnP6gofv2wGcK4xsYvXxEzslDxtA5b5By5Yic7vmKg+17Sxm
4yAW2QKBgDyEUzXq3Rrm7ZT720pPhuQDDSO0eHe1L1MUjTRsJ96GkIl0iqQCVgK8
A/6rFFTEeVf8L6GNMTwdtnDFz/CqIU+K1X4HLXmUY2suffWVxZ4KYqiEszCbyrdO
puayMcrx2unhKQyDYjUvD8GxHyquA+p52KDke2TkKfDxfzv0WOE1
-----END RSA PRIVATE KEY-----

正在发布签名的更新

若要发布签名更新,应将 --privateKeyPath (或 -k) 选项用于 releaserelease-react 命令。