I’m leading a team of 6 developers who are working in different geographies across different working hours, and the best investment I’ve made on behalf of the company so far, is getting us on GitHub’s bronze plan. Just to give you some background information, BitcoinFundi is built on Ruby on Rails but it’s more than just a Rails & MySQL application. It has different components and custom daemons so to get all of this to work together, our only option was to build our own Ubuntu servers on AWS.
Our Server Environments
We have two servers: A development/testing server we call Dionysius and the production server we call Mercury internally. All of these are connected to one git repository on GitHub and we call this repository Origin. Origin contains our source code.
Dionysius is a near identical clone of Mercury and , besides them both running two different branches of Origin, one big difference between the two is that Dionysius has a PhantomJS installation that uses the Capybara gem to run automated tests on all the source code that is upload by developers before it’s tested by a human being prior to deployment on Mercury.
How we use branches on Servers & Dev Machines
We were able to achieve this by having two branches on Origin — Master & Production. The active branch on Dionysius Master branch because that’s the branch developers push their changes to.
Developers are free to create as many branches on their local computers — we’re very easy going about how developers do stuff locally. I, for instance, mostly just work on one branch called Tawanda and when I write code I want to test onDionysius, I commit my code, switch to Master, merge Master with Tawanda and then push Master to Origin. There’s another developer on our team who prefers to create a different branch for every different feature he’s working on. Developers can do what they want on their local machines — as long as they are pushing commits to Master, we don’t care.
How we automated deployments
When a push is made to the Master branch on Origin, it triggers a webhook that gets Dionysius to automatically pull the changes that were made to the source code and then reload the web server. After that, PhantomJS launches Capybara to test the code for bugs we can find programmatically before an actual human being steps in. If there are any errors, we get an email notification and attend to that before we push another commit. When we’re finished with our Slack integration, we’ll be able to get these notifications in Slack. That will be nice!
If the tests succeed, the developer logs into Dionysius to check that everything is indeed working the way it’s supposed to work on Mercury. At that point, the developer creates a pull request, gets someone else to review the changes and merge the pull request with Production branch to effect those changes on Mercury.
If you would like to implement this in your organisation too then Github has an excellent tutorial on how to deliver automated deployments to your server.
When a new developer joins our organisation
First they install Git on their local machine
Downloading & installing git is pretty strait-forward
Next they add ssh keys to GitHub
We have a private repository on Github so only developers that are granted access will be able to push and pull fromOrigin. But first, the developers will need to upload their public ssh keys on GitHub. GitHub has an easy-to-follow tutorial on how to add ssh keys to GitHub.
Then they set up defaults
Assuming the dev’s name is Alice and their email address is firstname.lastname@example.org, they run the following commands:
Then they clone the Git repository
- Clone origin and put the source code in a folder called bitcoinfundi
- Move to the bitcoinfundi folder
They run the following commands:
# git clone email@example.com:golixdotcom/BitcoinFundi.git bitcoinfundi # cd bitcoinfundi
Then they make sure Git knows who they are
It’s important for us to know who pushed what commits to Origin so we have everyone run the following commands to tell Git who they are:
# git config –global user.name “Alice” # git config –global user.email firstname.lastname@example.org
Then they default branch for pushing and pulling
I heard it said once that the Scotch spell whisky without the ‘e’ (whisky not whiskey) because they believe that adding the ‘e’ wastes drinking time. I also heard that if you see a bottle of whiskey written “Scotch Whisky” then it’s a fake and not really from Scotland because the Scots just call it “Scotch” because they believe that adding the word whisky wastes drinking time. I don’t know how far true this is but at Golix we have the same mentality. We hate to waste drinking time by specifying the branch we’re pushing or pulling to whenever we push or pull commits. So we want a situation where:
- If no branch is specified we want to push to the current branch we are on — in this case it is the Master branch
- If no branch is specified when we run git pull, pull new commits on the Master branch
To do this, we run the following commands:
# git config –global push.default matching # git branch –set-upstream-to=origin/master master
Our 3 rules for commits
We’ll obviously continue to add/remove/modify these rules and grow and learn more but right now we’re living by these rules:
- We use GitHub’s issues to keep track of what tasks the developers should be working on. Developers should only be working on one of the open issues.
- Developers should make as many commits as possible but should only push when they have something they want to test on Dionysius.
- The commit message should contain what they worked on and the issue number preceded by a hash. For example:
# git commit -m “configuring routes to fix issue #4”
# git commit -m “generation error controllers and views for issue #4”
We do this because when anyone opens the commit from Github they will see a clickable link to the associated issue. This makes it easier to track and close issues.
Our 4 rules for creating issues
- An issue should be created for anything the development team should be working on.
- On creation, an issue should have as much of the following information as is possible:
- A short descriptive name and a longer detailed description of what needs to be done.
- The issue should be assigned to somebody
- A label to show the type of issue it is. The most common types of issues will be
- New Feature
- Incomplete Feature awaiting Completion Issue type is an important determiner of urgency & importance so in most cases a Bug will be more urgent than a New Feature
- The milestone before which this new issue should be completed
BTW, we’re hiring so if you’re a Rails developer and working with Bitcoin and these technologies are something that excites you, then I’d encourage you to consider joining our team. We have both part-time and full-time positions so you don’t necessarily have to leave your job to start working with us.
I have been writing code for the last thirteen years and I still remember how hard it was to collaborate with other people on the same project before Git came along. Especially if you were all editing the same source files. Humanity has really come a long way and technologies like Git have made the world a better place.