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
minus
action:
-
Go to the actions folder:
cd fastlane-plugin-awesome_sauce/lib/fastlane/plugin/awesome_sauce/actions
- Rename
awesome_sauce_action.rb
tominus_action.rb
and open the file - Rename the class name
AwesomeSauceAction
toMinusAction
inminus_action.rb
file -
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.rb
file:def self.minus(x:, y:) x - y end
-
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:
- Copy
minus_action.rb
and rename the copy toplus_action.rb
- Rename the class name
MinusAction
toPlusAction
inplus_action.rb
file -
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.rb
file:def self.plus(x:, y:) x + y end
-
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.
-
Go to the specs folder:
cd spec/
- Open
awesome_sauce_action_spec.rb
and 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
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
-
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
-
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 (: