This is Part 4 of the blog series Automating the Android Build and Release Process using Fastlane. In case you haven’t read the 3 posts that precede this one, here are links to Part 1, Part 2 and Part 3.
这是博客系列使用Fastlane自动化Android构建和发布过程的 第4部分 。 如果您还没有阅读该文章之前的3篇文章,那么这里有指向第1 部分 , 第2 部分和第3 部分的链接。
This will be a somewhat long and detailed post, so I would recommend that you grab a cup of coffee as you begin reading this. ☕️ 这是一篇篇幅较长且详细的文章,所以我建议您在开始阅读本文时先喝杯咖啡。 ☕️
The first step is to set up build variants depending on your project's requirements. At my current place of work, we have dev, qa, and production environments which point to different endpoints.
第一步是根据项目要求设置构建变体。 在我当前的工作地点,我们有指向不同端点的dev , qa和生产环境。
So we create build variants of our apps to cater for these environments. Add these under the productFlavors {} closure under app/build.gradle
因此,我们创建了应用程序的构建变体以适应这些环境。 将这些添加到app / build.gradle下的productFlavors {}闭合下
dev { dimension "env" applicationIdSuffix = ".dev"}qa { dimension "env" applicationIdSuffix = ".qa"}prod { dimension "env" applicationIdSuffix = ".prod"}We need to create google-services.jsonfiles for the new build variants we have created (i.e)dev and qa
我们需要为我们创建的新构建变体(即dev和qa )创建google-services.json文件。
Firebase Dashboard
Firebase仪表板
In the Firebase console, click on the Project Overview icon and select Project Settings. This will load the screen below:
在Firebase控制台中,单击“ 项目概述”图标,然后选择“项目设置”。 这将加载以下屏幕:
Project Settings
项目设定
Click the Add App button and it will launch the screen below:
单击添加应用程序按钮,它将启动以下屏幕:
Firebase Setup
Firebase设定
Update decode_gservices_key in the config.yml file to reflect for the dev and qa environments we have added.
在config.yml文件更新decode_gservices_key,以反映我们已经加入了开发和QA环境。
# ---------------------------------------------------------------------------------------------------------------------# DECODE FIREBASE GOOGLE_SERVICE_JSON FILE AND WRITE IT TO A FILE# --------------------------------------------------------------------------------------------------------------------- decode_gservices_key: &decode_gservices_key run: name: Decode Google Services JSON key command: | echo $GOOGLE_SERVICES_JSON | base64 -d | tee app/google-services.json app/src/mock/google-services.json app/src/prod/google-services.json app/src/dev/google-services.json app/src/qa/google-services.json >/dev/nullNOTE: You also need to update new google-services.json file on the Circle CI Environment Variables. Refer to my previous blog post on how to do this as highlighted in Step 4 under Firebase App Distribution. Delete the old key and create a new one with the same name. GOOGLE_SERVICES_JSON 注意:您还需要在Circle CI环境变量上更新新的google-services.json文件。 请参阅我以前的博客文章有关如何执行此操作的内容,如Firebase App Distribution下的第4步中突出显示。 删除旧密钥并创建一个具有相同名称的新密钥。 GOOGLE_SERVICES_JSON
I will set up the different build variants to do run different actions:
我将设置不同的构建变体以执行不同的操作:
2. qa variant: With this variant, I will do the jobs like in dev variant but will add the following:
2. qa变体 :使用这个变体,我将像dev变体中那样进行工作,但将添加以下内容:
3. pro variant: With this variant, I will do the jobs like in qa variant but will add the following:
3. pro变种 :使用此变种,我将像在qa变种中一样进行工作 但会添加以下内容:
We will have 3 branches in the Github repository:
Github存储库中将有3个分支:
Now let’s start work on the Fastfile . We will create lanes to run builds, tests and deploy APKs. Then every lane should have parameters for build type (Debug, Release) and build flavor (dev, beta, pro). This will make more sense as we go along with the rest of the steps.
现在让我们开始在Fastfile上工作。 我们将创建用于运行构建,测试和部署 APK的通道。 然后,每个通道应具有用于构建类型 (调试,发布)和构建风格 (开发,测试版,专业版)的参数。 在进行其余步骤时,这将更有意义。
Let’s create a lane named assemble_build to build our app. This lane builds our app with specified buildVariant (buildFlavor + buildType)
让我们创建一个名为assemble_build的通道来构建我们的应用程序。 此通道使用指定的buildVariant ( buildFlavor + buildType )构建我们的应用程序
desc "Assemble Build"lane :assemble_build do |options| gradle( task: "assemble", flavor: options[:build_flavor], build_type: options[:build_type] )end|options| is your lane parameters. For more about lane parameter, you can read this at Advance Lanes. |选项| 是您的车道参数。 有关车道参数的更多信息,您可以在 Advance Lanes 阅读 。
To run assemble_build lane with parameters above we can run the command below:
要使用上面的参数运行assemble_build通道,我们可以运行以下命令:
$ bundle exec fastlane assemble_build build_flavor:"YourBuildFlavor" build_type:"YourBuildType"
$ bundle exec fastlane assemble_build build_flavor:"YourBuildFlavor" build_type:"YourBuildType"
We will update the unit_tests lane to run unit tests for the specified build variant of our app.
我们将更新unit_tests通道,以针对应用程序的指定构建变体运行单元测试。
desc "Run Unit Tests"lane :unit_tests do |options| gradle( task: "test", flavor: options[:build_flavor], build_type: options[:build_type] )endIn the Fastfile, add a lane to do the work of running instrumented tests. I used this Fastlane Doc as a reference:
在Fastfile中,添加一个通道来执行运行测试的工作。 我使用此Fastlane文档作为参考:
desc "Run Instrumented tests"lane :instrumented_tests do |options| gradle(task: "connectedProdDebugAndroidTest")endWe will create a lane named instrumentation_test that leverages the Firebase Test Lab to run the UI tests. To use Firebase Test Lab in your project:
我们将创建一个名为instrumentation_test的通道,该通道利用Firebase测试实验室来运行UI测试。 要在您的项目中使用Firebase测试实验室 ,请执行以下操作:
5. Click on the CREATE SERVICE ACCOUNT button and fill in Service Account Name. Then click the CREATE button as seen in the screenshots below:
5.单击创建服务帐户按钮,然后填写服务帐户名称 。 然后单击CREATE按钮,如以下屏幕截图所示:
6. On the next screen under the Select a role drop-down filter, select Project > Owner then click the Continue button. See the screenshot below:
6.在“ 选择角色”下拉过滤器下的下一个屏幕上,选择“ 项目”>“所有者”,然后单击“ 继续”按钮。 请参见下面的屏幕截图:
7. The 3rd screen is optional, so just click the Done button. See the screenshot below:
7.第三个屏幕是可选的,因此只需单击“ 完成”按钮。 请参见下面的屏幕截图:
8. This will return you back to the Service Accounts screen where you can see your new service account. Click on the overflow button, then select the CREATE KEY > Choose JSON > Create as seen in the screenshot below:
8.这将使您返回“服务帐户”屏幕,您可以在其中看到新的服务帐户。 单击溢出按钮,然后选择CREATE KEY>选择JSON> Create,如下面的屏幕截图所示:
9. The result will download the private key json file to your computer for you to leverage in your project.
9.结果将把私钥json文件下载到您的计算机,供您在项目中使用。
fastlane-droid-8684e207a8fe.json — This is the downloaded file that contains the GCLOUD_SERVICE_KEY needed below. fastlane-droid-8684e207a8fe.json-这是下载的文件,其中包含以下所需的GCLOUD_SERVICE_KEY。
Now that we have the JSON file from Google Cloud, we just need to add and configure the Fastlane plugin.
现在我们有了来自Google Cloud的JSON文件,我们只需要添加和配置Fastlane插件。
Create a new lane to run Instrumented Tests in the Fastfile. Update this lane and leverage the assemble_build lane we created earlier.
在Fastfile中创建一个新的通道来运行仪器测试。 更新此通道并利用我们之前创建的assemble_build通道。
desc "Run Instrumented tests in Firebase Test Lab" lane :instrumentation_tests_firebase_testlab do |options| assemble_build(build_flavor:options[:build_flavor], build_type:"Debug") @app_apk = Actions.lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] assemble_build(build_flavor:options[:build_flavor] + "Debug", build_type:"AndroidTest") @android_test_apk = Actions.lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] run_tests_firebase_testlab( project_id: ENV["FIREBASE_PROJECT_ID"], app_apk: @app_apk, android_test_apk: @android_test_apk, devices: [ { model: "Nexus6P", version: "27" } ], delete_firebase_files: true ) endYou can see available devices here and if you want to check all the parameters that you can use, just take a look at the fastlane-plugin-run_tests_firebase_testlab README file.
您可以在此处查看可用的设备,如果要检查所有可以使用的参数,只需看一下fastlane-plugin-run_tests_firebase_testlab README文件。
Now, to run the tests in Firebase TestLab, the plugin needs three things:
现在,要在Firebase TestLab中运行测试,插件需要三件事:
NOTE: Since we have created assemble_build , we can build both app apk and android test apk. 注意:由于我们已经创建了assemble_build ,因此我们可以同时构建app apk和android test apk。
Now let’s take a look at lane above:
现在让我们看一下上方的车道:
@app_apk and @android_test_apk : are variables to store the APKs after we build app.
@app_apk和@android_test_apk :是在我们构建应用后用于存储APK的变量。
Actions.lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] : This is the fastlane gradle output variable. We can get the APK path from it. For more details you can run: $ bundle exec fastlane action gradle
Actions.lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] :这是fastlane gradle输出变量 。 我们可以从中获取APK路径。 有关更多详细信息,您可以运行: $ bundle exec fastlane action gradle
To run Firebase Test Lab with Fastlane, we have another step to finish:
要使用Fastlane运行Firebase测试实验室,我们需要完成另一个步骤:
The screenshot below shows the 2 major env variables that you should add to your Circle CI:
以下屏幕截图显示了应添加到Circle CI的2个主要env变量:
[1] GCLOUD_SERVICE_KEY - These are the contents of the private key json file that we downloaded above.[2] FIREBASE_PROJECT_ID - This is one of the properties found in the private key json file.
Note: Don’t commit your .env file & the firebase directory to source control. 注意 :不要将 .env 文件和 .env 目录 提交 到源代码管理。
NOTE: If the command fails, you can try cleaning the project first before running it. 注意:如果命令失败,则可以先尝试清洁项目,然后再运行它。
We will start by creating the different branches & have them point to different deployment pipelines.
我们将从创建不同的分支开始,并让它们指向不同的部署管道。
Update the config.yml file and link the build variants to the respective branches.
更新config.yml文件,并将构建变体链接到相应的分支。
[1] We’ll start with `test_unit` job.
[1]我们将从“ test_unit”工作开始。
## Run unit teststest_unit:<<: *android_configsteps:- checkout- *restore_gradle_cache- *restore_gems_cache- *android_dependencies- *ruby_dependencies- *save_gradle_cache- *save_gems_cache- *decode_gservices_key- run: name: Run unit tests command: | if [ -z "$CIRCLE_PULL_REQUEST" != "" ]; then echo "Doing a Pull Request Build for ${CIRCLE_PULL_REQUEST}." bundle exec fastlane unit_tests build_flavor:"dev" build_type:"debug" elif [ "${CIRCLE_BRANCH}" == "master" ]; then echo "Doing a Build on the ${CIRCLE_BRANCH} branch." bundle exec fastlane unit_tests build_flavor:"qa" build_type:"debug" elif [[ "${CIRCLE_BRANCH}" =~ ^release-.*$ ]]; then echo "Doing a Build on the ${CIRCLE_BRANCH} branch." bundle exec fastlane unit_tests build_flavor:"prod" build_type:"release" else echo "Doing a default Build on the ${CIRCLE_BRANCH} branch." bundle exec fastlane unit_tests build_flavor:"dev" build_type:"debug" fi- store_artifacts: path: app/build/reports/ destination: /reports/- store_test_results: path: app/build/test_results/ destination: /test-results/[2] `test_instrumentation` job.
[2]“ test_instrumentation”作业。
# Run Instrumentation Tests test_instrumentation: <<: *android_config steps: - checkout - *restore_gradle_cache - *restore_gems_cache - *android_dependencies - *ruby_dependencies - *save_gradle_cache - *save_gems_cache - *decode_gservices_key - run: name: Run Instrumented Tests - (Espresso Tests) command: | if [ -z "$CIRCLE_PULL_REQUEST" != "" ]; then echo "Run Instrumented Test for the Pull Request Build ${CIRCLE_PULL_REQUEST}." bundle exec fastlane instrumentation_tests_firebase_testlab build_flavor:"dev" elif [ "${CIRCLE_BRANCH}" == "master" ]; then echo "Run Instrumented Test on the ${CIRCLE_BRANCH} branch." bundle exec fastlane instrumentation_tests_firebase_testlab build_flavor:"qa" elif [ "${CIRCLE_BRANCH}" =~ ^release-.*$ ];then echo "Run Instrumented Test on the ${CIRCLE_BRANCH} branch." bundle exec fastlane instrumentation_tests_firebase_testlab build_flavor:"prod" else echo "Run Instrumented Test for a default Build on the ${CIRCLE_BRANCH} branch." bundle exec fastlane instrumentation_tests_firebase_testlab build_flavor:"dev" fi - store_artifacts: path: app/build/outputs/ destination: /outputs/ - store_test_results: path: app/build/outputs/ destination: /outputs/Next, we will create a job to deploy a production build variant of our app to the Google Play Console Internal Test track. To upload our APK & metadata to the play store, we will leverage the fastlane supply tool.
接下来,我们将创建一个工作 将我们的应用的正式生产版本部署到Google Play控制台 内部测试轨道。 要将APK和元数据上传到Play商店,我们将利用Fastlane 供应工具。
Since supply needs authentication information from Google, we will implement the Setting Up Supply steps from Fastlane Docs, some of which are covered below:
以来 供应 需要Google的身份验证信息,我们将实施“ 设置供应” 脚步 来自Fastlane Docs,其中一些内容如下:
Supply is a Fastlane tool that uploads app metadata, screenshots, and binaries to Google Play Console. You can also select specific tracks(internal test, alpha, beta) for your builds and promote builds to the production.
Supply是Fastlane工具,可将应用程序元数据 , 屏幕截图和二进制文件上传到Google Play控制台。 您还可以为构建选择特定的曲目(内部测试,Alpha,Beta),并将构建升级到产品中。
We will begin with the first step of collecting our Google credentials.
我们将从收集Google凭据的第一步开始。
NOTE: In my case, since I hadn’t worked with the API Access before, I had to link my account to a Google Developer Project to enable API access for my account. 注意:就我而言,由于我以前从未使用过API Access,因此必须将我的帐户链接到Google Developer Project才能为我的帐户启用API访问权限。
3. Click the CREATE NEW PROJECT button. This sets up our account and updates the screen to show the contents below:
3.单击创建新项目按钮。 这将设置我们的帐户并更新屏幕以显示以下内容:
API Access — Create Service Account
API访问权限-创建服务帐户
4. Click CREATE SERVICE ACCOUNT button & it will launch the dialog below:
4.单击创建服务帐户按钮,它将启动以下对话框:
5. Follow the Google Developers Console link in the dialog, which opens a new tab/window:
5. 单击对话框中的Google Developers Console链接,这将打开一个新的标签/窗口:
6. Provide a Service Account Name & Service Name Description and click the Create button.
6.提供服务帐户名称和服务名称描述 ,然后单击创建按钮。
7. Click Select a role and choose Service Accounts > Service Account User
7.单击选择角色,然后选择服务帐户>服务帐户用户。
8. Click the Create Key button & make sure JSON is selected as the Key Type.
8.单击创建密钥按钮,并确保选择JSON作为密钥类型 。
9. Click Done button to close the dialog & you should see the screen containing your newly created service account details:
9.单击“完成”按钮关闭对话框,您应该会看到包含新创建的服务帐户详细信息的屏幕:
Take note of the file name of the above JSON file downloaded to your computer. 记下下载到您计算机上的上述JSON文件的文件名。
fastlane run validate_play_store_json_key json_key:/path/to/your/downloaded/file.jsonIf all works well, you should see a message similar to this in your console:
如果一切正常,您应该在控制台中看到类似以下消息:
Edit your fastlane/Appfile and change the json_key_file line to have the path to your credentials file:
编辑您的fastlane / Appfile并更改json_key_file行以获取凭证文件的路径:
json_key_file "/path/to/your/downloadedWe also need to ensure that we add the base64 encoded version of the google-play-json-key-file.json to the Circle CI environment variables.
我们还需要确保将google-play-json-key-file.json的base64编码版本添加到Circle CI环境变量中。
NOTE: We will need to update the config.yml file to decode this JSON Key and make it available to the Appfile in our project. See the gist below:
注意:我们将需要更新config.yml文件 解码此JSON密钥,并将其提供给我们项目中的Appfile 。 请参阅以下要点:
# --------------------------------------------------------------------------------------------------------------------- # DECODE GOOGLE_PLAY_JSON_KEY AND WRITE IT TO A FILE # --------------------------------------------------------------------------------------------------------------------- decode_gplay_key: &decode_gplay_key run: name: Decode Google Play JSON key command: | echo $GOOGLE_PLAY_JSON_KEY | base64 -d | tee google-play-json-key-file.json >/dev/nullIf your app has already been deployed & approved on the play store, you’re ready to start using supply to manage it.
如果您的应用已经在Play商店中部署并获得批准,则可以开始使用供应商对其进行管理了。
When you run the action fastlane supply init, all of your current Google Play store metadata will be downloaded to fastlane/metadata/android.
当您运行action fastlane供应初始化时 ,所有当前的Google Play商店元数据都将下载到fastlane/metadata/android 。
In my case, I experienced an error although the process was successful. It downloaded all the metat data except the changelogs directory. 就我而言,尽管过程成功,但我还是遇到了错误。 它下载了除changelogs目录之外的所有metat数据。 I did some research online but didn’t seem to find a solution at the writing of this post. I have submitted the issue to the fastlane repo here. 我在网上做了一些研究,但在撰写本文时似乎没有找到解决方案。 我已将问题提交到这里的fastlane仓库。
desc "Deploy latest version to Google Play" lane :playstore do |options| gradle( task: "assemble", flavor: options[:build_flavor], build_type: options[:build_type], properties: { "android.injected.signing.store.file" => "fastlane-droid.jks", "android.injected.signing.store.password" => ENV['STORE_PASSWORD'], "android.injected.signing.key.alias" => ENV['KEY_ALIAS'], "android.injected.signing.key.password" => ENV['KEY_PASSWORD'], } ) # Uploads the APK built in the gradle step above and releases it to an internal test track upload_to_play_store(track:'internal') endTo test this out, run this command on your command-line interface:
要进行测试,请在命令行界面上运行以下命令:
bundle exec fastlane playstore build_flavor:"prod" build_type:"release"The command generates and deploys a prodRelease build variant of the application. The output will look something similar to this:
该命令生成并部署应用程序的prodRelease构建变体。 输出将类似于以下内容:
You will also see the new release on the track that you released it to, in our case the Internal test track:
您还将在发布它的轨道上看到新版本,在我们的示例中为内部测试轨道:
The reason why we use the Internal Test track then promote to Production instead of directly pushing to Production is to provide the ability for QA testing to ensure the application is stable before being shipped to our users. 我们之所以使用内部测试轨道而不是直接推动生产而不是直接推动生产,是为了提供质量检查测试的功能,以确保应用程序在交付给用户之前是稳定的。
Here we will add the final touches to the config.yml file.
在这里,我们将最后的修饰添加到config.yml文件中。
In the workflow below, we start by executing the job that runs our unit tests ( test_unit). Then we specify the test_instrumentation job that requires the test_unit job to finish running successfully.
在下面的工作流程中,我们首先执行运行单元测试的工作( test_unit )。 然后,我们指定test_instrumentation需要工作test_unit作业完成运行成功。
If both of the jobs that run the tests terminate without errors, we still have other jobs. But they will only run when we push code to master or release branches.
如果运行测试的两个作业均无错误终止,则我们还有其他作业。 但是它们仅在我们将代码推送到master或release分支时才运行。
workflows: version: 2 workflow: # Jobs that will run when you push to your repo jobs: - test_unit - test_instrumentation: requires: - test_unit - slack_deployment: filters: branches: only: - master requires: - test_instrumentation - firebase_app_distribution: requires: - test_instrumentation - playstore_deployment: filters: branches: only: - /^release-[0-9]+\.[0-9]+\.[0-9]+$/ requires: - test_instrumentationFor the full .circleci/config.yml file, you can find here.
有关完整的.circleci/config.yml文件,可以在此处找到。
If you have gotten to this point, Congratulations!!
如果您到了这一步,恭喜!
Below is a video showing how our build works across the different build environments.
下面的视频显示了我们的构建如何在不同的构建环境中工作。
I know that this post has a lot of information & I thought that creating a companion video showing you how the completed project works would be of great use.
我知道这篇文章有很多信息,我认为创建一个伴随视频向您展示完成的项目的工作方式很有用。
If you have any questions, feel free to reach out. Feedback is also welcome.
如有任何疑问,请随时与我们联系。 也欢迎反馈。
I plan on writing a final blog post that will incorporate topics like:
我计划写一篇最终的博客文章,其中将包含以下主题:
Thank you for reading.
感谢您的阅读。
Here’s the link to the branch for this example on Github
这是Github上此示例的分支链接
翻译自: https://proandroiddev.com/automating-the-android-build-and-release-process-using-fastlane-circle-ci-part-4-32f78b6ac876
fastlane 构建传参
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删