Our Development Process

Introduction for the new team members.

  1. We use a scrum based, bi-weekly, agile process.
  2. Every 2nd Wednesday we have a Sprint Kickoff meeting where we select tickets to work on in the next sprint. Tickets are chosen based on priorities, e.g. highest priority first and within a priority defects ahead of enhancements.
  3. Tickets are stored in Lighthouse.
  4. github is our source code repository.
  5. We use git flow branching model. Please read Why aren’t you using git-flow?.
  6. When starting work on a ticket, create a feature branch for it.
  7. We subscribe to the Test Driven Development philosophy. Code is considered complete when it has full test coverage and the tests are passing.
  8. Both unit and integration tests are implemented using rspec.
  9. Once all work on a ticket has been completed:
    – commit the changes to the feature branch using the following git commit message convention: “[#TICKET_NUMBER] Your message.” This allows us to cross-reference Lighthouse with github.
    – Then pull develop branch from github, rebase develop into feature branch and push feature branch to github. Rebase will keep commit history clean and linear.
    – Last but not least initiate a pull request on github. Please refer to Using Pull Requests.
  10. Next comes a code review. Developers with a thorough understanding of the code base can take on the reviewer role. When reviewing a pull request, discuss it with developer if necessary. When code is ready for merge:
    – Rebase develop to feature branch and push the feature branch to github.
    – Merge pull request and delete feature branch on github.
    – Last but not least change the ticket state in Lighthouse to resolved.
  11. We use tddium for Continuous Integration. Develop branch commits on github trigger execution of the entire application test suite. You will receive an email notification from tddium. Any failed tests need to be resolved as a priority ahead of working on the next ticket.
  12. QA Team does additional QA on top of test automation. Ticket state is changed to verified if it passes QA. It is changed to open if issues are discovered. Our goal is to have zero re-opened tickets.
  13. Every 2nd Tuesday we have a Sprint Wrap-up meeting where we go over completed and outstanding sprint tickets.
  14. After a Sprint Wrap-up meeting, a release branch is created. Release name is the same as the Lighthouse milestone number for the current sprint, e.g.
  15. After release branch is created we have a day for the final regression testing. Any issues found during regression testing have a priority and have to be fixed in the release branch.
  16. When a release is ready for production, i.e. all tickets are in verified state and there are no failing tests, the release branch is merged into develop and master. The master branch is deployed on production as described in this article: Deploying Ruby applications in the cloud.
  17. On rare occasions, a hot fix release is required in between regular releases. Hot fix naming convention adds a digit to the regular release name. For example if was the most recent release prior to a hot fix, the hot fix name would be
  18. Every business day we hold a brief team meeting – 10 minutes scrum at 10:10am.

The Art and Science of Product Prioritization

Prioritization is a challenge. A typical product wishlist far exceeds the product team capacity. Choosing wisely makes a big difference in product and ultimately business success.

Product wishlist items are collected using a variety of sources and techniques. They come from customers and internal stakeholders and are gathered using brainstorming sessions, interviews, online feedback capture, focus groups, analysis of sales win/loss reports and support cases, competitive analysis etc. Wishlist is constantly evolving with frequent additions of new items. Different stakeholders commonly have varying perspectives on the top priorities.

The process we have used to determine top priorities starts with scoring (the science part). All items are scored in two dimensions: business value and cost/complexity.

Items which are high value and low complexity (Quick Wins) are a no brainer and after a sanity check automatically become a priority. Items which are low value and high complexity make for an equally easy decision and are disqualified. Now comes the arts part. Items of high value and high complexity is where the key decisions have to be made. Scoring is a rather imprecise tool so simply using scores to drive decisions would not result in an optimal decision. Top items from the Strategic quadrant are instead selected in a working session involving key stakeholders where their respective merits are debated and ultimately voted on.

The process is outlined in more details below:

  1. Start with the business goals and key themes among customer requests. Translate these into product goals.
  2. Define scoring criteria. Value scores are based on alignment with the product goals. Cost/complexity scores are based on rough engineering estimates.
  3. Sanitize  wishlist.
  4. Brainstorm additional wishlist items.
  5. Score wishlist and place all items on the 2 x 2 board.
  6. Sanity check Quick Wins and Disqualified items.
  7. Debate and select top items from the Strategic quadrant.
  8. Selectively choose Discretionary items.

Steps 6 through 8 above are done is a working session with the key stakeholders. The entire process is repeated every 6-7 weeks, or at a minimum once a quarter.

Related posts:

Product Hierarchy of Needs: Winning, Keeping and Growing Business

Developing products at a high pace and low cost

Popular jQuery Mobile Tutorial upgraded to version 1.1.1

jQuery Mobile Tutorial has been upgraded to work with the latest stable release of jQuery Mobile – release 1.1.1.

If you are interested in learning jQuery Mobile, the tutorial will walk you through the process of building a simple but fully functional mobile application.

Part I of the tutorial covers framework basics – creation of static pages. Part II introduces dynamic pages and Part III adds data management features – ability to add, store and delete records.

Related posts:

HTML5 versus Native Apps: Which Platform To Choose For Your Next Mobile App

When not to use Rails db:migrate?

Rails db:migrate is used to manage database structural changes, .e.g. adding database columns, and database content changes, e.g. populating lookup tables. In general it works very well. There are however cases when alternative database migration approaches should be used. These include:

  • long lasting migrations
  • those which lock a table for too long
  • destructive structural changes

Locking table for too long

Locking table for too long will result in an application downtime as requests attempting to make changes to the table will time out. Structural changes to large tables fall into this category as executing ALTER TABLE will lock the table.

The way around the issue is to implement a multi-step process:

Before the release

  1. Create a new table with the new structure.
  2. Gradually copy data from the original table to the new table.

During the release (this can be executed as a transaction)

  1. Copy remaining data, i.e. original table data which are not in the new table yet.
  2. Rename the original table.
  3. Rename the new table to the original table name.

The process can be implemented as a set of rake tasks or database procedures.

Long lasting migrations

Long lasting migrations, even if they do not lock tables for a long time, can be problematic. They elongate the release process and typically you would want to complete a release process as quickly as possible to move to a stable infrastructure state. Data aggregation or data model de-normalization migrations fall into such category. For example you may decide to add a customer balance column to a customer table when calculating balance from transactions table is starting to take too long. This migration can be executed in three steps:

  1. In release A add a new aggregated column.
  2. Between release A and B run a rake task which populates the new column.
  3. In release B deploy code which uses the new column.

Destructive structural changes

Changes such as deleting columns can result in exceptions if a code using a column and the column itself are removed as part of a single release process. Between the time database migration is run and the time code on all servers is upgraded to the latest code base, the application may attempt to use a column which is no longer there.

A simple solution is to do structural deletions over two releases:

  1. In release A remove all code references to the database element (e.g. column) about to be removed.
  2. In release B implement database changes.

Work management

If migration involves multiple steps spanning two releases we simply create multiple, cross-referenced work tickets.

Rake tasks naming convention

One of the benefits of db:migrate is that it automates sequence of execution for various migrations. That benefit is lost when using rake to implement migration tasks. Implementing a naming convention for the rake tasks as outline below can help:

Tasks associated with a given release are grouped together using the release number as a namespace for the tasks. In general, releases rake file should be sparsely populated, i.e. only a small subset of releases should require migration rake tasks.


Rails db:migrate has many benefits and should be used whenever possible to implement database migration. There are a few use cases however where blindly using db:migrate would lead to issues. Simple processes utilizing rake tasks provide a viable alternative for these scenarios.

We have been selected by AlwaysOn as an AlwaysOn Global 250 Winner

Global 250 WinnerWe have been chosen by AlwaysOn as one of the AlwaysOn Global 250 winners. Inclusion in the AlwaysOn Global 250 signifies leadership amongst its peers and game-changing approaches and technologies that are likely to disrupt existing markets and entrenched players.

Here is the press release: 500friends Selected by AlwaysOn as an AlwaysOn Global 250 Winner.

A full list of all the AlwaysOn Global 250 winners can be found on the AlwaysOn website:
2012 AlwaysOn Global 250 Top Private Companies.

For more context on 500friends check Startup Spotlight: Q&A with 500friends.

git-flow with rebase

We are using git-flow for our source code branch management model. If you are not familiar with git-flow, Why aren’t you using git-flow? article provides a nice overview.

Many git users may be familiar with the git merge vs git rebase debate. In essence:

  1. Merge is simple to use and works great. It creates however lots of merge commits especially when working with a larger team.
  2. Rebase keeps commit history linear and clean. It is however harder to use and can be potentially destructive.

git merge vs git rebase: Avoiding Rebase Hell article provides a great comparison of both techniques.

The way to get the best of both worlds is to be explicit about when to use one versus the other. For us the simple rules to follow are:

  1. Rebase feature branches.
  2. Never rebase develop or master branch. (Always merge into develop and master.)
  3. Never rebase public branches.

To implement the rules we made a small change to the standard git-flow process:

When implementing enhancements or fixes always start by creating a feature branch:

git flow feature start foo

When done with work:

  1. pull develop branch from github
  2. rebase feature branch on top of develop

    git rebase develop feature/foo
  3. finish feature branch

    git flow feature finish foo
  4. push develop to github

To get more details on using rebase with feature branches please go to The magical (and not harmful) rebase article.

With this simple process change, git commit history is easier to follow while risks of making a mistake are kept at bay.

CTO Insights has global reach

Visitors come from all corners of the world. The top 5 countries are:

  1. USA – 32% of visitors
  2. India – 12%
  3. UK – 6%
  4. Germany – 4%
  5. Canada – 4%

%d bloggers like this: