部署

重要

Visual Studio App Center 计划于 2025 年 3 月 31 日停用。 虽然可以继续使用 Visual Studio App Center,直到它完全停用,但你可以考虑迁移到几个建议的替代方法。

详细了解支持时间线和替代方法。

多部署测试

入门 文档中,我们演示了如何使用特定的部署密钥配置 CodePush 插件。 但是,为了有效地测试版本,请务必使用StagingProduction我们建议在首次创建 CodePush 应用时 (或) 创建的任何自定义部署。 这样,就永远不会向最终用户发布你无法验证自己的更新。

注意

客户端回退功能可帮助在安装导致崩溃的版本后取消阻止用户,服务器端回滚 (即 appcenter codepush rollback) 允许你防止其他用户在发现错误版本后安装错误版本。 但是,如果一开始可以防止错误更新被广泛发布,则最好。

利用 StagingProduction 部署,可以实现如下所示的工作流 (随意自定义!) :

  1. 使用appcenter codepush release-react命令将 CodePush 更新发布到Staging部署 (,或者appcenter codepush release如果需要更多控制)

  2. 运行应用的过渡/beta 版本,从服务器同步更新,并验证它是否按预期工作

  3. 使用 appcenter codepush promote 命令将测试的版本从 Staging 提升为Production

  4. 运行应用的生产/发布版本,从服务器同步更新并验证它是否按预期工作

    提示

    如果想要采取更谨慎的方法,甚至可以选择在 #3 中执行“分阶段推出”,这允许你通过更新 (缓解其他潜在风险,就像 #2 中的测试涉及所有可能的设备/条件?) 仅向一部分用户提供生产更新, (例如 appcenter codepush promote -a <ownerName>/<appName> -s Staging -d Production -r 20 ,) 。 然后,在等待合理的时间来查看是否有任何故障报告或客户反馈传入后,可以通过运行 appcenter codepush patch -a <ownerName>/<appName> Production -r 100将其扩展到整个受众。

上述步骤是指应用的“过渡生成”和“生产生成”。 如果生成过程已经为每个“环境”生成了不同的二进制文件,则无需进一步读取任何内容,因为交换 CodePush 部署密钥类似于处理应用使用的任何其他服务 ((如 Facebook) )的环境特定配置。 但是,如果你正在寻找有关如何设置生成过程以适应这种情况的示例,请参阅以下部分,具体取决于应用的目标平台。

Android

Android Gradle 插件允许为每个“生成类型” ((如调试、发布) )定义自定义配置设置。 通过此机制,可以轻松地将调试版本配置为使用 CodePush 暂存部署密钥,将发布版本配置为使用 CodePush 生产部署密钥。

注意

提醒一下,可以通过从终端运行 appcenter codepush deployment list -a <ownerName>/<appName> -k 来检索这些密钥。

若要进行此设置,请执行以下步骤:

对于 React Native >= v0.60

  1. 打开项目的应用级build.gradle文件 (,例如android/app/build.gradle在标准React Native项目中)

  2. android { buildTypes {} }找到 部分并为 和 release 生成类型定义resValue条目debug,分别引用 StagingProduction 部署密钥。

    android {
        ...
        buildTypes {
            debug {
                ...
                // Note: CodePush updates shouldn't be tested in Debug mode as they're overriden by the RN packager. However, because CodePush checks for updates in all modes, we must supply a key.
                resValue "string", "CodePushDeploymentKey", '""'
                ...
            }
            releaseStaging {
                ...
                resValue "string", "CodePushDeploymentKey", '"<INSERT_STAGING_KEY>"'
                // Note: It's a good idea to provide matchingFallbacks for the new buildType you create to prevent build issues
                // Add the following line if not already there
                matchingFallbacks = ['release']
                ...
            }
            release {
                ...
                resValue "string", "CodePushDeploymentKey", '"<INSERT_PRODUCTION_KEY>"'
                ...
            }
        }
        ...
    }
    

注意

如果要在生成过程中配置部署密钥,请记得从 strings.xml 中删除密钥*

注意

由于此行,的releaseStaging命名约定非常重要。

对于 React Native v0.29 - v0.59

  1. 打开 MainApplication.java 文件并进行以下更改:

    @Override
    protected List<ReactPackage> getPackages() {
         return Arrays.<ReactPackage>asList(
             ...
             new CodePush(BuildConfig.CODEPUSH_KEY, MainApplication.this, BuildConfig.DEBUG), // Add/change this line.
             ...
         );
    }
    
  2. 打开应用build.gradle的文件 (,例如android/app/build.gradle在标准React Native项目中)

  3. android { buildTypes {} }找到 部分并为 和 release 生成类型定义buildConfigField条目debug,分别引用 StagingProduction 部署密钥。 如果愿意,可以在文件中定义密钥文本 gradle.properties ,然后在此处引用它们。 无论哪种方式都行得通,这是个人偏好的问题。

    android {
        ...
        buildTypes {
            debug {
                ...
                // Note: CodePush updates shouldn't be tested in Debug mode as they're overridden by the RN packager. However, because CodePush checks for updates in all modes, we must supply a key.
                buildConfigField "String", "CODEPUSH_KEY", '""'
                ...
            }
    
            releaseStaging {
                ...
                buildConfigField "String", "CODEPUSH_KEY", '"<INSERT_STAGING_KEY>"'
    
                // Note: It's a good idea to provide matchingFallbacks for the new buildType you create to prevent build issues
                // Add the following line if not already there
                matchingFallbacks = ['release']
                ...
            }
    
            release {
                ...
                buildConfigField "String", "CODEPUSH_KEY", '"<INSERT_PRODUCTION_KEY>"'
                ...
            }
        }
        ...
    }
    

    提示

    提醒一下,可以通过从终端运行 appcenter codepush deployment list -a <ownerName>/<appName> --displayKeys 来检索这些密钥。

    注意

    由于此行,的releaseStaging命名约定非常重要。

  4. 通过定义的生成配置( CodePush 而不是字符串文本)将部署密钥传递给构造函数。

对于 React Native v0.19 - v0.28

打开 MainActivity.java 文件并进行以下更改:

@Override
protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
        ...
        new CodePush(BuildConfig.CODEPUSH_KEY, this, BuildConfig.DEBUG), // Add/change this line.
        ...
    );
}

注意

如果在 Gradle 文件中为生成设置指定了不同的名称,请确保在 Java 代码中反映该名称。

大功告成! 现在,运行或生成应用时,调试版本将自动配置为与 Staging 部署同步,发布版本将配置为与 Production 部署同步。

注意

默认情况下, react-native run-android 命令生成并部署应用的调试版本,因此,如果要测试发布/生产版本,请运行“react-native run-android --variant release”。 有关如何为 Android 应用配置和创建发布版本的详细信息,请参阅React Native文档

如果要在同一设备上同时安装调试版本和发布版本 (强烈建议!) ,则需要确保调试版本具有发布版本中的唯一标识和图标。 否则,OS 或你都无法区分这两者。 可以通过执行以下步骤来配置唯一标识:

  1. build.gradle 文件中,指定 applicationIdSuffix 调试生成类型的 字段,这将为操作系统 ((如 com.foo vs. com.foo.debug) )提供唯一标识。

    buildTypes {
        debug {
            applicationIdSuffix ".debug"
        }
    }
    
  2. app/src/debug/res 应用中创建目录结构,从而允许替代调试版本的 (资源,如字符串、图标、布局)

  3. 在 #2 中创建的 debug res 目录下创建一个values目录,并从目录中app/src/main/res/values复制现有strings.xml文件

  4. 打开新的调试 strings.xml 文件,将 <string name="app_name"> 元素的值更改为其他 (值,例如 foo-debug) 。 这可确保调试版本现在具有不同的显示名称,以便你可以将其与发布版本区分开来。

  5. (可选)在 app/src/debug/res 目录中为要为调试版本更改的所有应用图标创建“镜像”目录。 此部分在技术上并不重要,但如果其图标明显不同,则可以更轻松地在设备上快速发现调试版本。

大功告成! 有关 资源合并 在 Android 中的工作原理的详细信息,请参阅资源合并。

iOS

Xcode 允许为每个“配置” ((如调试、发布) )定义自定义生成设置,这些设置可以引用为 Info.plist 文件中的键值, (如 CodePushDeploymentKey 设置) 。 通过此机制,可以轻松配置生成以生成二进制文件,这些二进制文件配置为与不同的 CodePush 部署同步。

若要进行此设置,请执行以下步骤:

  1. 打开 Xcode 项目,并在“ 项目导航器 ”窗口中选择项目

  2. 确保选择项目节点,而不是目标之一

  3. 选择“ 信息 ”选项卡

  4. +单击“配置”部分中的按钮,然后选择“重复的”发布“配置

    配置

  5. 将新配置命名为 过渡 (或任何你喜欢)

  6. 选择“ 生成设置” 选项卡

  7. +单击工具栏上的按钮,然后选择“添加 User-Defined 设置

    设置

    将此设置 命名为MULTI_DEPLOYMENT_CONFIG。 转到设置并为“发布”添加值$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)。 在此之后,为 Staging 添加值$(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)

    MultiDeploymentConfig

    注意

    对于 Xcode 10 及更低版本:转到“生成位置>”“按配置生成产品路径>”“暂存”,并将“暂存”值从 更改为$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)$(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)

    BuildFilesPath

    注意

    由于 , https://github.com/facebook/react-native/issues/11813我们必须执行此步骤,才能在 RN 0.40.0 或更高版本上使用调试或发布以外的其他配置。

  8. +再次单击工具栏上的按钮,然后选择“添加 User-Defined 设置

    将此设置CODEPUSH_KEY命名为 ,将其展开,并为过渡配置指定过渡部署密钥,并为发布配置指定生产部署密钥。

    设置密钥

    注意

    提醒一下,可以通过从终端运行 appcenter codepush deployment list -a <ownerName>/<appName> --displayKeys 来检索这些密钥。

  9. 打开项目的 Info.plist 文件,并将条目的值 CodePushDeploymentKey 更改为 $(CODEPUSH_KEY)

    Info.plist

大功告成! 现在,运行或生成应用时,过渡版本将自动配置为与 过渡 部署同步,发布版本将配置为与 生产 部署同步。

注意

如果发现错误消息 ld: library not found for ...检查此问题以获取可能的解决方案。

此外,如果想要为它们提供单独的名称或图标,可以修改 Product Bundle IdentifierProduct NameAsset Catalog App Icon Set Name 生成设置,这样,当安装在同一设备上时,过渡版本可以与发布版本区分开来。

动态部署分配

上一部分演示了如何在广泛向最终用户发布更新之前,使用多个 CodePush 部署有效地测试更新。 但是,由于该工作流静态地将部署分配嵌入到实际二进制文件中,暂存或生产版本将仅同步该部署中的更新。 在许多情况下,这已足够,因为你只希望团队、客户、利益干系人等与预生产版本同步,因此,他们只需要知道如何同步过渡的版本。 但是,如果要执行 A/B 测试,或向某些用户提供应用的早期访问,在运行时将特定用户 (或) 受众动态放入特定部署可能很有用。

若要实现此工作流,请在调用 方法时指定希望当前用户与之同步的 codePush 部署密钥。 指定后,此密钥将替代应用的 Info.plist 中提供的“默认” (iOS) 或 MainActivity.java (Android) 文件。 这允许生成用于过渡或生产的生成,它还能够根据需要动态“重定向”。

// Imagine that "userProfile" is a prop that this component received
// that includes the deployment key that the current user should use.
codePush.sync({ deploymentKey: userProfile.CODEPUSH_KEY });

更改到位后,现在需要选择应用如何为当前用户确定正确的部署密钥。 实际上,通常有两种解决方案:

  1. 公开随时更改部署的用户可见机制。 例如,设置页面可以有一个用于启用“beta”访问的开关。 如果你不关心预生产更新的隐私,并且你拥有可能想要选择加入早期 (且可能自行) 更新 ((如 Chrome 频道) )的) 更新,则此模型非常有效。 但是,此解决方案将决策掌握在用户手中,这无助于以透明方式运行 A/B 测试。

  2. 使用指示用户应同步的部署的附加元数据段为用户的服务器端配置文件添加批注。 默认情况下,应用可以使用二进制嵌入密钥,但在用户进行身份验证后,服务器可以选择将其“重定向”到不同的部署,这样就可以根据需要以增量方式将某些用户或组放置在不同的部署中。 甚至可以选择将服务器响应存储在本地存储中,使其成为新的默认值。 如何将密钥与用户配置文件一起存储完全由身份验证解决方案 ((例如 Auth0、Firebase、自定义 DB + REST API) )决定,但通常非常简单。

    注意

    如果需要,还可以实现允许最终用户在不同的部署之间切换的混合解决方案,同时允许服务器替代该决策。 这样,你便有了一个“部署解析”层次结构,确保你的应用能够现成地更新自身,最终用户可以通过提前访问位来获得回报,但你也可以根据需要对用户运行 A/B 测试。

由于我们建议使用 Staging 部署来预发布测试更新 (,如上一部分) 所述,因此,将其用于用户的 A/B 测试并不一定有意义,而不是如) 上面的选项 1 中所述允许提前访问 (。 因此,我们建议充分利用自定义应用部署,以便你可以根据需求对用户进行细分。 例如,可以创建长期部署,甚至一次性部署,向其发布应用变体,然后将某些用户放入其中以查看他们如何参与。

// #1) Create your new deployment to hold releases of a specific app variant
appcenter codepush deployment add -a <ownerName>/<appName> test-variant-one

// #2) Target any new releases at that custom deployment
appcenter codepush release-react -a <ownerName>/<appName> -d test-variant-one

注意

部署名称中不支持字符“/”和“:”。

注意

部署的“安装指标”中报告的用户总数将考虑已从一个部署“切换到另一个部署”的用户。 例如,如果 生产 部署当前报告有 1 个总用户,但你动态地将该用户切换到 过渡,则 生产 部署将报告 0 个总用户,而 过渡 部署将报告 1 个 (切换) 的用户。 此行为使你能够准确地跟踪发布采用情况,即使在使用基于运行时的部署重定向解决方案的情况下也是如此。