Fastlane combat (two): Action and Plugin mechanisms

As architects, we often have to face a difficult problem is the selection of technology. Whether it is business or open source projects or alternatives is too much, which is good for this requires us to emerge in an endless stream, when the technology selection, the need to consider from multiple dimensions, including good scalability is our object of focus considerations.

Any good framework or platform should have good scalability, in order to meet the changing business scenario and individual requirements, and one aspect of this expansion is reflected in: whether it can provide a mechanism, this mechanism can not only meet the convenience of development two times, and even to minimize the original system produces any intrusion or damage.

Standing on this point, today we will introduce the two extensions of Fastlane, Action and Plugin.

Action mechanism of Fastlane

Fastlane itself contains two modules, one is the kernel part, the other is Action. Action is the smallest unit of execution Fastlane automation in the process of visual speaking is a Fastfile script in a command, such as: git_pull, deliver, pod_install and so on, and these commands behind corresponds to a script written in Ruby.

I guess the authors of Fastlane planning and even early in the project stage, should consider this: in mobile development, automation of business scene too much, each team has its own special requirements, is unable to meet only by the power of one or two, so how to function the actual business development, with elegant way to the open source community huge engineers to maintain, become the focus of consideration in the architecture of Fastlane content.

Therefore, through continuous exploration, discussion and practice, the Action expansion mechanism came into being. We can understand the establishment of a complete set of rules for Fastlane, this rule is so easy, either official engineer or engineers in the open source community, everyone in the game rules, it will not only reduce the threshold of the expansion, to attract engineers to improve and enhance the Fastlane itself; constraints, reduce unnecessary communication cost and code inspection. So we can see whether it is the official contribution, or the contribution of the Github community Action who, without exception, are part of the Action extension.

So far, Fastlane contains about more than and 170 Action, roughly divided into the following categories:

  1. The mobile terminal and the continuous delivery of 15 core related tool chain: such as: deliver (upload IPA, screenshots and meta information to ITC supply (APK), upload, screenshots and meta information to Google Play sigh (iOS), Provisioning file management and so on), the details are as follows: https:// github.com/fastlane/fastlane#fastlane-toolchain
  2. And iOS related, such as: IPA, xcode_install, etc.
  3. And Android related, such as: gradle, ADB, etc.
  4. Related to version control, such as git_pull, hg_push, etc.
  5. And iOS dependent library management related, such as: cocoapods, Carthage, etc.
  6. Third party platform docking related, such as: hipchat, JIRA, twitter, slack, etc.

The details of these Action and usage methods can be viewed in this link: https://docs.fastlane.tools/actions/Actions/.

It should be said that almost all of the common scenes, but if you still can not fully meet the requirements, it is necessary to customize their own.

Scene analysis

So how do you define a Action? According to the habit, in order to facilitate our understanding, we start with a business scenario. In the previous article, I used to cite an example: the release of private Pod, the steps are as follows:

  1. Increase the version number in Podspec
  2. Perform pod lib lint command for library validation
  3. Git Commit code
  4. Git Push code to the far end
  5. Hit a Git Tag
  6. Will Tag Push to the far end
  7. Execute pod repo push command library to private warehouse

Then, in response to the above steps, we can find a ready-made Action to achieve, so we can add the following Lane in Fastfile:

Desc "Release new private pod version Lane do |options| target_version: do_release_lib: version] = options[project = options[project] path =" #{project}.podspec "git_pull ensure_git_branch master pod_install pod_lib_lint confirmed # branch (verbose: true, allow_warnings: true, sources: SOURCES, use_bundle_exec: true, fail_fast: true version_bump_podspec (path:) path, version_number: target_version) # update podspec git_commit_all (message:" Bump version to #{target_version} ") # submitted version modified add_git_tag (tag: target_version) # set tag push_to_git_remote # pushed to the GIT warehouse pod_push (path: path, repo:" GMSpecs "allow_warnings:, true, sources:, SOURCES) # submitted to the private warehouse end

Custom Action

