Workflow

We mostly build new long-term products. Such products have one shared attribute - changing requirements. In most cases, it’s not possible to fully design final product upfront because of various reasons. It could be because it’s not clear what users really want, or because business rules changed just after delivering the first version of the product. For this reason, we designed our workflow process to support fast changing requirements as the core element. Our entire workflow process is change driven.

We use SCRUM based project management methodology. We use Redmine with Redmine Backlogs plugin to support this methodology.

We have the following roles in our projects:

  • CTO (chief technology officer).
  • Developer.
  • Lead developer.
  • Product owner (usually a member of the client’s team).
  • Scrum master.
  • System engineer.
  • Tester.

Activities At Project Start

  • We design a basic diagram of the project describing most important entities and their associations.
  • We define and agree on the basic naming of the main entities.
  • We create stories in the issue tracker.

Redmine Backlogs

Stories

A user story is a feature described from the end-user perspective. For example, “As a user, I should be able to click on the product and see the product details.”. In other words, a story is used for high-level requirements and planning.

The product owner creates the majority of the user stories. Some of the stories, especially the technical ones, are created by developers.

Estimating stories

We use Planning poker for estimating the complexity of the story. Available estimates are:

  • 0 - duplicate stories or already implemented features.
  • 0.5 - basic change (e.g. add missing translations).
  • 1 - very small change (includes the test suite updates).
  • 2 - small change (e.g. a very small feature or a bug which needs further investigation).
  • 3 - medium change (a complex bugfix or a medium feature, for example, extend already existing functionality).
  • 5 - large change (e.g. when a story contains several requirements which require to add new or extend existing functionality).
  • 8 - extra large change (e.g. usually a big feature - create new app entry points (controllers/API), create new resources, etc.).
  • 13 - significant refactoring or a very complex change (e.g. something which requires making changes to the whole app).
  • 20 - we tend to avoid such large stories by splitting them into smaller ones.

As a convenience, we use the Scrum poker cards app for Android devices or Scrum time app for iOS devices during the estimation of the stories.

Stories are estimated every day after standup. Every team member of the project estimates the complexity of the story. The estimate of the story is calculated by taking the average number of all of the estimates, then rounded up to the nearest number in the available estimate list. If the dispersion of the estimates is high, then we discuss the reason behind that and agree on the most suitable estimate. The story estimate is then entered into the “Story points” field of the story in Redmine.

Sprints

A sprint is one-week length plan of stories. Every Thursday:

  • A new sprint is created.
  • Uncompleted stories (with any status except ‘Closed’) are moved to the new sprint.
  • The previous sprint is closed after the retrospective.
  • Unestimated stories are estimated.
  • If the sum of story estimates is less than that of the closed sprint, then more stories are added to the current sprint from the backlog to match the story estimate of the previous sprint.
  • The product owner sort the stories in the new sprint by priority (stories at the top has the highest priority).

If new stories are created during the sprint, then they are added to the Backlog. If the new story has high priority, then it can be added to the current sprint, but other stories (with lower priority) should be moved back to the backlog for the sprint to match the sum of the story estimates of the previous sprint.

Story workflow

The purpose of this chapter is to describe the story delivery process of the developer. This process consists of five main parts:

  • Preparation.
  • Implementation.
  • Testing.
  • Merging.
  • Deploying.

Preparation

Developers accept the first story with status ‘New’ from the top of the current sprint by changing the status of the story to ‘Accepted’ and assigned to self. After that, creates a new branch based on the develop branch. When starting to work on a large feature, suggest the possible application design and discuss it with the team.

The branch name begins with the story number following the name of the story and separated by dashes. For example, if the story number is “12345” and the story name is “Add favicon”, then the branch name is “feature/12345-add-favicon”.

git checkout develop
git pull
git double feature start 12345-add-favicon

Implementation

While working on a feature, developers:

  • Run the style checkers regularly and fix the violations.
  • Run the test suite and makes sure the tests pass.
  • Manually test the code locally.

Testing

After implementing the requirements of the story, developers:

  1. Update the feature branch by rebasing it against the develop branch

     git checkout develop
     git pull
     git checkout feature/12345-add-favicon
     git rebase develop
    
  2. Merge the feature branch to the testing branch and, if necessary, manually check the feature on staging (or the iOS/Android beta build).

     git checkout testing
     git pull
     git merge feature/12345-add-favicon
     git push
    
  3. Release the beta build (only for iOS and Android apps)

     fastlane beta
    
  4. Publish the feature branch to the remote repository for the feature to become publicly available

     git checkout feature/12345-add-favicon
     git double feature publish
    
  5. Create the merge request in Gitlab. Use branch feature/12345-add-favicon as the source and develop as the target.

  6. Run git double test to merge feature branch to testing branch.

  7. testing branch is automatically deployed to staging environment.

  8. Changes the status of the ticket to ‘Resolved’ and assigns to the tester. For iOS and Android builds, enter the build number of the beta build to the ticket’s field ‘Build Number’. When project has no dedicated tester, testing should be done by developerand product owner.

Tip: If the feature is in early development phase and it should not yet be checked by linters and peer programmers, prepend WIP to the merge request name.

If there are any issues found by the tester, the ticket is returned to the developer with status ‘Feedback’. After the feedback is fixed, developer changes the status of the story to ‘Resolved’ and sent back to tested.

Once the story is tested and returned from the tester with status ‘Resolved’, the developer can proceed to the merging part of the process.

Merging

To be able to merge the feature to the develop branch, the merge request has to be approved and the Jenkins CI build has to be successful.

There are two ways to get the merge request approved:

  • If the merge request was reviewed by the team during the merge request review and no feedback is received.

    or

  • If the lead developer and one other developer of the same project review the merge request and two likes are received.

In the case when feedback is received, developers fix the code and the merge request is reviewed once again.

After the merge request is approved and the build of the merge request is successful, the feature can be merged:

git checkout feature/12345-add-favicon
git double feature finish 12345-add-favicon

To associate this commit with the feature story, the commit message has to end with a hashtag and the story number - “Commit title. #12345”.

After this, developers can deploy and finish the feature.

Deploying

  • Merge the develop branch to master branch.

      git checkout master
      git pull
      git merge develop
    
  • Deploy the changes to production.

    • Rails projects:

      cap production deploy
      
    • iOS and Android projects:

      fastlane release
      
  • When the changes are deployed to production, send the story with status ‘Resolved’ to the product owner.

If the feature meets the requirements, the product owner will set the story status to ‘Closed’. This means that the story is completed. However, if there is any feedback from the product owner, then the story will be assigned back to the developer with status ‘Feedback’. In this case, the developer creates a new branch and the same process is repeated again.

Handling updates to requirements

When the client changes requirements for features that are being developed or are not started being developed, the client puts updates into corresponding ticket. If that story already has estimated story points, it is re-estimated again by the team, or updates are put into separate story depending on the situation.

In some cases, the client puts new feature requests or updates to current features into other communication channels (e.g. chat or email). In that case, responsible team members put those requests to corresponding tickets by themselves. The lead developer finds responsible team member if it is unclear who should respond to the requests.

Time tracking

We track all spent time on work-related activities to ongoing tickets in the issue tracker. This way the development process is more transparent to the clients. They know how much time was spent on which tickets, and they know how long it took for each feature to be implemented. Such time tracking also helps the team to track development velocity and identify which parts took longer than expected to be developed, and what unexpected problems occurred during development. This helps to estimate more accurately in the future.