# 快速通道自动部署 NativeScript 应用程序

·

如果我不得不指出 NativeScript 开发人员原本令人兴奋的生活中最不愉快的一项任务,我会说:部署!哦,我怎么看不起他们…

从 Apple 的配置文件简介到日新月异的 Google Play 控制台,部署应用程序总是让人感到无聊,麻烦,并且可能浪费时间来为出色的应用程序开发出色的功能。在项目的整个生命周期中,一个应用程序可以在测试版本,测试版,错误修复和新功能之间部署数十次(如果不是数百次!)。如果有一种方法可以使部署自动进行,这样我们就可以在需要时将最新版本的应用程序交付我们的队友和用户,这不是很好吗?好吧…感谢 fastlane。

fastlane 是一种工具,可以自动执行 iOS 和 Android 应用程序的部署和发布。通过正确的配置,它可以用于自动化 NativeScript 部署。正如您从本文的长度可以看到的那样,设置它并非易事…但是,如果您的项目持续时间足够长,则可以节省大量时间。

我们将逐步介绍配置 fastlane 所需的步骤,并解释每个步骤,以便您了解如何针对项目进行调整。本文是经过数小时实验的结果,直到我达到了对我的项目有意义的配置,并且对在开发团队中管理机密性的关注程度很高。同样,请随时根据您的项目和组织进行调整。

TIP

免责声明:在本文中,我们将假定您已经为 iOS 和 Android 确定了部署。我们没有展示如何部署应用程序,而是展示了如何自动化这些部署。

作为一个例子,我们将创建一个 FASTLANE 配置称为 HubbyChef 一个示范项目。

# 入门 FASTLANE

我们将从安装 fastlane 开始,可以使用以下命令完成该操作:

brew cask install fastlane

TIP

有关更多安装选项和故障排除的信息,请参阅 fastlane 文档。

我们无法使用 fastlane 命令 fastlane init 来开始使用,因为 NativeScript 项目文件夹结构与“常规”本机应用程序不同。相反,我们将手动创建和编辑配置文件。

# 快速档案(fastlane/Fastfile)

创建文件夹fastlane/和其中的文件Fastfile

mkdir fastlane
touch fastlane/Fastfile

Fastfile是主 FASTLANE 配置文件。这是我们添加车道的地方。您可以将泳道视为一组任务。车道包括动作和其他车道。您也可以在平台下对车道进行分组。

让我们看看如何通过为我们的顶部结构创建所有东西Fastfile

fastlane_version '2.131.0'
desc 'test lane'
lane :test do
  print "TEST SUCCESSFUL!"
end
platform :ios do
 desc 'Fetch certificates and provisioning profiles'
 lane :certificates do
 end
 desc 'Build the iOS application.'
 lane :build do
 end
 desc 'Ship to Testflight.'
 lane :beta do
 end
end
platform :android do
 desc 'Build the Android application.'
 lane :build do
 end
 desc 'Ship to Playstore Alpha track.'
 lane :alpha do
 end
end

第一行(fastlane_version '<x>')将确保您的队友没有使用过时的快车道版本。然后,我们创建了一个测试车道 test,只是为了查看 fastlane 是否正常工作。您可以使用命令进行测试fastlane test。结果应该TEST SUCCESSFUL!在控制台中打印出来。

然后,我们添加了两个平台:iosandroid。对于 ios 平台,我们将有车道 certificatesbuildbeta。对于android,车道 buildalphadesc每个通道上方的 s 描述了它们将要执行的操作。稍后我们将调用这些通道有fastlane <platform> <lane>,例如fastlane ios build

运行fastlane lanes将显示所有可用车道的摘要:

快车道结果

fastlane_lanes.png

# 应用档案(./fastlane/Appfile)

创建Appfile内部fastlane文件夹。该文件将存储有关该应用程序的信息,如下所示:

app_identifier "dev.tiagoalves.hubbychef"
apple_id "tralves@tiagoalves.dev"
team_id "xxxxxxxxx"

# .env.default(./.env.default)

将密码和 API 密钥之类的机密直接存储在 fastlane 配置文件中是不安全的,因为这些文件是项目的一部分,应将其与代码一起推送到版本控制中。相反,我们将使用 dotenv 所有敏感信息并将其存储在.env.default文件中。只是不要忘记.gitignore它。

该文件包含一组键值条目,例如:

MATCH_PASSWORD="xxxxxxxxx"

我们可以在Fastfilewith中使用此值ENV["MATCH_PASSWORD"],但有时动作只会在后台使用这些值。

# 的 iOS

现在,我们将从最难的部分开始构建 iOS 配置:代码签名。

# 代码签名

请允许我继续并推荐该 match 方法。您可以在此处阅读有关此概念的所有信息,但总而言之,这 match 将为您提供帮助:

  • 自动生成必要的证书和配置文件(无需访问 Apple 开发者帐户页面);
  • 将证书和配置文件存储在存储库(Git 或 Google 云存储)中。所有文件都将被加密作为附加的安全层;
  • 易于设置,以在新计算机中部署或为新团队成员服务。match将负责在构建过程中安装所有内容;
  • fastlane构建集成;

您可以match在官方文档中阅读所有内容。在这里,我们将展示使其工作的基本步骤。

TIP

提示:该match文档建议创建“一个新的共享 Apple Developer Portal 帐户,类似 office@company.com”。这将使整个团队之间的共享访问变得更加容易。

# 1)安装 match

运行命令:

fastlane match init

此命令将询问有关证书和配置文件的存储方法。我建议使用 GIT 并为证书创建一个新的私有存储库(例如https://github.com/tralves/hubbychef-certs)。该命令将创建文件fastlane/Matchfile

# 2)配置 match

fastlane/Matchfile使用项目和 Apple 帐户信息编辑文件。这是我的Matchfile样子:

git_url("https://github.com/tralves/hubbychef-certs")
storage_mode("git")
type("development") # The default type
app_identifier("dev.tiagoalves.hubbychef")
username("tralves@tiagoalves.dev") # Your Apple Developer Portal username
team_id('xxxxxxxxxx')
team_name('Tiago Alves')

将存储库加密密码添加到,.env.default这样您就不必在每次部署时都提供该密码。

MATCH_PASSWORD="xxxxxxxxx"
# 3)生成证书和配置文件

现在,您可以使用生成新的证书和配置文件match

TIP

提示:在执行此步骤之前,请确保在计算机的“钥匙串访问”中删除该帐户的所有 Apple Developer 证书。match将创建并安装可能与现有证书冲突的新证书。

为此,请运行:

match development
match appstore

这将创建开发和分发证书及其各自的配置文件。它还会将它们安装在您的计算机上。如果一切顺利,您现在可以在 Xcode 中打开项目并使用新的配置文件。您还可以看到在先前创建的 GIT 存储库中提交的这些文件。像魔术!

# 4)配置 certificates 车道

现在,您可以配置certificates 的车道在Fastfile

desc 'Fetch certificates and provisioning profiles'
lane :certificates do
    match(type: 'development')
    match(type: "appstore")
    # match(type: "adhoc")
end

通过此通道,您可以使用安装所有证书fastlane ios certificates

# 建立步骤

有了所有证书和配置文件后,我们现在可以进行构建步骤了。在这里,我们将创建一个.ipa带有分发配置文件的签名,然后可以将其分发到 Testflight 或 App Store。这是我的ios build 车道的样子:

desc 'Build the iOS application.'
lane :build do
    sh("tns", "prepare", "ios", "--release", "--clean", "--env.production")
    match(type: "appstore")
    build_app(
      scheme: "HubbyChef",
      workspace: './platforms/ios/HubbyChef.xcworkspace',
      export_method: "app-store"
    )
end

此通道中的第一个操作运行命令tns prepare ios --release --clean --env.production,这是我们将在手动部署中键入的命令。

第二个操作,match(type: "appstore")确保已安装分发证书和配置文件,并将它们设置为在下一个操作中使用。

最后,该 build_app 动作会编译并签名.ipa。注意操作中的参数:

  • scheme:在 Xcode 顶部栏中显示的构建方案,通常是应用程序的名称: Xcode 方案
  • workspace:项目.xcworkspace 文件的路径;
  • export_method:导出存档的方法。在这种情况下,我们要app-store
    至此,我们可以.ipa使用以下命令生成签名:

fastlane ios build
如果一切顺利,您应该.ipa在项目的根文件夹中看到。

# 运送到 Testflight

最后一步是将其运送.ipa到 Testflight。看看ios beta 车道:

desc 'Ship to Testflight.'
lane :beta do
    build
    changelog_from_git_commits
    upload_to_testflight(
      beta_app_feedback_email: "tralves@tiagoalves.dev",
      beta_app_description: "App for Hubbies trying to learn how to cook.",
      demo_account_required: false,
      distribute_external: true,
      groups: ["beta testers"],
      notify_external_testers: true,
      beta_app_review_info: {
        contact_email: "tralves@tiagoalves.dev",
        contact_first_name: "Tiago",
        contact_last_name: "Alves",
        contact_phone: "+351 9xxxxxxxx",
        demo_account_name: "",
        demo_account_password: "",
        notes: "<3 Thank you for reviewing!"
      },
    )
end

该车道通过调用启动build 车道我们前面,所以我们总是有新鲜内置的应用程序发送给 Testflight 定义。

然后,我喜欢使用该动作 changelog_from_git_commits。默认情况下,此操作将捕获自上一个 GIT 标签以来的所有提交消息,并将它们用作将应用程序提交到 Testflight 时将使用的更改日志。这样,您的 Beta 测试人员将知道每个版本中的新增功能,并且您无需为此做任何事情(除非编写适当的提交消息…)。

  1. 上传到 testflight 的最后一个操作将是:
  2. 将其上传.ipa 到 App Store Connect;
  3. 将构建添加到 Testflight;
  4. 分配给所需的测试组(在这种情况下,为“ beta 测试人员”组);
  5. 提交应用以供审核;

如果您曾经手动执行此过程,则将使用表单域标识此操作中的参数,否则必须一遍又一遍地填写。使用此配置,您要做的就是:

fastlane ios beta

您也可以使用 Fastlane 通过操作将应用程序提交到 App Store upload_to_app_store。您可以在这里阅读所有内容。我不会在本教程中创建该泳道,因为这不是我自己尝试的事情,因为我对此步骤拥有更多控制权。但是,它应该与 using 非常相似upload_to_testflight

# 安卓系统

我们只有一半了!是时候创建 fastlane Android 配置了。

# 代码签名

您可能已经.keystore为您的项目准备了文件。如果没有,请参见此处如何创建一个。

我们将密钥库放入其中certs/hubby-chef-prod.keystore,并将其秘密添加到.env.default

KEYSTORE_PASSWORD="xxxxxxxxxxxxx"
KEYSTORE_ALIAS="dist"
KEYSTORE_ALIAS_PASSWORD="xxxxxxxxxx"

# 建立步骤

要构建 Android 应用,需要运行该命令的通道 tns 来创建签名的生产版本:

desc 'Build the Android application.'
  lane :build do
    sh("tns", "build", "android", "--release", "--clean", "--env.production",
        "--key-store-path", "../certs/hubby-chef-prod.keystore",
        "--key-store-password", ENV["KEYSTORE_PASSWORD"],
        "--key-store-alias", ENV["KEYSTORE_ALIAS"],
        "--key-store-alias-password", ENV["KEYSTORE_ALIAS_PASSWORD"]
      )
end

我们完成了!现在fastlane android build,您可以运行,最后,您应该看到app-release.apk下方platforms/android/app/build/outputs/apk/release/

# 运送至 Play 商店 Alpha 音轨

我们需要设置一个 Google Developers Service 帐户。为此,请按照以下步骤操作(或查看 fastlane 文档):

  • 打开 Goog​​le Play 控制台;
  • 单击“设置”菜单项,然后单击“ API 访问”;
  • 点击“创建服务帐户”按钮;
  • 点击对话框中的“ Google Developers Console”链接,这将打开一个新的标签/窗口:
  • 点击 Google Developers Console 顶部的“创建服务帐户”按钮;
  • 提供服务帐户名称(例如hubbychef-manager);
  • 点击“创建”;
  • 单击“选择角色”,然后选择“服务帐户”>“服务帐户用户”;
  • 点击“继续”;
  • 点击“创建密钥”;
  • 选中“提供新的私钥”复选框;
  • 确保选择“ JSON”作为“密钥类型”;
  • JSON 文件将被下载;
  • 单击“授予访问权限”以获取新添加的服务帐户;
  • 从“角色”下拉菜单中选择“发布管理器”(或“项目负责人”);
  • 点击“添加用户”关闭对话框;

然后,将 JSON 文件内容复制到.env.default,如下所示:

PLAYSTORE_JSON_KEY_DATA='
{
  "type": "service_account",
  "project_id": "api-642090...",
  "private_key_id": "11d039fd....",
  "private_key": "-----BEGIN PRIVATE KEY-----\nMI...",
  "client_email": "hubbychef-manager@api-6420905...",
  "client_id": "114219...",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis...",
  "client_x509_cert_url": "https://www.googleapis.com/..."
}

现在,我们可以在中创建车道Fastfile

desc 'Ship to Playstore Alpha.'
  lane :alpha do
    build
    changelog_from_git_commits
    upload_to_play_store(
      track: 'alpha',
      track_promote_to: 'alpha',
      json_key_data: ENV["PLAYSTORE_JSON_KEY_DATA"],
      apk: './platforms/android/app/build/outputs/apk/release/app-release.apk'
    )
end

就像我们在 iOS 上所做的一样,我们从调用build lane 开始。同样,我们将使用changelog_from_git_commits生成变更日志。

然后将构建版本发送给动作upload_to_play_store。在这里,我们将构建发送到“ Alpha”轨道,但是您可以将其发送到 Beta 或 Production。查看 upload_to_play_store 的文档以了解更多详细信息。

# 工作流程

请允许我用 fastlane 添加有关我的部署工作流的另一条注释。这些是我部署新版本的步骤:

# 1)增加中的版本package.json

但是,增加版本存在问题:即使您只是部署到 Testflight,Apple 也会花数小时甚至数天的时间审查您的应用程序。我的替代方法是使用此 NativeScript 插件,该插件可让您在中添加versionNumber参数package.json。该编号将是 iOS 上的内部版本号。如果仅增加此值,则将立即批准您的应用进行测试。该插件还可以确保您versionCode在 Android 上获得增量。

WARNING

警告:fastlane 操作 increment_build_number 不适用于 NativeScript 应用程序的生成流程。

# 2)运行 fastlane 命令:
fastlane ios beta
fastlane android alpha
# 3)创建一个 git 标签

这样可以确保该操作changelog_from_git_commits仅在下次部署时捕获正确的提交。

# 总而言之…

fastlane 是一个很棒的工具!在本文中,我们只是简单介绍了 fastlane 可以为您做什么。如果您想要附加到构建过程中,则可能需要采取一些措施。我说的是诸如集成自动测试,拍摄屏幕截图,bot /报告松弛,各种 CI 集成等内容。

我知道所有这些工作看起来都很艰巨,但这只是我弄清楚这个问题的时间的一小部分!这肯定会节省您的时间和耐心。部署将是一件轻而易举的事……您最终将需要更频繁地进行部署,从而使您的用户,队友,质量检查人员和老板更加快乐。请享用!