My First Open Source Contribution
I recently decided to contribute to Open Food Network (https://github.com/openfoodfoundation/openfoodnetwork, http://openfoodnetwork.org/), which connects suppliers, distributors and consumers to trade local produce.
The Rails project has good documentation and contributor guidelines, though not all in one single document with a linear workflow. The project uses Ruby version 2.1.5, which I did not yet have installed. Since I use Rbenv, this would have been a simple matter of running:
$ rbenv install 2.1.5And in the project folder:
$ rbenv local 2.1.5Unfortunately, I started following the directions. Had I completed them, I would have ended up making RVM my Ruby environment/version management system. When I realized the path I was on, I was able to back out and set up the version with rbenv.
Along with the environment set up, the directions also said to join the Slack channel and introduce myself, which I did. The response was quite quick and friendly. They offered assistance regarding environment set up issues.
Back on the tech setup front, I cloned down the repo and set my Ruby version. The project gitignored application.yml, and included an application.yml.example to copy and set up for the local environment, which I did. This included several fields for localization including timezone, currency and more. The defaults were set for Melbourne, Australia.
I tried to change the timezone from “MELBOURNE” to “DENVER”. When I tried to run rspec, I got this:
An error occurred while loading ./spec/features/admin/bulk_order_management_spec.rb.
Failure/Error: require_relative "../config/environment"
ArgumentError:
Invalid Timezone: DENVEROk, fine. I changed it back to Melbourne. The tests ran. 3000 tests and almost and hour later, I got:
4 deprecation warnings totalFinished in 53 minutes 50 seconds (files took 18.56 seconds to load)
3036 examples, 3 failures, 11 pending
After speaking with someone else setting up this codebase who also used the given timezone and got the same result, I asked about it in the Slack channel. The regular contributors were not aware of anything that would cause this, and asked for more detail. I also began probing more.
All of the failing tests were from one group of user stories, and within one context which had the following code:
let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.today - 7.days - 1.second) }
let!(:o2) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.today - 7.days) }
let!(:o3) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now.end_of_day) }
let!(:o4) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now.end_of_day + 1.second) }Hmm, Time.zone you say?… On a hunch, I changed my Mac OS system time zone to Melbourne, and — Success!
I posted my findings in the Slack channel. Understandably, people were uncomfortable with this only working in Melbourne.

So the app didn’t like my first attempt to name a timezone. I Googled timezone names, read a Wikipedia list of timezone names, looked through the codebase, searched for all occurrences of timezone, time zone, Time.zone, ran rake tasks related to time. None of it helped until I found the class ActiveSupport::TimeZone.
I read the docs for the class here: https://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html. The class contains a MAPPING hash constant, where each time zone on Earth is a key/value pair. One of the keys was “Melbourne”, but there was no global consistency to the naming. I found the name of my local time zone: “Mountain Time (US & Canada)”.
I changed the application.yml to include my local time, changed my system time zone back to automatic, and the tests passed. I posted my findings in Slack, and suggested adding a comment to the application.yml.example file. Someone liked my idea, and said I should do it, so I did:
# Time zone must match the operating system time zone in order to pass all tests. This is a string which is the key for the MAPPING hash constant in the ActiveSupport::TimeZone class. Documentation for this class including the entire hash can be found here: https://api.rubyonrails.org/classes/ActiveSupport/TimeZone.htmlI followed the directions for submitting a PR. I re-ran all the tests just to be safe. Did a git rebase. Committed with a good message, pushed my branch to my personal forked repo, then did a PR following the repo’s template where I explained all my decisions. This automatically ran two sets of checks. Since this was not initially an issue, a new issue was created and assigned to me.
Someone commented, rightly so, that this was too long to be on one line, and therefore hard to read, so I changed it per their request:
# Time zone must match the operating system time zone in order to pass all tests.
# This string is the key for the MAPPING hash constant in ActiveSupport::TimeZone.
# Documentation including the hash: https://api.rubyonrails.org/classes/ActiveSupport/TimeZone.htmlI pushed this up to my branch, which automatically added to to the PR, and the PR was approved. I learned some things about environment set up, communication, and workflow on a larger project. Perhaps my second contribution will actually involve writing code.