The Developer Needs to Upload a Build for This Distribution Fastlane

App developers always strive to improve the product they are working on. So information technology is definite that either(mostly) you will be adding new features to existing products or (luckily) you will be setting up a whole new projection. Either mode, onboarding new developers or bootstrapping an entirely new projection is a pretty challenging task. If not executed advisedly, technical debt arises and headaches for developers, managers, sales people, and well-nigh chiefly, clients.

Git-menstruum: A quick overview

Git flow is reasonably used in Active as well every bit conventional Waterfall-based projects as well.

Before we start our thought process nigh implementing Continous Integration and Continous Delivery, information technology is crucial to decide your own git branching model. It should resemble your development workflow to make use of CI/CD tools.

Git branching model

This article is focused on mobile applications. Therefore, nosotros volition utilise the following git branching model for which serves the purpose as an example.

Figure 1: Git Branching Model by Vincent Driessen

Git flow is essentially a merge base solution. It does non rebase the branch. As well, keeping tag proper name format vX.Y.Z-beta-N helps to generate a changelog using automated utilities.

Neither Github-period nor Git-period in its purest class can aid u.s.a. adopt a resilient development workflow. The modern tendency of Github usually seems to be having at least two branches, develop and primary where develop branch is always nether active development and principal are belongings the latest tagged releases at whatever given fourth dimension.

Git-flow(with GitHub-period tweaks) will help us come to a concrete solution for CI and CD. Of course, depending on your team sizes, yous may have a different menses, but that flow should too be resembling the above-mentioned Git Branching Model.

Implementing Continous Integration & Commitment

By definition, an automatic process or practice employed by software developers collaborating on a single software project of integrating lawmaking changes on the shared repository. This automation process may be composed of steps similar testing lawmaking, packaging, and delivering and deployment to production.

During product development, developers have frequently been requested to requite a new IPA file or APK file to the QA squad or the customer for checking and testing the features. Extending your workflow with CI/CD for unit-testing, distributing your binary tin can significantly reduce your off-development burden.

Advantages of CI/CD

CI/CD combined with git-catamenia gives many benefits such every bit the following:

  • Saves programmer time by sending automated builds to testing teams
  • Removes probability of inconsistency in builds(mainly caused due to local caching) by the guaranteed pristine build
  • Takes team engagement to the next level by encouraging open up communication and free information flow
  • Reduces programmer dependency by promoting knowledge sharing amid team members
  • Improves programmer confidence when merging code
  • Helps eliminate a class of bugs that might occur due to transmission treatment

At that place could exist de-merits of employing CI in a small team or individual developer adding overheads. However, for developers working on multiple projects with many people, CI is a wise investment with very high returns in terms of time and money.

Fastlane

Fastlane is recommended to implement CI/CD. Historically it became a function of Cloth in 2015, after acquired by Google in 2017. Withal, depending on the squad skills, you lot may implement the solution on some scripting languages like Shell Script, Cherry-red, Python etc. The community of Fastlane is vibrant, and you will notice a lot of open up-source plugins for your concern use case.

Nosotros have chosen Fastlane tools for implementing our CI/CD Solutions. It does require some knowledge of Reddish however, you don't need to be an adept to piece of work with it since information technology is implemented using Ruddy-similar to widely used iOS dependency manager CocoaPods. (+ane to Gradle for its built-in dependency management function for Android)

Manufactures on how to get started with Fastlane can exist establish here. There is reasonably practiced documentation for both iOS and Android. Nevertheless, we had difficulties finding some details related to Android Fastlane actions though we could search on forums like StackOverflow.

Modeling Git Branching Model to Fastlane

Ordinarily, each major branches in our Git Branching Model correspond to an environment equally shown in the table below:

Environs Alias/Tag Branch Description
Development alpha develop All the features for side by side or distant releases are ordinarily developed in this environment
Staging beta release/ or hotfix/ Pre-release surround
Product prod master Build made on primary always uses this environment

More complex flows may accept boosted layers of environment separation. For example, we can categorize our environment in the post-obit equally a lane (a.k.a Ruby function):

                      # Fastfile            ALIAS_MAP = {            'alpha'            =>            'Develop',            'beta'            =>            'Staging',            'prod'=>            'Product'            } ...   desc            'Build alpha IPA'            lane            :blastoff            do            |options|            build_app            # This volition be replaced with custom `build_deploy` private lane later            end            desc            'Build beta IPA'            lane            :beta            do            |options|            build_app            # This will be replaced with custom `build_deploy` private lane subsequently            end            desc            'Build production ipa'            lane            :prod            do            |options|            build_app            # This will be replaced with custom `build_deploy` private lane afterward            stop            ...                  

Listing ane

ℹ️We may utilise lane options parameters to pass command line arguments from CI YAML file.

Y'all tin can put some configuration of build_app action into Gymfile per lane basis every bit shown below:

                      # Gymfile            for_platform            :ios            do            include_bitcode            true            include_symbols            true            for_lane            :alpha            do            scheme            '<YOUR_DEV_SCHEME>'            export_method            'evolution'            # or 'enterprise' for in-business firm testing            cease            for_lane            :beta            do            scheme            '<YOUR_STAGING_SCHEME>'            export_method            'advertisement-hoc'            finish            for_lane            :prod            exercise            scheme            '<YOUR_PRODUCTION_SCHEME>'            export_method            'app-shop'            # or 'enterprise' for release            cease            end                  

Listing 2

For available configuration options for Gymfile follow the link here.

After putting above lawmaking from Listing 2 in a Gymfile, you don't need to pass relavant settings similar scheme and export_method into build_app action like below:

                      # You don't need to gear up parameters marked with 👈            # since it is handled in Gym file            build_app(            scheme:            "Release",            # 👈            export_options:            {            # 👈            method:            "app-store"            # 👈            } )                  

Listing three

ℹ️Note: We will use xcconfig to set bundle id and provisioning contour unlike Listing three

Firebase App Distribution

To distribute the congenital IPA binary to Firebase, Reading this document on how to setup Firebase App Distribution is highly recommended.

In Listing 1, we used build_app action to trigger the build. We can motility that activeness into a private_lane called build_deploy and salve duplicate code into these three principal lanes. (Cheque List 7 at the end for farther clarification)

                      desc            'Build and deploy ipa'            private_lane            :build_deploy            practice            |options|            #1. Bank check if any new commits since concluding release            is_releasable = analyze_commits(match:            "*#{options[:environment]}*")            unless            is_releasable       UI.of import            "No changes since last one hence skipping build"            next            terminate            #ii. Increment build number            increment_build_number(            build_number:            lane_context[SharedValues::RELEASE_NEXT_VERSION]            # set a specific number            )            #3. If y'all can use `match`, you use `friction match`.            setup_provisioning_profiles            #iv. Build deploy            build_app     deploy_app options            cease                  

List 4

Pace ane. Check if whatsoever new commits since the final release

analyze_commits is a third-party action for semantic release only quite helpful if y'all follow conventional commits. Information technology lets us cheque if in that location has been any alter since the last release. If there is then we go further otherwise stop with a bulletin-"No changes since the final one hence skipping build". This will help united states of america save some build minutes on the CI motorcar.

Step 2. Increment build number

We tin can keep the Marketing Version and Internal Build Version split. For example, if the Xcode project has AGV tooling enabled, we can use increment_build_number, which will automatically change the build number in the target.

Step 3. Setup Provisioning Profiles

Nosotros can use the Fastlane match command hither. In case if we don't have access, nosotros may need to install it manually using import_certificate first and and so performing FastlaneCore::ProvisioningProfile.install.

Step 4. Build and deploy

We use build_app action every bit nosotros used in Listing 1. After the IPA file is gear up we have to send it to Firebase App Distribution using deploy_app a private lane.

Deploying

We deploy to Firebase for blastoff and beta only. For prod upload either we manually upload to App Store Connect or automate information technology using upload_to_testflight action. We will limit our word to upload prod IPA as an asset on Github Release only.

The deploy_app lane is also self-explanatory as shown in the listing beneath. We tin separate the process in 5 steps:

                      private_lane            :deploy_app            exercise            |options|            environment = options[:environment]            next            if            environment ==            'prod'            # Since `prod` is uploaded to testflight and app store            #1. Generate Alter Log            notes = conventional_changelog(title:            "Modify Log",            format:            "plain")            #2. Get Google App ID            gsp_path =            "SupportingFiles/GoogleService/#{ALIAS_MAP[surround]}-Info.plist"            google_app_id = get_info_plist_value(path:            gsp_path,            key:            'GOOGLE_APP_ID')            #3. Upload to firebase            firebase_app_distribution(            app:            google_app_id,            # groups: tester_group,            release_notes:            notes,            firebase_cli_path:            FIREBASE_CLI_PATH     )            #four. Upload dSYM files to crashlytics            upload_symbols_to_crashlytics(gsp_path:            gsp_path)     clean_build_artifacts            end                  

List 5

Step 1. Generating Alter Log:

Nosotros are using the semantic-version plug-in of Fastlane to generate these logs. conventional_changelog has to exist used in conjunction with analyze_commits(which we have used in build_deploy lane to bank check is_releasable). analyze_commits takes match argument-a regex for matching with the previous git-tag like v1.0.ane-beta-5. This helps to generate logs for only between the last tag and electric current v1.0.1-beta-6.

Step two. Get Google App ID

Nosotros need google_app_id from the relevant GoogleService-Info.plist. This Plist is generated on Firebase. Our sample code project is a multi-configuration single target Xcode project. Three GoogleService plists are renamed and moved to GoogleService folder:

  • GoogleService/Develop-Info.plist
  • GoogleService/Staging-Info.plist
  • GoogleService/Product-Info.plist

We get gsp_path outset and from that we get google_app_id.

Stride 3. Upload to firebase

To use this plugin we have to install firebase CLI as well. On CircleCI inside setup control nosotros have installed npm package for firebase-cli. firebase_app_distribution is nothing only a wrapper to use the CLI to upload to Firebase. We need to requite firebase_cli_path so that the appropriate binary is used.

Step 4. Upload dSYM files to crashlytics

Finally we upload dSYM files to Firebase. This volition help Firebase brand crash reports de-symbolized and readable.

Note: When bitcode is enabled in an Xcode project, App Store recompiles the code and provides us with dSYM files. These files need to exist downloaded and uploaded to Firebase Crashlytics for crash report de-symbolization. Therefore, for the product version only we need to perform this stride. checkout download_dsym action for Fastlane.

Github Release

release_on_github is a individual lane and helps us automatically tag the commit, add release notes and attach IPA file for production, which tin can be later uploaded to App Store Connect.

Since Firebase doesn't accept APIs to download the IPA file except from installing information technology on device only-in case where you may want to requite beta releases to the client using other distribution like deploygate-You may desire to go on the IPA as a pre-release in Github release history.

Uploading IPA as an nugget

                      desc            "Release on github"            private_lane            :release_on_github            practice            |options|            environs = options[:environment]            #1. Generate Change Log            notes = conventional_changelog(title:            "Change Log")            #ii. Get Version and Build Number            version_number = get_version_number     build_number = get_build_number            #three. Set Github Release            is_prerelease = environment ==            'beta'            ?            true            :            false            proper name =            "[#{ALIAS_MAP[surroundings]}] v#{version_number}              Build:              #{build_number}}"            set_github_release(            repository_name:            "#{ENV['CIRCLE_PROJECT_USERNAME']}/#{ENV['CIRCLE_PROJECT_REPONAME']}",            name:            name,            commitish:            ENV['CIRCLE_SHA1'],            clarification:            notes,            tag_name:            "5#{version_number}-#{options[:surround]}-#{build_number}",            is_prerelease:            is_prerelease,            upload_assets:            [lane_context[SharedValues::IPA_OUTPUT_PATH]]     )            end                  

Listing 6

Step 1. Generate Change Log

conventional_changelog generates by default mark-downwards way notes. This is handy when preparing motorcar-release notes.

Step 2. Get Version and Build Number

We use these to set up the title of the release. AGV tooling should be enabled in the XCode project to utilise get_version_number and get_build_number.

Pace 3. Set Github Release