Here, we may ask, this is not finished, do you need to customize the Action ah? Do not worry, in fact, about 3 months ago, when I write this Fastfile, Fastlane just a lack of a Action can support the Cocoapods command, that is, the:

Pod lib lint

This command is used to verify whether the private Pod library is correct, so at the time, under the helpless, can only write a. After finishing the work that is not so difficult to imagine, Fastlane has been providing ready-made templates for us, even if you are not familiar with the syntax of the Ruby, but also Never mind, Fastlane is open source, can directly download the source code to see other people’s Action will know how to write, we can find all the Action files in this directory:

Fastlane/fastlane/lib/fastlane/actions/

The custom Action process is as follows. First, we execute commands in the terminal:

Fastlane new_action

Then according to the prompt, in the command line in the name of action pod_lib_lint, and Fastlane in the current directory in the actions folder to help us create a pod_lib_lint.rb Ruby file, as follows (omitted key part):

Module Fastlane module Actions class PodLibLintAction < Action def self.run (params) UI.message Parameter API Token: #{params[api_token]}: "end... Def... Self.available_options [FastlaneCore:: ConfigItem.new (key:: api_token, env_name: FL_POD_LIB_LINT_API_TOKEN, The name of the environment variable # description:" API Token for PodLibLintAction a short description of this, # parameter verify_block: proc do |value| UI.user_error ("No API token! For PodLibLintAction given, pass using `api_token:'token'` unless (value and) Not value.empty?) end,...] end end end

As you can see, the custom Action are part of the Fastlane/Actions module, and inherited from the Action class. Although the contents of the template is quite a lot, but do not worry, most of the content is a simple text description, for us to focus only on the two methods on the line:

  1. Self.run method: here is the actual business processing code.
  2. Self.available_options method: here, we declare that the parameters need to be exposed to the outside.

Before we start to write the actual business code, we need to understand the business logic of the Action specific, so we first analyze the Cocoapods lib lint command in the terminal execution

Pod lib lint –help

Terminal print out (save only key part)

Usage: lib lint Validates the $pod Pod using the files in the working directory. Options: --quick Lint skips checks that would require to download and build the spec --allow-warnings Lint validates even if warnings......

You can see that this command contains many options (Options), and we need to do is to put these options are mapped to the parameters in action, so we next according to the option type, declared in the self.available_options, the code below (only key part):

Def self.available_options [FastlaneCore:: ConfigItem.new (key:: use_bundle_exec, description: Use bundle exec when there is a Gemfile presented is_string: false, default_value:, true, FastlaneCore:): ConfigItem.new (key:: verbose, description: Allow ouput detail in console optional: true, is_string:, false) end...]...

The statement after the final write business logic in the self.run method, at the same time, the above options exposed by params, so that when the operation of pod_lib_lint action, we can pass the corresponding parameters, so that the Fastlane can perform complete orders to carry various options, as shown in the following code (only key part):

Def self.run (params) command = [] command < < "bundle exec" if File.exist? ("Gemfile") & & params[: use_bundle_exec] command < < "pod lib lint" command < "--verbose" if; < params[: verbose] command < < --allow-warnings if params[allow_warnings]... Result... = Actions.sh (command.join ('')) UI.success ("Pod lib lint Successfully return result end")

As can be seen from this code, the key point lies in the Actions.sh (), so we want to ensure that the SH method performed here is consistent with the output of the command and pod lib commands in the terminal, for example, lint:

Pod lib –quick –verbose –allow-warnings lint –use-libraries

Finally, we copy the pod_lib_lint.rb to the fastlane/actions folder under the iOS project, and then execute the following command in the project directory:

Fastlane action pod_lib_lint

If there is no error, the terminal will output the following:

Fastlane combat (two): Action and Plugin mechanisms
image

In fact, originally wrote this Action, I just intend to use the team, and did not contribute to the Github plan, so only a part of the parameters. We used for some time, feeling more stable, it will be all parameters are completed, and then contributed to the main Fastlane warehouse, the address is as follows:

Https://github.com/fastlane/fastlane/blob/master/fastlane/lib/fastlane/actions/pod_lib_lint.rb

Here to say a digression:
code for the open source project is submitted, the whole process will be more stringent, in addition to function without Bug, unit tests need to be completely covered, there are certain requirements for syntax soft index. When submitted to pull request, Github will be the first to use automation tools (HoundCI and CircleCI) to conduct a comprehensive inspection, through to the Code Review team only after artificial Check, so the usual code of the bad habit of students need to pay more attention to.

Plugin mechanism of Fastlane

We often encounter this scenario when using Fastlane:

  1. My custom Action needs to be used in multiple internal projects
  2. I think this custom Action is very good, want to share with other teams

At this point, copy paste can solve the problem, but it is not a clever plan. Action released to the official Fastlane warehouse is a good choice, but the official warehouse itself to Action requirements are relatively high, and will not accept non universal Action, even if the receiving, the release cycle will be relatively long, but after either upgrade or repair Bug, depending on the Fastlane version itself and greatly reduces the flexibility.

So from the beginning of 1.93, Fastlane provides a mechanism for Plugin to solve this problem. We can be understood as: Plugin is on the basis of Action made a layer of packaging, the packaging of clever use of RubyGems the mature Ruby library management system, so it can be installed independently of the Fastlane main warehouse for search, delete, and release.

We can even simply think: Plugin is the RubyGem package Action, we can manage the same as RubyGems Fastlane management Plugin.

Install Plugin

So far, about 30 Plugin have been released to RubyGems, and we can find the following commands:

Fastlane search_plugins [query]

Details can be seen here
AvailablePlugins

Assuming that our project needs to use a git called version_from_last_tag, which is used to obtain the latest tag, then we perform the project directory in the terminal:

Fastlane add_plugin version_from_last_tag

After completion of the addition, the project will be more of a Gemfile, Gemfile.lock, fastlane/Pluginfile three files, of which the Pluginfile is actually a Gemfile, which contains Plugin for reference, the format is as follows:

# Autogenerated by Fastlane Ensure this file # # is checked in to source control gem'fastlane-plugin-version_from_last_tag'!

The Pluginfile itself has been cited by Gemfile, so it confirms the above statement: Plugin management is actually the management of RubyGem.

After the Plugin is the actual usage and the use of Action is the same, so we do not repeat here.

Release Plugin

If you want to publish a Plugin, you can choose as a Gem to RubyGems, so we can through the search_plugins command to search; can also choose to submit only code to Github, and then provide a GitHub address to other projects or team use, then the need for such declaration in a Pluginfile:

Gem "fastlane-plugin-version_from_last_tag", git: "https://github.com/jeeftor/fastlane-plugin-version_from_last_tag"

Before the release, in order to facilitate local debugging, you can point to the local gem, Pluginfile in this statement:

Gem "fastlane-plugin-version_from_last_tag", path: "../fastlane-plugin-version_from_last_tag"

With the Plugin, Fastlane update frequency greatly reduced, the number of Action on the main warehouse will remain at the current level, instead of the increasing number of Plugin. Companies and teams can choose their own Plugin, you can also release Plugin anytime, anywhere to other teams.

epilogue

With Action, to enhance the scalability of the Fastlane greatly, we can easily prepare for their own business scene tools; Plugin, and on the basis of scalability greatly enhances the flexibility of the two together can be used the advantages of Fastlane repeat play.

Usually, if a tool is only intended to be used in a project, it is recommended that the direct use of Action, after all, a Ruby script can be solved, the cost is relatively low; if you intend to multiple projects and even cross team use, so it is recommended to use Plugin.

More detailed description of the Action and Plugin can view the official document:

Action:https://docs.fastlane.tools/actions/Actions/
Plugin:https://docs.fastlane.tools/plugins/CreatePlugin/

The current two articles in the context and content are related to the iOS, the next article, I will explain in detail how to apply Fastlane to the Andriod platform.