So, you want to make a Danger Plugin? This is awesome. We all have common issues, and this is a great way to share code with the world. We’ve found once a single rule becomes longer than 10-15 lines of code, converting it into a plugin makes a lot of sense.
The concept of a Plugin in Danger is very simple. It’s a subclass of
If you don’t know about Ruby modules, then don’t worry, think of it as Ruby
namespacing. That’s the
Danger:: bit. You’ll have to create a class that is a
Plugin inside a
This subclass will be created automatically with a reference to the current
Danger::Dangerfile ruby object. It will be created before the
Dangerfile(s) are parsed by it.
There are no ways to automatically execute code with knowledge of the current
status. A plugin should get told to do some work from the user’s
Your plugin is added as an attribute to the user’s
Dangerfile(s), this is
based on your class name, but is editable.
def self.instance_name to_s.gsub("Danger", "").danger_underscore.split("/").last end # e.g. removes "Danger", converts camel case to snake case, and splits if there's any /s # DangerProse -> prose # DangerMyThing -> my_thing # MyPlugin -> my_plugin
One of the great things about a Danger Plugin is that the code is exactly the
same as it was in your
Dangerfile. A plugin has access to all of the same
methods and attributes as you had when it was being parsed inside a
Dangerfile. This is because anything your plugin doesn’t understand gets
passed to the current
Dangerfile for it to have a chance to act.
This is useful mainly in two things:
- Low barrier to entry.
- You have access to all of the other plugins.
#Creating the Plugin
Starting is pretty simple, we have a template. As well as a command
to get you started. Your first step is the name: the Rubygems rule
[core_app]-[gem]_[name]. So, the first space is always a
- then later
spaces would be
Now that you know the rules, in your development folder run
create [name]. This will create a README similar to the one for
$ danger plugins create guitar_lessons -> Creating `danger-guitar_lessons` plugin [!] using template 'https://github.com/danger/danger-plugin-template' -> Configuring template Configuring danger-guitar_lessons user name:Orta Therox user email:firstname.lastname@example.org year:2016
This sets you up with this folder structure:
danger-guitar_lessons ├── .travis.yml ├── Gemfile ├── Guardfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── danger-guitar_lessons.gemspec ├── lib │ ├── danger_guitar_lessons.rb │ ├── danger_plugin.rb │ └── guitar_lessons │ ├── gem_version.rb │ └── plugin.rb └─ spec ├── guitar_lessons_spec.rb └── spec_helper.rb
Which covers a lot of the basics for you.
The template isn’t empty, it comes as an existing simple plugin based on our work in danger-prose. This is to make it easier to show how all of the plugin comes together, I’d recommend reading through these files in this order:
These are main places where you would be doing work.
You’ll want to move your code into the file at
/lib/[NAME]/plugin.rb. Then you
can write some tests to ensure nothing will break in the future.
The template comes with some tests for the example plugin. It already comes with
infrastructure to have a
Danger::Dangerfile instantiate your plugin. You can
start off by modifying that to work with your plugin.
To run all of the tests, you can use the command
bundle exec rake spec. The
testing infrastructure is RSpec, the template also comes with a
Guardfile for use with guard with guard-rspec. This
means you can run
bundle exec guard and it will start a server which listens
for test changes and re-runs your tests as you work.
If you’re new to testing on ruby, here are some examples that you can use as a reference:
danger-proselint - danger_plugin_spec.rb
danger - request_source_spec.rb
danger - string_spec.rb
danger-rubocop - danger_plugin_spec.rb
This template comes with a
.travis.yml file that lints your documentation, and
offers advice on the syntax of your Ruby. If you want to quickly change the
bundle exec rubocop -a in the directory.
#Adding the Gem to your Project
To test your project back with the codebase you’ve extracted the code from,
you’ll need to use a
Gemfile. So many
You should add a
gem using the
:path attribute. e.g. add a new line with:
gem "danger-guitar_lessons", :path => "../danger-guitar_lessons"
Then when you run
bundle install your new gem is added to the project. You can
bundle exec danger local to test inside you project. You can make
changes to your plugin, then you only need to run
bundle exec danger local.
#Automate your README
Danger can generate your README based on the inline documentation in your
plugin. To do this, run
bundle exec danger plugins readme. The markdown will
be output into your terminal, then you can copy & paste it into
#Pushing to RubyGems
So you’re ready to ship now, you’ve got a few tests, and you’ve ran it inside
your project using a
You’re going to want to push it to RubyGems, here’s their guide on publishing a gem.
Once it’s on RubyGems, then you should change your application’s Gemfile to
:path and let it become the public gem. Awesome. That’s you ready
for using your plugin in production.
#Getting it on Danger.Systems
Having a plugin available on RubyGems means anyone can use it.
This is entirely optional, however having your gem on this site means that it will be more visible!
In order to go on Danger.Systems you need to ensure the running
danger plugins lint passes.
This means that the plugin is well documented so that the site can generate a page for it. The linter will guide you through the process, and show you examples of how to use the documentation syntax.
Once you are all green, and ideally warning free in the linter. You should send a merge request to danger.systems/plugins.json. Please don’t add it as the first item.
If you want to make sure that your plugin’s docs are always up to date, you can follow the instructions here to set up a webhook which triggers this static site to update and with latest release.
#Supporting multiple platforms: E.g. GitHub, GitLab, etc
You can determine if another plugin exists (all Platforms are plugins) but doing
Here is an example of GitLab and GitHub support in the same plugin: danger-mentions.