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
-
First of all let’s install fastlane if you have not done it yet:
brew install fastlane -
Cool, now we can create our plugin, let’s name it awesome_sauce:
fastlane new_plugin awesome_sauce - Enter a description and short summary of your choice
-
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
minusaction:
-
Go to the actions folder:
cd fastlane-plugin-awesome_sauce/lib/fastlane/plugin/awesome_sauce/actions - Rename
awesome_sauce_action.rbtominus_action.rband open the file - Rename the class name
AwesomeSauceActiontoMinusActioninminus_action.rbfile -
Fill the description:
def self.description "Subtracts one number from another" end -
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 -
Сreate a method for calculation in the
helper/awesome_sauce_helper.rbfile:def self.minus(x:, y:) x - y end -
Call this method in
minus_action.rbfile:def self.run(params) Helper::AwesomeSauceHelper.minus( x: params[:x], y: params[:y] ) end
- Let’s do the same for the
plusaction:
- Copy
minus_action.rband rename the copy toplus_action.rb - Rename the class name
MinusActiontoPlusActioninplus_action.rbfile -
Change the description:
def self.description "Adds one number to another" end -
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 -
Сreate a method for a new calculation in the
helper/awesome_sauce_helper.rbfile:def self.plus(x:, y:) x + y end -
Call this method in
plus_action.rbfile: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.
-
Go to the specs folder:
cd spec/ - Open
awesome_sauce_action_spec.rband clean it up -
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 -
Add some tests for
minusaction: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 -
Add some tests for
plusaction: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 -
Go to the root of your plugin:
cd ~/fastlane-plugin-awesome_sauce -
Execute the tests (locally for now, but you can also run them on CI if you wish):
rspec
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:
-
Open Fastfile:
cd ~/fastlane-plugin-awesome_sauce/fastlane/Fastfile -
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 -
Initiate the release:
fastlane release
Implementing the plugin
-
Open your main project:
cd ~/my_very_important_project -
Create a Pluginfile:
touch fastlane/Pluginfile -
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 -
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 (: