Creating Your First PR - An Intro To Git and the PR Process
Congratulations fellow traveler, so you’re interested in contributing to Metasploit eh? Well welcome aboard, its going to be a fun ride! You’ll learn lots along the way but here are some tips and tricks that should help you get started with making your first PR request whilst also avoiding some common pitfalls and learning how some of our systems work.
Initial Steps and Important Notes
The rest of this guide assumes you have already followed the steps at Setting Up A Developer Environment in order to get a fork of Metasploit set up and ready to run, and that you have added in your SSH keys (see Adding a New SSH Key To Your GitHub Account), set up Ruby and optionally the PostgreSQL database, and done any custom shortcuts you wish to configure.
Getting the Latest Version of Metasploit Framework
Before making any new contributions, you will want to sure you are running the latest version of Metasploit Framework. To do this run
git checkout master && git fetch upstream && git pull, where
upstream is the branch connected to the Rapid7 remote, aka Rapid7’s copy of the code. You can verify that
upstream is set correctly by running
git remote get-url upstream and verifying it is set to
Once you run this command, it will check out the
master branch, then fetch all the changes from
upstream (which should be configured to be Rapid7’s copy of Metasploit Framework on GitHub). Once it has cached these changes, the
git pull command will then pull these changes into the current branch, aka
Not pulling down changes before writing new code could lead to big issues down the line, particularly if someone has edited a file you intended to modify. In that case maintainers will then have to try find the right combination of changes to implement, which could lead to your PR being rejected if these changes are too complex.
Making Sure Your Gems Are Updated
The next step is to make sure you have the latest copy of the Gems that Metasploit Framework depends on. This can be done by running
bundle install from the same directory as where the
Gemfile.lock file is located, which will be in the same folder as wherever you cloned your fork to locally.
Doing this will allow you to make sure that you are running the latest libraries, which will ensure if you do encounter any bugs whilst developing code, those bugs are not related to out of date Gems being installed, and are therefore potentially legitimate bugs that need fixing.
Creating a New Branch for Your Code
Once all of this is done, you will want to create a new branch for your code, which can be done by running
git checkout -b <your branch name here>. This will snapshot the current branch that you are on, and use that to create a new branch with the name provided. Note that I did say snapshot. This is why it’s important to update the current branch’s code to the latest version of Metasploit Framework available prior to running this command, otherwise the new branch will contain outdated code.
Adding in Your Changes and Creating Meaningful Commit Messages
Once you have made your code changes, add them using
git add <path to file to add> <optional path to second file to add>. Note that you can specify multiple files to add using
git add at the same time.
To commit these changes locally, use
git commit -m "<commit message here>". Note that as a general rule of thumb, commit messages should aim to be 50 characters or less while telling readers what was changed in that commit. You generally don’t want to create commits that do multiple things at once, instead create a separate commit for each group of items that you are changing, and make sure that the commit message reflects what changed in a general sense.
Note also that maintainers may end up squashing your commits down so that your commit A, B, and C, now become commit D which contains all of the same changes as commit A, B, and C, but in one commit and with one associated commit message. This is often done when the code is ready to be landed into Metasploit Framework to help make the commit history easier for people to read.
Checking for Code Errors
Before code can be accepted into Metasploit Framework, it must also pass our RuboCop and MsfTidy rules. These help ensure that all contributors are committing code that follows a common set of standards. To check if your code meets our RuboCop standards, from the root of wherever you cloned your fork of Metasploit Framework to on disk, run
rubocop <path to your module from current directory>.
-a parameter will ask RuboCop to check your module and if possible fix any issues that RuboCop is able to fix. In this case the command would be
rubocop -a <path to your module from current directory>. It is encouraged to keep running this command and fixing any issues that come up until RuboCop no longer comes back with any errors to report. Once this is complete, run
git add <file> followed by
git commit -m "RuboCop Fixes". You can change the commit message if you want, but it should mention RuboCop as it helps maintainers know what the commit is related to.
As a good practice rule, you should always separate your commits that contain RuboCop changes from those that contain non-RuboCop related changes. This helps ensure that when it comes time to review your code, review can proceed a lot quicker and more efficiently.
Note that special cases exist if you are writing library code as our RuboCop rules are primarily designed to be run against modules. If at any point you are confused r.e this, please feel free to reach out and ask us for help on Slack at https://metasploit.com/slack.
Once this is done, the next tool to run is located in the root of the Metasploit local fork at
tools/dev/msftidy.rb. You will want to run this tool against your module code (if applicable), using
tools/dev/msftidy.rb <path to module>. This will give some output if there are any errors, or no output if your module passed the tests. Try and fix any errors mentioned here.
The next step to do, if you are writing a module, is to write the documentation for the module. You can find some information on how to write module documentation at Writing Module Documentation.
In general when writing documentation you will want to search for a similar documentation file under the
documentation folder located in the root of the Metasploit fork. You can then copy one of these files and use it as the basis for writing your new documentation for your module.
When writing the information for the documentation, be sure to make sure your installation steps are as clear as possible. Any confusion over how to set up the target to be exploited will likely result in delays. You will want to put as much detail here as possible.
Additionally any information about caveats, scenarios you have tested, custom options you added in, or quirks you noticed should also go into this file.
Checking Documentation Syntax
Once you have written the documentation, you then want to run
toos/dev/msftidy_docs.rb <path to documentation file>. This will report on any errors with your documentation file, which you will want to fix before submitting your PR. Notice however that if you get a warning about long lines, these may be okay to ignore depending on the context. A good example is if a line is long merely because of a URL. Such warnings can be safely ignored.
Submitting Your Changes and Opening a PR
Once you have gone through all of the steps above you should be ready to submit your PR. To submit your PR, first check which branch points to your copy of the code. If you have followed the setup guide, it should be
origin. You can double check this branch’s remote URL using
git remote get-url origin. It should look something like
gwillcox-r7 substituted for your username.
origin branch is in fact pointing to your copy of the code, run
git push origin local-branch:remote-branch and replace
local-branch with the branch locally where your code changes are located, and
remote-branch with what you want this branch to be called on the remote repository, aka
origin which will be your fork on GitHub.com. In most cases you will want these two names to be the same to avoid confusion, but its good to know this syntax should you start working with more complex situations. Note that if the branch pointing to your copy of the code is not named
origin, replace the word
origin in the command above with the name of the branch that does point to your copy of the code.
This should result in output similar to the following:
> git push origin update_mssql_lib_parameters:update_mssql_lib_parameters Enumerating objects: 15, done. Counting objects: 100% (15/15), done. Delta compression using up to 2 threads Compressing objects: 100% (8/8), done. Writing objects: 100% (8/8), 1.55 KiB | 1.55 MiB/s, done. Total 8 (delta 7), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (7/7), completed with 7 local objects. remote: remote: Create a pull request for 'update_mssql_lib_parameters' on GitHub by visiting: remote: https://github.com/gwillcox-r7/metasploit-framework/pull/new/update_mssql_lib_parameters remote: To github.com:gwillcox-r7/metasploit-framework * [new branch] update_mssql_lib_parameters -> update_mssql_lib_parameters
To create a new pull request (aka PR), browse to the URL mentioned in this output. In this case for the output above this would be
This will open a new template to create a PR request. Please follow all of the directions here and provide the requested details whilst also deleting the template text once you have provided the requested information. Note that PRs that do not provide anything but the template text for their description will be closed.
In your PR description you should take care to mention what it is that you are submitting, details on the type of vulnerability and CVE-ID, if applicable, how to test the submission, as well as any special concerns or items of note that occurred whilst conducting testing.
Once this is done a member of our team will review your PR within a few days and provide feedback on any changes that may still need to be made before the submission can be accepted.