We use an agile workflow, based on Scrum. The workflow is tweaked to let us work effectively in a distributed team, even with the difficulty of working with clients in significantly different time zones.
We implement projects in small iterations («sprints»). By the end of each sprint we deploy a stable working project to the server.
Sprints are either one or two weeks long depending on the project specifics. Duration is fixed and we always deploy the same day*.
Workflow is optimized to ensure that:
We use Continuous Integration and follow the git-flow approach in order to manage our repositories.
By the end of each sprint we have a call and demo the project to the client. During the sprint we have short daily calls with a team.
Each project begins with a plan and the creation of a backlog which includes all features that are to be developed.
Each sprint goes through multiple phases:
During Preparation and Stabilization, the developers’ workload is not constant. Therefore our scheduled sprints overlap in such a way that by the end of one sprint’s development phase, we have already started the next sprint’s development.
During the preparation stage, the analyst:
At the beginning of the development phase, developers split their tasks into subtasks and prepare estimations of the number of hours required. Based on these estimations we can see if we are outside of the original predicted hourly ranges and make adjustments accordingly.
When we complete tasks, developers deploy new features to our development server. QA begins testing those features as they arrive.
During the development phase, developers are rarely blocked on any tasks and don’t require input from the client. On the rare occasion that input is required, we contact the client. Most clients are in a different time zone generating a short lag-time between asking the question and receiving an answer. This is one reason why we prepare multiple tasks for each developer to guarantee that they are kept busy while waiting.
By the end of the development phase developers create a release branch and deploy it to the staging server.
Our testing process consists of two parts:
When bugs are discovered, developers fix them in the release branch and then deploy updates to the staging server.
Sprints overlap in the stabilization phase. QAs do regression testing while developers start working on the next sprint. When bugs are found - developers fix them and switch back to the next sprint.
Deployment is not really a phase, it is more of a joyful event. It is worth mentioning because deployment is our ultimate goal.
It would be suspicious if we told you that everything always goes according to plan. Sometimes there are situations that require us to fix something in production immediately regardless of our sprint phase or even sleep phase.
When this happens, we create a small ad-hoc sprint that runs parallel to the current sprint.
Any new feature is implemented on top of the current production code (not the current development branch) and is pushed to the staging server for testing. When testing is completed - we deploy a hot fix to production and merge it to the development branch.
Hot fixes are usually small and don’t require any changes in the current sprint, but from time to time we may have to move low-priority tasks to the following sprint.
We often work with a client’s existing team, but we still prefer to follow our workflow.
This collaboration works best when we are given a separate section of the project which saves on coordination efforts. We prefer to avoid projects where our developers are directly managed by the client’s personnel.
We work with external providers for: designs, mobile applications, HTML/CSS coding and other services. Our workflow does not conflict with our partners’ processes in any way. We schedule our work in such a way that we always have externally-provided materials ready before sprint starts - this way we don’t have to coordinate and micro-manage our tasks during the week.
We have the following roles in our workflow: Analyst, Developer, QA. Some management work is required, especially when we have to coordinate with external teams. We don’t have a designated manager, instead an Analyst or a lead Developer takes care of the management tasks.
We built our own task management system and we use it on all of our projects. It allows us to schedule sprints, predict task durations, and track time. It also features a user friendly client UI that permits clients to monitor their project in real time.
Sometimes clients have to use Jira, Trello, Asana or another system for their projects. In these cases we use our system, but sync data with the client’s system.
We use git for all of our projects. Recently we’ve migrated to GitLab, but prior to that we were using Bitbucket. Git is a very flexible tool, but in order to use it efficiently with a team, it requires some conventions. We follow the famous git-flow approach, which matches our workflow perfectly.
We’ve used different combinations of Jenkins, TeamCity, Fabric and Ansible scripts. Today we use GitLab’s continuous integration system on all of our projects.
If for some reason we cannot use GitLab, our fallback is Jenkins.
Described workflow proves to be of great assistance in keeping projects on time for our clients. Contact us if you have any ideas on how to improve this workflow or if you have any other questions.
Django ORM is a very abstract and flexible API. But if you do not know exactly how it works, you will likely end up with slow and heavy views, if you have not already. So, this article provides practical solutions to N+1 and high loading time issues. For clarity, I will create a simple view that demonstrates common ORM query problems and shows frequently used practices.