A Fresh Cup is Mike Gunderloy's software development weblog, covering Ruby on Rails and whatever else I find interesting in the universe of software. I'm a full-time Rails developer and contributor, available for long- or short-term consulting, with solid experience in working as part of a distributed team. If you'd like to hire me, drop me a line. I'm also the author of Rails Rescue Handbook and Rails Freelancing Handbook.

Navigation
« Double Shot #321 | Main | Double Shot #320 »
Monday
Oct272008

Contributing to Rails: Step-by-Step

There are a few guides floating around about how to contribute your own code to Rails. But none of them (or at least none of the ones that I found) walk you through every step of the way. So, here's an attempt to fill that gap.

Step 0: Learn at least something about Ruby and Rails. If you don't understand the syntax of the language, common Ruby idioms, and the code that already exists in Rails, you're unlikely to be able to build a good patch (that is, one that will get accepted). You don't have to know every in-and-out of the language and the framework; some of the Rails code is fiendishly complex. But Rails is probably not appropriate as the first place that you ever write Ruby code. You should at least understand (though not necessarily memorize) The Rails Way
and The Ruby Programming Language.

Step 1: Install git. You won't be able to do anything without the Rails source code, and this is a prerequisite. The git homepage has installation instructions. If you're on OS X, use the Git for OS X installer. Everyday Git will teach you just enough about git to get by. The PeepCode screencast on git ($9) is easier to follow.

Step 2: Get the Rails source code. Don't fork the main Rails repository. Instead, you want to clone it to your own computer. Navigate to the folder where you want the source code (it will create its own /rails subdirectory) and run:

[sourcecode language='ruby']
git clone git://github.com/rails/rails.git
[/sourcecode]

Step 3: Set up and run the tests. All of the Rails tests must pass with any code you submit, otherwise you have no chance of getting code accepted. This means you need to be able to run the tests. For the tests that touch the database, this means creating the databases. With MySQL:

[sourcecode language='ruby']
mysql> create database activerecord_unittest;
mysql> create database activerecord_unittest2;
mysql> GRANT ALL PRIVILEGES ON activerecord_unittest.*
to 'rails'@'localhost';
mysql> GRANT ALL PRIVILEGES ON activerecord_unittest2.*
to 'rails'@'localhost';
[/sourcecode]

If you're using another database, check the files under activerecord/test/connections in the Rails source code for default connection information. You can edit these files if you must on your machine to provide different credentials, but obviously you should not push any changes back to Rails.

Now if you go back to the root of the Rails source on your machine and run rake with no parameters, you should see every test in all of the Rails components pass. After that, check out the file activerecord/RUNNING_UNIT_TESTS for information on running more targeted tests.

Step 4: Fork Rails. You're not going to put your patches right into the master branch, OK? Think of a name for your new branch and run

[sourcecode language='ruby']
git checkout -b my_new_branch
[/sourcecode]

It doesn't really matter what name you use, because this branch will only exist on your local computer.

Step 5: Write your code. You're on your branch now, so you can write whatever you want (you can check to make sure you're on the right branch with git branch -a). But if you're planning to submit your change back for inclusion in Rails, keep a few things in mind:
  • Get the code right

  • Include tests that fail without your code, and pass with it

  • Update the documentation

  • Step 6: Sanity check. You know at least one other Rails developer, right? Show them what you're doing and ask for feedback. Doing this in private before you push a patch out publicly is the "smoke test" for a patch: if you can't convince one other developer of the beauty of your code, you're unlikely to convince the core team either.

    Step 7: Update your copy of Rails. It's pretty likely that other changes to core Rails have happened while you were working. Go get them:

    [sourcecode language='ruby']
    git checkout master
    git pull
    [/sourcecode]

    Now reapply your patch on top of the latest changes:

    [sourcecode language='ruby']
    git checkout my_new_branch
    git rebase master
    [/sourcecode]

    No conflicts? Tests still pass? Change still seems reasonable to you? Then move on.

    Step 8: Create your patch. Still in your branch, run

    [sourcecode language='ruby']
    git commit -a
    git format-patch master --stdout > my_new_patch.diff
    [/sourcecode]

    Sanity check the results of this operation: open the diff file in your text editor of choice and make sure that no unintended changes crept in.

    Step 9: Create a Lighthouse account. You will need one to send in a ticket with your patch. You can do this at the free signup page.

    Step 10: Create a ticket with your patch. Go to the Rails Lighthouse page. Sign in if necessary. Click on "Add New Ticket." Fill in a reasonable title and description, remember to attach your patch file, and tag the ticket with the 'patch' tag and whatever other subject area tags make sense.

    Step 11: Get some feedback. The Contributing to Rails page suggests using the rubyonrails-core mailing list or the #rails-contrib channel on IRC freenode for this. You might also try just talking to Rails developers that you know.

    Step 12: Lather, rinse, release. It's entirely possible that the feedback you get will suggest changes. Don't get discouraged: the whole point of contributing to an active open source project is to tap into community knowledge. If people are encouraging you to tweak your code, then it's worth making the tweaks and resubmitting. If the feedback is that your code doesn't belong in the core, you might still think about releasing it as a plugin.

    And then...think about your next contribution!

    Reader Comments (11)

    Hi,

    Thanks for this very clear and easy howto.
    I have a problem though,
    I'm running the tests with rails' 2-1-stable branch.
    I get 2 failures on activerecord (running on mysql).
    Is this normal or to be expected?
    Are there tests that are known not to work in certain situations (ruby version, db related)?

    Thanks.
    Mathijs

    October 28, 2008 | Unregistered CommenterMathijs Kwik

    make sure mocha is installed or you will
    get a bunch of test failures:

    gem install mocha

    October 28, 2008 | Unregistered Commenterwarren vosper

    Thanks, great guide.

    October 28, 2008 | Unregistered CommenterNick

    if you can't tell, I'm on a fresh OS install
    here (Fedora 9 64bit). so here's some more
    stuff you need:

    yum install fcgi fcgi-devel
    gem install fcgi

    # you may need os packages for this one as well,
    # I already had then installed.

    gem install sqlite3-ruby

    # 64bit mysql was a pain. lots of info out there
    # on the tubes about it. this finally worked for me:

    gem install mysql -- –-with-mysql-config=/usr/bin/mysql --with-mysql-lib=/usr/lib64/mysql

    I'm still having problems with sqlite tests (transactions
    don't seem to be working).

    and gem_dependency_test is failing as well.
    Loaded suite test/gem_dependency_test
    Started
    .config.gem: Unpacked gem dummy-gem-d-1.0.0 in vendor/gems has no specification file. Run 'rake gems:refresh_specs' to fix this.
    config.gem: Unpacked gem dummy-gem-e-1.0.0 in vendor/gems has a mismatched specification file. Run 'rake gems:refresh_specs' to fix this.
    F........F..F..F
    Finished in 0.0466920000000001 seconds.

    1) Failure:
    test_gem_adds_load_paths(GemDependencyTest) [test/gem_dependency_test.rb:51]:
    not all expectations were satisfied
    unsatisfied expectations:
    - expected exactly once, not yet invoked: #.gem(#)

    October 28, 2008 | Unregistered Commenterwarren vosper

    Thanks for sharing!

    October 28, 2008 | Unregistered CommenterMark

    I don't get purpose of this post - in step #0 you suggest to learn something about Ruby first and in step #5 you points readers to "write your code".

    There should be more steps between 0 and 5, something like 200+ I guess

    October 29, 2008 | Unregistered CommenterJuzef

    @Juzef; Stop being square, please.

    October 31, 2008 | Unregistered CommenterAnonymous

    Hi,
    In step 8, we create a patch file.
    But I've not found how to apply that patch. Can anyone show me or point in the right direction on how to apply the patch file in git/github??

    November 10, 2008 | Unregistered CommenterMillisami

    Millisami -

    If you're working in a git repository, and you have a patch file for that repository, you just run

    git apply

    But...in the context of Rails: you don't apply the patch files, because you don't have commit privileges on the master repo. That's for the core team to do.

    November 10, 2008 | Unregistered CommenterMike Gunderloy

    Note to readers: be sure you've installed mocha (gem install mocha) as warren notes above, and be sure to update rubygems (gem update --system) to get the test suite to run completely.

    July 26, 2009 | Unregistered CommenterYong Bakos

    Really helpful, man. Thanks.

    February 4, 2010 | Unregistered CommenterLucas Efe

    PostPost a New Comment

    Enter your information below to add a new comment.
    Author Email (optional):
    Author URL (optional):
    Post:
     
    Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>