We cheque if its beta so marks it as Pre-Release. Based on the environment we format the proper name/ title for the release notes. Set the tag name in a format like v1.0.ane-beta-1234 and upload the congenital IPA file every bit an nugget to the release.

Notation: Y'all will need to set up your personal token or ci bot token to GITHUB_API_TOKEN in the environs. This token should have permission to create a tag.

Revising Main Lanes in List 1

We will skip the alpha releases on Github because they are quite frequent in releases and stored on the Firebase. Hence, y'all can salvage some infinite on Github by not tagging them and causing it hard to navigate release history on Github.

                      # Fastfile            ALIAS_MAP = {            'alpha'            =>            'Develop',            'beta'            =>            'Staging',            'prod'=>            'Production'            } ...   desc            'Build alpha IPA'            lane            :alpha            do            |options|            build_deploy options            # Not releasing to Github since Firebase App Distribution            end            desc            'Build beta ipa'            lane            :beta            do            |options|            build_deploy options     release_on_github options            end            desc            'Build product ipa'            lane            :prod            do            |options|            build_deploy options     release_on_github options            stop            ...                  

Listing 7

Matching up CircleCI configuration with Fastlane

CircleCI uses YAML files which should exist simple. When a pull request is merged or lawmaking is pushed to some branch, it may trigger a CircleCI workflow given a properly ready config.yml which in turn fires a specific lane on Fastlane.

Please advisedly note that nosotros have three environment arguments called alpha, beta and prod which you can refer in Table 2 in the alias column. Have a look at snippet of yaml file beneath:

                      ---            jobs:            deploy:            executor:            name:            default            parameters:            build_type:            type:            enum            enum:            ["alpha",            "beta",            "prod"]            # Corresponds to lanes            default:            blastoff            steps:            -            attach_workspace:            at:            /Users/distiller/project            -            run:            name:            Build            ipa            control:            package            exec            fastlane            ios            <<            parameters.build_type            >>            -            store_artifacts:            path:            output            when:            on_success                  

Following is also snippet of the same yaml file. Hither setup installs required dependency similar rubygems, npm modules, cocoapod, firebase cli, carthage etc.

                      ---            workflows:            principal:            jobs:            -            setup            -            test:            requires:            -            setup            -            deploy:            proper name:            build_deploy_alpha            build_type:            alpha            requires:            -            setup            filters:            branches:            merely:            -            develop            # RegEx            -            deploy:            name:            build_deploy_beta            build_type:            beta            requires:            -            setup            filters:            branches:            but:            -            /release\/.*/            # RegEx            -            /hotfix\/.*/            # RegEx            -            deploy:            proper name:            build_deploy_prod            build_type:            prod            requires:            -            setup            filters:            branches:            only:            -            principal            # RegEx                  

Pay special attention to the filters of the each workflow besides. They are containing Regular Expressions similar develop, /release\/.*/, /hotfix\/.*/,master.

These filters make sure that CI build is triggered simply for those branches which match to a higher place regex.alpha builds are triggered when code is pushed to develop, beta for release/* and prod for principal.

Push On Co-operative Lane executed Surround
develop bundle exec fastlane ios alpha Evolution
release/* & hotfix/* bundle exec fastlane ios beta Staging
master bundle exec fastlane ios prod Production

The only purpose of showing the above snippet is to prove you how the git branching model is practical to the CircleCI YAML file configuration and the Fastlane configuration file. Yous can learn more near CircleCI Yaml hither.

Decision

Effective development workflow and CI-CD implementation can assist reduce tons of developer hours. Similarly, the QA squad will be able to link the bugs and issues to a particular build and can have a more than productive conversation with developers. Especially, ramping upwardly time for the new developer also reduces significantly.

Resources

Sample Code Fastlane Tools Docs Firebase App Distribution Git Branching Model past Vincent Driessen AGV tooling enabled

Commodity Photo past Rasa Kasparaviciene

jonesacesturod.blogspot.com

Source: https://engineering.monstar-lab.com/en/post/2021/09/15/How-to-setup-CICD-for-iOS-App-Development-with-Fastlane-CircleCI-and-Firebase-App-Distribution/

0 Response to "The Developer Needs to Upload a Build for This Distribution Fastlane"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel