如果要我指出 NativeScript 开发者激动人心的生活中最不愉快的一项任务,我会说:部署!哦,我多么讨厌它们……
从苹果的配置文件地狱到不断变化的 Google Play Console,部署应用程序总是让人感觉无聊、繁琐,纯粹是浪费时间,你本来可以用来为你的精彩应用程序开发精彩的功能。在项目的生命周期中,一个应用程序可以部署数十次(如果不是数百次!),包括测试版本、测试版、错误修复和新功能。如果有一种方法可以使部署自动化,以便我们可以随时将应用程序的最新版本交付到我们的队友和用户手中,那岂不是太好了吗?好吧……有了 fastlane,现在可以实现了。
fastlane 是一个用于自动执行 iOS 和 Android 应用程序部署和发布的工具。通过正确的配置,它可以用来自动化 NativeScript 部署。正如你从这篇文章的篇幅中所看到的,设置它并不简单……但是,如果你的项目持续时间足够长,它将为你节省大量时间。
我们将介绍配置 fastlane 所需的步骤,并解释每个步骤,这样你就知道如何根据自己的项目进行调整。这篇文章是我经过几个小时的实验得出的,最终得到了一种对我的项目有意义的配置,并在一定程度上关注了在开发团队中管理秘密。再次强调,请随意根据自己的项目和组织进行调整。
免责声明:在本文中,我们假设你已经为 iOS 和 Android 都完成了部署设置。我们不会展示如何部署应用程序,而是展示如何自动化这些部署。
例如,我们将创建一个 fastlane 配置,用于一个名为 HubbyChef 的演示项目。
我们将从安装 fastlane 开始,可以使用以下命令完成安装
brew cask install fastlane
有关更多安装选项和故障排除,请查看 fastlane 文档。
我们不能使用 fastlane 命令 fastlane init
来开始,因为 NativeScript 项目文件夹结构与“正常”原生应用程序不同。相反,我们将手动创建和编辑配置文件。
fastlane/Fastfile
)创建文件夹 fastlane/
,并在其中创建文件 Fastfile
。
mkdir fastlane
touch fastlane/Fastfile
Fastfile
是 fastlane 的主配置文件。在这里,我们将添加我们的 lane。你可以将 lane 视为一组任务。Lane 包括 操作 和其他 lane。你也可以将 lane 分组到 platform 下。
让我们看看如何通过为 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>'
) 将确保你的队友没有使用过时的 fastlane 版本。然后,我们创建了一个测试 lane test
,只是为了看看 fastlane 是否正常工作。你可以使用命令 fastlane test
进行测试。它应该在控制台中打印出 TEST SUCCESSFUL!
。
然后,我们添加了两个 platform:ios
和 android
。对于 ios
平台,我们将使用 lane certificates
、build
和 beta
。对于 android
,将使用 lane build
和 alpha
。每个 lane 上面的 desc
描述了它们将执行的操作。我们将在稍后使用 fastlane <platform> <lane>
调用这些 lane,例如 fastlane ios build
。
运行 fastlane lanes
将显示所有可用 lane 的摘要
./fastlane/Appfile
)在 fastlane
文件夹内创建 Appfile
。此文件将存储有关应用程序的信息,如下所示
app_identifier "dev.tiagoalves.hubbychef"
apple_id "[email protected]"
team_id "xxxxxxxxx"
./.env.default
)将密码和 API 密钥等秘密直接存储在 fastlane 配置文件中并不安全,因为这些文件是项目的一部分,应该与代码一起推送到版本控制中。相反,我们将使用 dotenv
并将所有敏感信息存储在 .env.default
文件中。只要不要忘记 .gitignore
它。
此文件包含一组键值对,例如
MATCH_PASSWORD="xxxxxxxxx"
我们可以在 Fastfile
中使用 ENV["MATCH_PASSWORD"]
来使用此值,但有时操作会在后台使用这些值。
现在我们将构建我们的 iOS 配置,从最难的部分开始:代码签名。
请允许我推荐 match
方法。你可以在这里 阅读有关此概念的所有内容,但简而言之,match
将为你执行以下操作
match
将在构建过程中负责安装所有内容;fastlane
构建集成;你可以在 官方文档 中阅读有关 match
的所有内容。在这里,我们将展示让它工作的基本步骤。
提示:
match
文档建议创建 “一个新的共享 Apple 开发者门户帐户,类似于[email protected]
”。这将使团队成员之间共享访问权限变得更加容易。
1) 安装 match
运行以下命令
fastlane match init
此命令将询问证书和配置文件的存储方法。我建议使用 GIT 并为证书创建一个新的私有存储库(例如 https://github.com/tralves/hubbychef-certs
)。该命令将创建文件 fastlane/Matchfile
。
2) 配置 match
使用你的项目和 Apple 帐户信息编辑文件 fastlane/Matchfile
。这是我的 Matchfile
的样子
git_url("https://github.com/tralves/hubbychef-certs")
storage_mode("git")
type("development") # The default type
app_identifier("dev.tiagoalves.hubbychef")
username("[email protected]") # Your Apple Developer Portal username
team_id('xxxxxxxxxx')
team_name('Tiago Alves')
将存储库加密密码添加到 .env.default
,这样你就不必每次部署时都提供密码。
MATCH_PASSWORD="xxxxxxxxx"
3) 生成证书和配置文件
你现在可以使用 match
生成新的证书和配置文件。
提示:在执行此步骤之前,请确保已从你机器的“钥匙串访问”中删除与该帐户关联的所有 Apple 开发者证书。
match
将创建并安装新的证书,这些证书可能与现有证书冲突。
为此,请运行
match development
match appstore
这将创建开发和分发证书以及它们各自的配置文件。它还将在你的机器上安装它们。如果一切顺利,你现在就可以在 Xcode 中打开项目并使用新的配置文件。你还可以看到这些文件已提交到之前创建的 GIT 存储库中。就像变魔术一样!
4) 配置 certificates
lane
现在,你可以在 Fastfile
中配置 certificates
lane
desc 'Fetch certificates and provisioning profiles'
lane :certificates do
match(type: 'development')
match(type: "appstore")
# match(type: "adhoc")
end
使用此 lane,你可以使用 fastlane ios certificates
安装所有证书。
有了所有证书和配置文件,我们现在可以着手构建步骤。在这里,我们将创建一个使用分发配置文件签名的 .ipa
,稍后可以将其发布到 TestFlight 或 App Store。这是我的 ios build
lane 的样子
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
此 lane 中的第一个操作运行命令 tns prepare ios --release --clean --env.production
,这是我们在手动部署中键入的命令。
第二个操作 match(type: "appstore")
确保安装分发证书和配置文件,并将其设置为在下一个操作中使用。
最后,build_app
操作 编译并签名 .ipa
。请注意操作中的参数
scheme
:构建方案,如 Xcode 顶部的栏中所示,通常是应用程序的名称:workspace
:指向项目 .xcworkspace
文件的路径;export_method
:导出存档的方法。在本例中,我们想要 app-store
。此时,我们可以使用以下命令生成已签名的 .ipa
fastlane ios build
如果一切顺利,你应该在项目根文件夹中看到 .ipa
。
最后一步是将 .ipa
发布到 TestFlight。查看 ios beta
lane
desc 'Ship to Testflight.'
lane :beta do
build
changelog_from_git_commits
upload_to_testflight(
beta_app_feedback_email: "[email protected]",
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: "[email protected]",
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
该 lane 从调用我们之前定义的 build
lane 开始,这样我们始终可以有一个最新构建的应用程序发送到 TestFlight。
然后,我喜欢使用 操作 changelog_from_git_commits
。默认情况下,此操作会获取自上次 GIT 标签以来的所有提交消息,并将它们用作提交应用程序到 TestFlight 时使用的变更日志。这样,你的测试人员就会知道每个版本的新功能,而你无需为此做任何事情(除了编写正确的提交消息……)。
最后一个操作 uploadtotestflight 将
.ipa
上传到 App Store Connect;如果你曾经手动执行过此过程,你就会识别出此操作中的参数与你必须反复填写的表单字段相对应。有了此配置,你只需执行以下操作
fastlane ios beta
你还可以使用 fastlane 将应用程序提交到 App Store,使用操作 upload_to_app_store
。你可以在 这里 阅读有关它的所有信息。我在本教程中没有创建该 lane,因为我自己没有尝试过,我更愿意对这一步有更多控制。不过,它应该与使用 upload_to_testflight
很相似。
我们才完成了一半!是时候创建 fastlane Android 配置了。
你可能已经拥有项目的 .keystore
文件。如果没有,请查看 这里 如何创建它。
我们将 keystore 放在 certs/hubby-chef-prod.keystore
中,并将它的秘密信息添加到 .env.default
中
KEYSTORE_PASSWORD="xxxxxxxxxxxxx"
KEYSTORE_ALIAS="dist"
KEYSTORE_ALIAS_PASSWORD="xxxxxxxxxx"
要构建 Android 应用程序,需要一个 lane 来运行 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
,最后,你应该在 platforms/android/app/build/outputs/apk/release/
下看到 app-release.apk
。
我们需要设置一个 Google Developers 服务帐户。为此,请按照以下步骤操作(或查看 fastlane 文档)
hubbychef-manager
);然后,将 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
中创建 lane
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 或生产轨道。查看 upload_to_play_store
的文档 以获取更多详细信息。
请允许我再补充说明一下我使用 fastlane 进行部署工作流程。以下是我部署新版本时采取的步骤
1) 在 package.json
中增加版本号。
不过,增加版本号存在一个问题:即使你只是部署到 Testflight,Apple 也要花数小时甚至数天的时间来审核你的应用程序。我的另一种选择是使用 这个 NativeScript 插件,它允许你将 versionNumber
参数添加到 package.json
中。这个数字将是 iOS 上的版本号。如果你只增加这个值,你的应用程序将立即被批准进行测试。这个插件还确保你获得 Android 上的递增 versionCode
。
警告:fastlane 操作
increment_build_number
无法与 NativeScript 应用程序生成流程良好配合。
2) 运行 fastlane 命令
fastlane ios beta
fastlane android alpha
3) 创建一个 git 标签
这将确保操作 changelog_from_git_commits
仅在下次部署时获取正确的提交。
fastlane 是一款很棒的工具!在这篇文章中,我们只是触及了 fastlane 可以为你做些什么的皮毛。如果你想将某些内容附加到构建流程,很有可能存在一个 操作 来实现它。我说的是诸如集成自动化测试、截取屏幕截图、Slack 机器人/报告、各种 CI 集成等等。
我知道所有这些工作看起来很繁琐,但与我最初摸索这些内容相比,这只是一小部分时间!它一定会为你节省时间和精力。部署将会变得轻而易举... 你最终会更频繁地进行部署,从而使你的用户、队友、QA 人员和老板更快乐。享受吧!