4 minute read

Fastlane, plugin them all

Introduction

Have you ever dealt with a long-long Fastfile or a bunch of fastlane actions or even any build scripts that hang out side-by-side with a source code of your project and turned to be completely unreadable? Then I have a modern architectural idea to make such things less complicated and much more readable, reliable and extendable.

I suggest to craft your own private fastlane plugin that will wrap everything you have around building and such things and return you a gorgeous DIY DSL that can be used in your Fastfile. It might sound a little vague and complicated, but this is really awesome sauce, see, you will love it! Very-very roughly it will look like this:

  • Terminal
brew install fastlane
fastlane add_plugin awesome_sauce
  • Fastfile
lane :awesome_lane do
  edit_some_weird_properties # this action comes from my awesome sauce fastlane plugin
  my_hackish_way_to_build # same for this one
  my_tricky_way_to_test # same here
  ok_boy_ship_it # same
end

Auto-generating the plugin

  1. First of all let’s install fastlane if you have not done it yet:

     brew install fastlane
    
  2. Cool, now we can create our plugin, let’s name it awesome_sauce:

     fastlane new_plugin awesome_sauce
    
  3. Enter a description and short summary of your choice
  4. And that’s it, fastlane generated a template for us, check it out:

     ls fastlane-plugin-awesome_sauce
    

Crafting the plugin

Let’s add some super simple features to our plugin for proof of concept purposes. For instance minus and plus, just to show how these two actions will live side-by-side. Sure, these actions are useless, but who said that you can’t do some really cool stuff on your own? This is just a POC after all (:

  • Let’s start from the minus action:
  1. Go to the actions folder:

    cd fastlane-plugin-awesome_sauce/lib/fastlane/plugin/awesome_sauce/actions
    
  2. Rename awesome_sauce_action.rb to minus_action.rb and open the file
  3. Rename the class name AwesomeSauceAction to MinusAction in minus_action.rb file
  4. Fill the description:

     def self.description
         "Subtracts one number from another"
     end
    
  5. Add available options:

     def self.available_options
     [
         FastlaneCore::ConfigItem.new(
             key: :x,
             description: "The number from which to subtract",
             optional: false,
             is_string: false
         ),
         FastlaneCore::ConfigItem.new(
             key: :y,
             description: "The subtracted number",
             optional: false,
             is_string: false
         )
     ]
     end
    
  6. Сreate a method for calculation in the helper/awesome_sauce_helper.rb file:

     def self.minus(x:, y:)
         x - y
     end
    
  7. Call this method in minus_action.rb file:

     def self.run(params)
         Helper::AwesomeSauceHelper.minus(
             x: params[:x],
             y: params[:y]
         )
     end
    
  • Let’s do the same for the plus action:
  1. Copy minus_action.rb and rename the copy to plus_action.rb
  2. Rename the class name MinusAction to PlusAction in plus_action.rb file
  3. Change the description:

     def self.description
         "Adds one number to another"
     end
    
  4. Change the description of available options:

     def self.available_options
     [
         FastlaneCore::ConfigItem.new(
             key: :x,
             description: "The number to which to add",
             optional: false,
             is_string: false
         ),
         FastlaneCore::ConfigItem.new(
             key: :y,
             description: "The number to be added",
             optional: false,
             is_string: false
         )
     ]
     end
    
  5. Сreate a method for a new calculation in the helper/awesome_sauce_helper.rb file:

     def self.plus(x:, y:)
         x + y
     end
    
  6. Call this method in plus_action.rb file:

     def self.run(params)
         Helper::AwesomeSauceHelper.plus(
             x: params[:x],
             y: params[:y]
         )
     end
    

Here we go, our mega simple plugin is almost ready to use!

Testing the plugin

We all know there are some cowboy rules, so let’s add the tests to our plugin.

  1. Go to the specs folder:

     cd spec/
    
  2. Open awesome_sauce_action_spec.rb and clean it up
  3. Describe a class we gonna test:

     describe Fastlane do
         describe Fastlane::FastFile do
             describe 'Very limited calculator' do
                 it 'is dummy test' do
                     expect(42).to eq(42)
                 end
             end
         end
     end
    
  4. Add some tests for minus action:

     it 'minus positive number' do
         result = described_class.new.parse("lane :test do
             minus(x: 44, y: 2)
         end").runner.execute(:test)
         expect(result).to eq(42)
     end
    
       it 'minus negative number' do
         result = described_class.new.parse("lane :test do
             minus(x: 40, y: -2)
         end").runner.execute(:test)
         expect(result).to eq(42)
     end
    
     it 'minus float number' do
         result = described_class.new.parse("lane :test do
             minus(x: 44.5, y: 2.5)
         end").runner.execute(:test)
         expect(result).to eq(42)
     end
    
  5. Add some tests for plus action:

     it 'plus positive number' do
         result = described_class.new.parse("lane :test do
             plus(x: 40, y: 2)
         end").runner.execute(:test)
         expect(result).to eq(42)
     end
    
     it 'plus negative number' do
         result = described_class.new.parse("lane :test do
             plus(x: 44, y: -2)
         end").runner.execute(:test)
         expect(result).to eq(42)
     end
    
     it 'plus float number' do
         result = described_class.new.parse("lane :test do
             plus(x: 40.5, y: 1.5)
         end").runner.execute(:test)
         expect(result).to eq(42)
     end
    
  6. Go to the root of your plugin:

     cd ~/fastlane-plugin-awesome_sauce
    
  7. Execute the tests (locally for now, but you can also run them on CI if you wish):

     rspec
    
    Preview

P.S.: in «‎real world» you’d probably like to run tests as part of the rake command with rubocop linter and such things, but this is «‎hello world», so it’s grand (:

Releasing the plugin

On the one hand we could all the time use master branch as a source of truth for the plugin, but from my point of view it’s better to have a way to use the different versions of the plugin, this is simply a good practice.

So for that, we just need to tag the commit with the version number. I’ll also attach a gem file with the release just in case. Let’s do it using fastlane:

  1. Open Fastfile:

    cd ~/fastlane-plugin-awesome_sauce/fastlane/Fastfile
    
  2. Create a new lane release (you need to have a Github API token for this step):

     lane :release do
     version_path = '../lib/fastlane/plugin/awesome_sauce/version.rb'
     release_version = File.read(version_path).scan(/\d+/).join('.')
     sh('rake build')
     set_github_release(
         repository_name: 'your_github_username/fastlane-plugin-awesome_sauce',
         api_token: ENV['GITHUB_TOKEN'],
         name: "Awesome Sauce v#{release_version}",
         tag_name: "v#{release_version}",
         description: "v#{release_version}",
         commitish: git_branch,
         upload_assets: ["pkg/fastlane-plugin-awesome_sauce-#{release_version}.gem"]
     )
     end
    
  3. Initiate the release:

     fastlane release
    

Implementing the plugin

  1. Open your main project:

     cd ~/my_very_important_project
    
  2. Create a Pluginfile:

     touch fastlane/Pluginfile
    
  3. Install the plugin:

     echo "gem 'fastlane-plugin-awesome_sauce', git: '[email protected]:my_github_username/fastlane-plugin-awesome_sauce.git', tag: 'v0.1.0'" > fastlane/Pluginfile
     fastlane install_plugins
    
  4. Use its actions to the fullest in your Fastfile:

     lane :awesome_lane do
         sum = plus(x: 1, y: 1) * minus(x: 4, y: 2)
         say(text: "The result is: #{sum}")
     end
    

Conclusion

Peep into a Sample Project

We’ve just crafted our very own fastlane plugin, even if it’s not so smart, more important is that now you know what secrets fastlane keeps. It’s time to find out how to make it work for you… Happy Mondays (:

Updated: