How to achieve optimal workflow for software development as a team
Over time, our software development team has built up a workflow that has enabled us to achieve excellent results with less effort. The developers are more engaged and motivated, so they work better. This is how we achieved these results.
Also available in Italian.
This article is part of a series in which we have tried to describe the entire workflow of the development team:
- How to achieve optimal workflow for software development as a team: introduction to the workflow, principles and practices
- Becoming Agile: how to introduce the Scrum method into a team and implement the change within the company
- Web development in modules: detailed focus on the adoption of a system of software components for web development in an Agile team (Work in progress)
- Continuous Deployment and review apps in an agile team: how to make your team’s reviews more efficient by deploying dynamic test environments always up-to-date.
Introduction to the workflow
What is it possible to achieve with a tried and tested collaborative software develop workflow
I am a Software Engineer and I currently work at Chialab. There are some 10 developers in our team, working on a wide variety of projects, from web apps to CMSs and mobile apps. Developers often work simultaneously on a number of projects, changing context several times through the day.
The current software development workflow has enabled us to organize our projects to achieve:
- Better results
- A better understanding of the codebase and technologies
- Better rapport and understanding among team members
- Personal satisfaction, less frustration and a greater sense of belonging to projects.
We organize ourselves autonomously, working with the Agile Scrum method. Working in an Agile team offers great advantages, but you need to adhere to some principles and practices, some general to the Agile movement and others specific to your chosen Agile framework. For more information on how to introduce an Agile approach into your team, see the article Becoming Agile.
Incremental, iterative workflow
Building a well-oiled software development workflow is not something that happens in the space of a few weeks. It takes time, because it is a cyclical process. As Agile software development tells us, this process can be defined as both incremental and iterative.
By “incremental” we mean the progressive addition of features to the product in each sprint (in Agile, these are pre-defined periods of work). In this regard, we began to adopt a component-based software which, among the many known benefits, offers the advantage of applying this process to the software; it offers us a set of “bricks” (software components) that can be developed and reused independently from the development of the main software system.
The “iterative” nature of the workflow is intrinsic to the definition of the Agile sprints. At the end of each pre-defined work period, we receive feedback from clients and testers. This gives us a better sense of the priorities for the issues (which often change during the course of the project), so as to know which functions to develop first, and which to defer, or even eliminate because they are obsolete. Once again, the component-based development gives us finer granularity, enabling us to add/remove functions far more easily than we could with a monolithic development style.
Agile Retrospectives are particularly effective for improving workflow. These moments offer an efficient and constructive method for discussing various aspects; in this setting, we discuss any problems within the team, and carefully examine the workflow itself, with reference to our experience with the freshly-concluded sprint. Retroactive analysis is essential in order for the team to achieve iterative improvement, and for this reason it should be used even if you do not adhere to the Scrum method, periodically setting aside moments for critical discussion of your work over the last period.
There are some fundamental rules to be followed during these moments of discussion and analysis:
- Transparency during discussions
- Avoid discussing technical and technological aspects during retrospectives. As we will see below, Code Reviews are the moment set aside for these kinds of discussion
- Do not defer any discussions: problems that are not dealt with will arise again in the same way, or on a heightened scale, at the next Retrospective.
Let us now examine the various stages of the workflow, looking in detail at the tools of which we have had direct experience in our team.
The workflow in detail
Stage 1 — Drafting the issue, estimate and assignment to developer
The issue-writing stage (a unit of work assigned to a developer) can be performed by a product owner, by the Scrum master, or by a developer, it doesn’t matter; what does matter is that the description should be clear both to the developers and to less technical team members. The language used must always be understandable, containing a mix of technical and functional aspects.
An example of an issue might be: “create an entry window containing username and password fields, which in case of errors gives an “error” message. See attached images for graphic aspect”. We recommend adding as much information as possible, in the form of comments, pictures and documents that will be useful to the developer to produce an issue as faithful to the initial instructions as possible.
The issue should then be evaluated collectively by the team. This is a fundamental stage of the workflow; it is important for the entire team to take part in the evaluation. We have achieved good evaluation abilities, based on the following aspects:
- Intrinsic difficulty of the issue
- Lack of knowledge of the context or technology
- Likelihood that unforeseen problems will arise
- Time needed to carry out the necessary tests and to review the work.
In Agile there are several metrics used to evaluate issues. Nonetheless, as for many aspects of Agile, the real usefulness and efficacy of each practice needs to be assessed for the specific team, iterating in the various sprints and trying different metrics until you find the one that gives the team the most consistent results.
For estimates you can use Story Points (defined by the characteristics listed above) or hours of work; with the first option, values to be assigned might be Fibonacci numbers or clothing sizes (S, M, L, etc.). The important thing, over time, is to find what works best for the team.
How do you get good at estimating? Using feedback from previous sprints. Analysing the estimates from previous issues helps improve the teams abilities for subsequent estimations. It is essential to then adapt any estimates that were initially wrong, even during sprints, so as to ensure that retrospective analyses do not give misleading results.
As a team we saw considerable improvements in our issue estimates, which we adapted to each developer. Once the issue has been assigned, the individual developer analyses the initial estimate and proposes to keep it or alter it, based on his/her own knowledge relevant to the issue (the technology, knowledge of the project, etc.). Each developer has distinct characteristics, and greater knowledge of some projects than of others: over time, by adapting our estimates to individual developers, we were able to achieve an ideal team workload for each Sprint (velocity), which was consistently defined.
It is important to emphasise that if an issue is assigned to a developer, this absolutely does not mean that it will be completed exclusively by that individual; The assignment is simply an assumption of responsibility on the part of the developer to see a task through. He/she may be helped (as is often the case) by several developers, giving team members a greater engagement and sense of belonging with regards to the project (this principle, in addition to being a matter of common sense, is specified as one of the values of Agile Software Development).
Stage 2 — Software development
One fundamental tool in software development these days is the versioning system (for example, Git). Amongst other things, these enable us to maintain a separate workflow for the different issues we are working on, and to simultaneously have several remote versions of the codebase, or “branches”. These branches allow each developer to work first on a local copy of the software system, updated with the developments for his/her issue, before asking for his/her edit to be propagated to the main version of the branch (as a rule, this branch is known as the master).
In our team, in addition to a main branch, we introduced specific branches for each sprint. The sprint generally represents a period at the end of which the modifications visible to the client are “released”. It is important to run several parallel instances of the same software system. This will ensure backup and protection from any subsequently-rejected modifications and from any failures. The different instances should reflect the stages in the life cycle of the software (development, staging/testing and production).
The branch associated with the sprint is used as a main version during the intra-sprint development, and then the main copy (master) is aligned with it after the demo at the end of the sprint. The branch of a newly-concluded sprint is then deleted and a new branch is created ready for the next sprint.
Stage 3 — Validation
Once the issue has been completed, the developer requests for it to be propagated to the main branch, using a merge request. Merge requests are adopted by several systems, including Gitlab, which uses a workflow called “GitFlow”, and likewise by Github with the name Pull Request (the workflow is slightly different, see this link for more details).
We use Gitlab. Two tools on this platform help us in this situation:
- Gitlab’s Milestones can be used to “label” individual Merge requests, so that they are easily traceable. In this way it is possible, for example, to quickly view Merge requests opened at a given time, regarding all projects, or during the current sprint. The Milestones used are identified using the code of the current Sprint.
- The Gitlab labels help make information immediately visible regarding the status of a MR (Merge Request), without opening the details.
If the MR is approved, the modification is propagated to the main branch, ready for release.
But first each issue must pass two tests: a technical test known as a Code Review, and a functional acceptance, often performed by the person responsible for Quality Assurance on the project.
At this validation stage, we do not need to analyse the code, but the high-level behaviour of the application. We are only checking the functional requirements foreseen for the issue.
As a rule of thumb, this validation should be done first, because it is more likely that an error in the behaviour of the application, or a misunderstanding of the requirements, will lead to the need to significantly change the codebase with regards to one or more errors noted during the review stage (as we will see, this assumption is not a rule, and flexibility is important in the workflow).
This stage is the moment for technical discussions regarding modification introduced for the issue in question. Two people come into play here, the reviewee (who has completed the work and “opened” the Merge Request) and the reviewer (who analyses the code and modifications introduced, before “closing” the MR). The reviewer analyses the work from a technical point of view, starting discussions on specific parts of the code, thanks to the possibility to comment in-line in the tool provided by Gitlab. Only when the reviewer declares that all discussions have been “solved” is the MR considered to be approved.
Online it is possible to find numerous articles on “best practices” for code reviews (for example: https://medium.com/@palantir/code-review-best-practices-19e02780015f), from the points of view of both the reviewer and the reviewee. What we would like to offer you here, based on our own experience, are the tactics that contributed most positively to our workflow:
- Using a friendly, understanding tone: a reviewee is psychologically more inclined to discuss “his/her” code if the discussion is held on friendly terms, rather than feeling “attacked” with brusque and superficial criticisms
- Propose solutions rather than “pointing the finger” and simply announcing the existence of an error
- Open discussions even just to offer a different viewpoint or an alternative solution, or simply to ask for clarification: the code review is not just a moment of analysis, but above all a moment of growth for the team
- Draw in other team members for more opinions
- Do not be “afraid” to point out each problem: it is important to be very precise and accurate in communicating even the slightest typo. Errors that are found in code review but not communicated will be propagated into the main version of the software, creating frustration for the developers who subsequently work on the codebase
- Be flexible: it is important not to go over the top, pointing out identical and repeated errors. Often, certain identical errors are repeated in different parts of the code; in these cases it is helpful to flag up every occurrence of the error, but perhaps avoid repeating the initial explanation each time.
Submitting the code for code review ensures that the codebase is:
- The fruit of collective work
- As compliant as possible with intra-team standards, such as documentation, testing, and code formatting rules
- Equally familiar to the entire team, so that no single edit is ever propagated to the main version without at least two developers analysing it first.
The workflow is achieved with the contribution of every member of the team: for this reason, its efficacy depends on the experience built up by the same team. It is very important to use Retrospectives, Code Review and every type of intra-team meeting to analyse the workflow and to have a critical approach so as to be able to improve with every Sprint.
It is equally important to make use of the tools available, such as those mentioned above, many of which are freely available online, and never to stop researching and experimenting with new methods. Just as the technology market is changing, so must development methods keep up with new client demands and technological developments.
The fundamental point is to find a workflow that is shared and accepted by all team members, and not to be afraid to change any choices made as soon as you notice things are starting not to work out as you had hoped: in Agile, change is always advisable, as long as it is adopted gradually and iteratively.
Chialab is a design company. By developing strategy, design, software and content, we generate exciting relationships between brands and people. https://www.chialab.it.