Playbook

Development

Here you can find a basic set of rules and common practices used for Rails development in Prograils. If you’d like to add something, feel free to contribute (with pull request).

GIT

  1. Always use GIT. Always.
  2. Use Git flow. If by any means you refuse to use Git flow, use feature branches. Each feature branch should be created from develop branch. Features should be merged into develop, then into master.
  3. Use pull requests when possible. It’s always better to have your code checked and accepted by someone else. Also, by doing so you’re not the only one responsible for your feature :)
  4. Commit early, commit often.
  5. Never commit directly to the master branch. Never.
  6. Code in master branch should be always stable and ready for deployment.
  7. Avoid committing directly to the develop branch unless your change is a hotfix, in which case it’s by all means allowed.
  8. Merge using git merge --no-ff
  9. Know difference between git pull and git pull --rebase with awerness of the differences between them: link 1, link 2, link 3, link 4

Git Workflow

Information: All commands assume tracking remote branch is enabled for master, develop, production, and staging.

When you checkout a branch whose name exists in remote repo tracking automatically set:

$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  origin/newbranch
$ git checkout newbranch
Branch newbranch set up to track remote branch newbranch from origin.
Switched to a new branch 'newbranch'

When you created new branch you need to add -u parameter to git push:

$ git checkout -b newbranch2
Switched to a new branch 'newbranch2'
$ git push -u origin newbranch2
Total 0 (delta 0), reused 0 (delta 0)
To [path]
 * [new branch]      newbranch2 -> newbranch2
Branch newbranch2 set up to track remote branch newbranch2 from origin.

git help (git help pull, git help branch), and internet resources http://gitready.com, http://git-scm.com/book are your friends.

Workflow (Git Flow)

Requirements

You have cloned the repository with master, develop, production and staging branches

Create a feature

  1. pull the develop branch (git checkout develop, git pull)
  2. create a feature branch from develop branch (git checkout -b feature/A develop)
  3. do the coding, commit your changes
  4. (optional) It is a good time to squash your commits using git rebase - do this ONLY on commits that haven’t been pushed to remote repository
  5. (optional) You can place your commits on top of current develop branch using git rebase (git checkout develop, git pull, git checkout feature/A, git rebase develop) - do this ONLY when you didn’t push this branch to remote repository

After a feature is completed:

  1. You need to do one of two: a) If code review is needed push your feature branch to repository and create a pull request (into develop branch) b) Otherwise just merge the feature branch to develop and push develop to repository (git checkout develop, git merge --no-ff feature/A, git push)
  2. merge develop to staging and push the staging branch (git checkout staging, git pull, git merge develop, git push)
  3. deploy to staging environment (cap staging deploy or something)

When all features for upcoming release are accepted in the internal review system:

  1. create a release branch of the develop branch (git checkout -b release/v2012-04-14-10-12-ml develop, git push -u origin release/v2012-04-14-10-12-ml)
  2. perform any final work in the release branch (minor bug fixes and preparing meta-data for a release) - adding new features at this stage is strictly prohibited
  3. merge the release branch into the master branch and then merge the master branch into the production branch. Remove the release branch (git checkout master, git merge release/v2012-04014-10-12-ml, git push, git checkout production, git merge master, git push, git branch -d release/v2012-04-14-10-12-ml && git push origin :release/v2012-04-14-10-12-ml)
  4. deploy to the production environment (e.g. cap production deploy)

Bugfixes:

Bugfixes can be done by branching a bugfix branch off master, which is then merged back into master" and develop when done.

Code style:

Use Overcommit to help you follow code style guides. Example: config file. See also rubocop config file and haml lint config file

GIT commit messages:

  1. Separate subject from body with a blank line
  2. Limit the subject line to 50 characters
  3. Capitalize the subject line
  4. Do not end the subject line with a period
  5. Use the imperative mood in the subject line (e.g. add, create, modify, perform, fix)
  6. Wrap the body at 72 characters
  7. Use the body to explain what and why vs. how
  8. Read http://chris.beams.io/posts/git-commit/, https://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message

Ruby:

  1. We’re using latest Ruby 2.x release (2.5.0 at the moment of writing this text)
  2. On development machines rbenv is preffered
  3. On servers rbenv is used with newest 2.x release
  4. Apply coding style rules decreibed here
  5. Use Ruby >=1.9 hash syntaxt: { a: 1, b: 2 }, not {:a=>1, :b=>2}
  6. Use Safe Navigation Operator (&), avoid using try()

JS/CoffeeScript:

  1. Write new JS in CoffeeScript
  2. Use soft-tabs with a two space indent
  3. Always use camelCase, never underscores
  4. Don’t ever use $.get or $.post. Instead use $.ajax and provide both a success handler and an error handler
  5. Use $.fn.on instead of $.fn.bind, $.fn.delegate and $.fn.live
  6. Try to prefix all javascript-based selectors with js- or use data- attribute. More reading: here.

CSS:

  1. Use soft-tabs with a two space indent
  2. Put spaces after : in property declarations
  3. Put spaces before { in rule declarations
  4. Put spaces after , in attribute declarations
  5. Use hex colour codes #000 unless using rgba
  6. Use // for comment blocks (instead of /* */)
  7. Don’t nest selectors more than 3 levels deep
  8. Use a blank line between selectors
  9. Don’t use units in zero numeric values
  10. Never put multiple property declarations in one line
  11. Use hyphen-delimited syntax for IDs and classes http://csswizardry.com/2010/12/css-camel-case-seriously-sucks/
  12. IDs should never be used in CSS
  13. Don’t use !important to solve high specificity problems either
  14. Read https://github.com/styleguide/css

Rails:

  1. Always keep Rails version up to date. Update to minor ASAP, to major - when possible
  2. We use HAML as the templating language, along with SCSS for stylesheets and CoffeeScript for JS. ERB templates are allowed in plain text emails only
  3. Never assume, that localhost:3000 is default host:port for development. When possible, use *.dev mapping (use invoker). When you need to use host in app, try to use request.host_with_port
  4. Readmes shoud be updated, edited with markdown
  5. To bootstrap app use Prograils base app whenever it’s possible
  6. Basically, the Admin area is always required. If you can’t use ActiveAdmin, use Twitter bootstrap as a base layout for it
  7. Code and docs should be written in English

API building:

  1. Use proper HTTP status codes for responses. Never use 200 (OK) HTTP status for failed request. Use the 422 (Unprocessable identity) HTTP status code for validation errors
  2. Use JSON content type for both requests and responses
  3. When a request is failed return response with error and error_description keys (consistent with ouath2 error responses):
 {
      "error": "some_error_code",
      "error_description": "Some human readable message"
    }

Gems:

Recommended gems are

Development:

Test:

  • vcr Record test suite’s HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests
  • database_cleaner Cleaning databases for Rails < 5.1. Can be used to clean database in capybara tests. For other tests, Rails’ defeult transaction strategy is sufficient
  • factory_bot A library for setting up Ruby objects as test data. For integration with rails use factory_bot_rails
  • capybara with headless Chromedriver. Do not use capybara-webkit or poltergeist anymore, existing projects should switch to Chromedriver at earliest possibility
  • simplecov Code coverage analysis tool

Production:

  • puma HTTP server for Rack applications

Some of these gems are used in base app. Look there for examples of integration.

Screencasts:

Code Responsibility:

You’re responsible for every project you contributed to in last 12 months. This is important if in doubt who should install a critical update (Rails or from other lib). If you were participating and you’re still wondering who should do it, then just do it. Time is critical in such situations. Critical bugs should be fixed ASAP. Time of day does not matter in such cases. Critical bugs are those which affect basic business functionalities of application (e.g. impossibility to upload video in a video-sharing app).

Tests:

Developers are obliged to cover their code with automated tests before pushing any feature on a test server. Once a functionality is deployed, our testers are informed via a dedicated Slack channel (via @qa mention) to make the 2nd verification. The second verification is made by thorough manual tests. Our testers not only play the role of end users that comb through the app searching for bugs and unwanted behaviour (including validating feature(s) on all supported platforms and devices) but also validates delivered features with requirements. The 3rd and final approval is performed by the client. If there is still something that needs to be improved developers receive feedback: a list of issues in a corresponding Trello ticket which is moved back to a development stage and when ready, pushed through testing path once again.

Our inside ‘rules’ regarding tests are:

  1. Do test. A lot
  2. All new features need to have full test coverage
  3. Unit and integration tests are most important
  4. Use rspec when possible. Choosing different test framework will require acceptance of other team members
  5. Make use of rspec-rails
  6. Try to follow Better Specs suggestions
  7. All code pushed to master and other branches is checked in CI.
  8. Do not test functionalities provided by other gems (like email/password validation in Devise) - unless you have overwritten their code and behaviour
  9. Use factory_bot for fixtures