Contributing to Open Source in 7 Steps

Making contributions to open source repositories is a great way to give back to the community. Open source software has a rich history and is a crucial component in many successful software applications. Most open source projects are maintained by either one or many developers for free. Since “free” is not usually the price of food and shelter, these maintainers are not available to work on their projects at all hours, most of them have day jobs so they can eat and buy clothing.

To help keep open source projects up to date and bug free, members of the community regularly contribute a portion of their own free time. Since the start of the Year of Commits project, I have made quite a few contributes to open source software and distilled the process down to these seven basic steps.

1. Find a repository that has some issues

A great way to get a foot in the door in an open source repository is by solving one of its open issues. A project is much more likely to accept code that addresses an open issue as opposed to code that is added “just because”. Open issues are either bugs or feature requests and are tracked on Github.

Some really great tools exist for exploring Github’s vast index of repositories for relevant projects. CodeTriage is one of these awesome tools. CodeTriage enables a user to narrow down Github’s list of repositories by programming language. CodeTriage has a very nice UI, ordering a very large amount of Github projects in descending count of open issues.

Alternatively, Github has their own tooling around discovering projects with their explore feature. Trending repositories from this week or this month are available on a per programming language basis. The explore feature is great for popular projects but exposes far fewer projects than CodeTriage.

To demonstrate a typical contribution’s life cycle, the fetching-gem project has been chosen.

The fetching-gem library is a convenience Ruby library for accessing elements of nested hashes and arrays with dot notation and noisy feedback.

Recently, the fetching-gem's issues page had a feature request: “Make the library compatible with the Enumerable#first(n) behaviour”:

Find Issue

2. Read the contributing guidelines

Before starting work on a project, make sure that the contribution guidelines of the project have been met. Some more popular repositories have very explicit rules about the number of commits per patch, the logical grouping of those commits, and even commit message style concerns.

The fetching-gem's contribution guidelines are very simple, it merely instructs that a fork should be made and then a pull request from the forked repository should be made.

3. Fork it

Obtaining a copy of a project’s code is crucial when trying to make a contribution. In Github, the act of forking a repository creates a copy of the repository. This copy may be altered until the feature is built or bug is fixed without disrupting the original project. The Fork button can be found at the top of a repository’s Github page.

After the Fork has been made, the next step is to clone the forked copy locally:

$ git clone git@github.com:<your_username>/fetching-gem.git

Cloning the repository locally will automatically add the origin git remote URL to the code directory. Additionally, adding the source remote URL right away is a great way to make sure that local code and the master remote code can easily stay in sync.

$ cd fetching-gem/
$ git remote add upstream git@github.com:covermymeds/fetching-gem.git
$ git remote -v

origin git@github.com:yez/fetching-gem.git (fetch)
origin  git@github.com:yez/fetching-gem.git (push)
upstream  git@github.com:covermymeds/fetching-gem.git (fetch)
upstream  git@github.com:covermymeds/fetching-gem.git (push)

The above command adds a new remote, upstream, to the directory. With this remote in place, a git fetch upstream command will grab the latest updates from the original repository.

Exploring unfamiliar code is not the most intuitive process, but thankfully a number of blog posts have been written about the topic.

4. Reproduce the issue

With the fork cloned locally and remote pointers all set up, it is time to reproduce and address the issue. Since this particular issue was a feature enhancement ask, “reproducing” the issue consisted of calling a method with the wrong arguments and expecting it to fail:

> require 'fetching-gem'
> fetching_array = Fetching([1, 2])
> fetching_array.first(2)
ArgumentError: wrong number of arguments (1 for 0)

Success! The code definitely does not support the Enumerable#first(n) behaviour, so there is indeed work to be done.

5. Fix the issue

Both when adding code and altering existing code, it is important to make sure it is tested. In most cases, the project under revision will have chosen a particular testing library and have some amount of tests. Adding the appropriate tests at the same time as the patched code will boost the library’s maintainer(s) confidence in the patch.

Adhering to the style of the code under manipulation is also important. From test example descriptions to variable declaration styling, consistency is a complexity reducing concept that is extremely valuable later on.

For brevity’s sake, the finer details surrounding my example fetching-gem patch can be found on Github.

6. Submit a PR

With the contribution guidelines adhered to, the code altered, and the issue taken care of, it is time to submit the long anticipated patch.

A well crafted pull request (PR) message consists of a few key elements:

  1. It is concise. Too much explination will be glossed over and ends up doing more harm than good.
  2. A special “Resolved #" text exists, allowing Github to automatically reference and resolve the issue upon a successul merge.
  3. If applicable, an example of the new behaviour is given.

The pull request that I recently added to fetching-gem looked like this:

Submit a PR

Another possible check when submitting a PR involves continuous integrations. If a project automatically builds its test suite with a service like Travis, Github will supply some checks at the bottom of the PR:

Check CI

If, for some reason, this status is not green and the tests did not pass, use the Details link to find out more information why.

7. Feel Awesome!

Pending continuous integration passing and the repository’s maintainer(s) signing off on the change, a patch will be accepted into the project. What a fantastic feeling that is! Awesome maintainers (like the fetching-gem maintainer mikegee) will show their appreciation directly on the PR, immortalizing your contribution for all days to come.

Feel Great

7b. Repeat 4 - 6

In the case that the submitted code is not exactly what the maintainer(s) is looking for, some additional work might be warranted. This back and forth could be thought of as frustrating, but it is also a great learning opportunity. When else is feedback so easily received about one’s code from people they would have probably never met otherwise?

Open source projects have tremendous value and a strong presence in the technology ecosystem. Contributing to these projects is an easy way to show appreciation and feel like a valued member of the open source community.