By Sergey Prihodko, CTO at clevergig.
There are a huge number of books and a myriad of articles on how to properly run a software business. But why doesn’t anyone share their internal processes in the company? Maybe they do not want to reveal secrets, or they simply don’t like sharing.
Looking at all these advisors, we decided that it would be nice to share real insight and practical advice instead of a useless theory.
Over the past six months, after huge redesigns and code changes, we learned how to build a proper team and how to release a product as fast as possible.
But keep in mind that this process may not be suitable for your company. Your culture could be different, also every human is different and technical processes differ from company to company.
At clevergig, everything begins with vision and passion. But passion and vision without wisdom and experience will get you nowhere. Keep this in mind and you will avoid the biggest reason for product failure.
Usually, companies think they can learn what to build and how to build it from customers. But that’s not true. Customers don’t really know what’s possible in the case of technology. And the biggest reason — nobody knows what they want until they see it in action.
Fail fast, fail often is good approach instead of spending a lot of time to build something no one wants to use. But product teams are still often using the second approach, mostly because they can’t test ideas.
In our team, we understand that at least half of our ideas are never going to work. Ideas don’t work mostly because the customer doesn’t care. We must understand that if we do not kill at least half of our ideas, then after the launch, we will simply find out that they do not work. Our goal is to understand this at an early stage and leave only the good ones.
We are always looking for the fastest ways to validate an idea. Sketches on paper or accurate prototypes in prototyping software, or even simple code sketch to see the interactions between data structures. We always ask ourselves these questions: could customers use it? Will they use it? And if not, why?
An excellent product can only be created by an excellent team.
We see many product teams fail because they perceive the product as a project. In a good team, everyone is interested in the product as a whole. In product development, it isn’t good to have a manager who talks about what to do. This is not right. Products, designers and engineers should work side-by-side. We believe that if you use each member of the team only for their part of the work, then the productivity of the whole team cuts in half.
Product development is about culture, not about the process!
Clever agile rules
Of course, you won’t go so far just to a single vision. People need a set of values to help them make the right decisions. Thus, we have some ‘clever’ rules that were inspired by the Agile manifesto.
- Working face-to-face
- Say no to bureaucracy
- Daily and weekly goals for the whole team
- The result is more important than following the plan
- Small steps are better than big ones
We realised for ourselves that people work much faster when they communicate. They will find a solution much faster by discussing the problem in the kitchen while chatting. For this reason, our team sits together in one room. And most importantly — before you plunge into the problem and try to solve it alone, you need to ask your colleagues if they have ever faced it before.
The whiteboard is much more efficient and faster than using heaped tools. We are fighting with excessive tools usage. Thus, trying not to use the entire managerial list of tools about which they read in books.
We believe clevergig has incredible potential, but we are in a race against time. Every single day of work counts. Thus, we have weekly goals, broken down into personal daily goals. At the beginning of the day, everybody should set their daily goals, which relates to the team’s weekly goal.
Having a plan is important to success, but the plan is never fulfilled without any question. Great teams are always ready for change and are creative about them. And all because there is nothing more stable than changes.
We adhere to the principle of small steps. Thus, we always try to deliver small features quickly. Because only by cutting off all unnecessary things can we find out whether this functionality is really needed.
A sip of Project Management
Even in a case of using clever rules and having a vision we still depend on project management rules.
- Brief stories
- Tasks roadmap
We always plan the next 2–3 weeks with clear releases. The next 1–2 months are planned, with high-level briefs describing the problems and possible solutions. Beyond a few months, we only have high-level ideas which intersect with our vision and mission. All team ideas go onto a list, managed by the PM and PO and reviewed regularly. We collect ideas from the latest trends, market research, customers feedback and from sales and management teams.
Of course, our product team has a goal. This is a high-level goal, which requires at least 6 months to achieve. It consists of our vision of the future and our strategy.
The Product Owner handles maintaining detailed user stories. They should not contain all the small details but only illuminate the necessary functionality. Also, there should not be a solution in the stories, because it lies entirely on the team. The purpose of user stories is to understand what we are doing, for whom and why. Usually, user stories are highlighted in a Google Doc and later transferred to Jira, in order for the team to check and break them into tasks.
Since we are moving very fast and releasing the product several times a week, we try to break the user stories into small components — subtasks. The responsibility for this lies entirely on the members of the team. We use Jira to do this, which is managed by the Project Manager. Usually, the whole subtask belongs to one team member who handles it, but other members of the team can also take part in it. For example, attach links to design works or send test results.
All subtasks are tied to the release in Jira. Each release goes through several stages before it reaches a live server. At first, each task is individually tested, then all tasks are deployed on the test server, where it is checked for its compliance with the design and described requirements. Only after that is the rollout to the live server, where a small check is made once more. This is all done only to check and deliver a product of excellent quality, and not to blame someone for failure.
Every Friday at 2 pm our team gathers around our large screen in our meeting room, people grab a snack, and the engineers show what they have done this week. This strengthens our faith in the product. We are in a race against time and competitors. Thus, we must show each other how much we can do in a week.
Of course, this can’t be possible without strong engineering culture in our team. Our main artefacts of agile engineering are clean estimation process, robust code review and intelligent git and GitHub workflow.
Estimation is hard. For software developers, it’s among the most difficult (except variable naming) aspects of the job. And everybody tries to take it a bit too seriously — from owners and managers to developers. But that’s a mistake. Estimation is just that: an estimate. There’s no need to work weekends to compensate for under-estimating a piece of work. So let’s look at some ways we make estimates as accurate as possible.
Usually, the Product Owner collects requirements from the business, but they don’t yet understand the details of implementation. So, good estimation can give new information about each part of the work. Being clear about expectations and requirements at the beginning of the project can make a huge difference, so we also believe in the importance of creating software requirements specifications documents (SRS) as way of improving the overall process.
When the engineering part of the team begins its estimation process, questions usually revolve around requirements and user stories. Those questions help the entire team understand the work more fully. For the Product Owner specifically, breaking down work items into smaller pieces and estimates helps to prioritise all parts of work. Involving everyone on the team is key. Each team member brings a different perspective on the product and the work required to deliver a user story.
For example, if product management wants to do something that seems simple, like support a new web browser, development and QA can share their experience about what can be hiding beneath the surface. Likewise, design changes need not only the designer but development and QA as well. Leaving part of the product team out of the estimation process creates lower quality estimates and compromises the quality of the software. Traditional software teams give estimates in a time format: days, weeks, months. Our team has started with story points. Story points to rate the relative effort of work in a Fibonacci-like format: 0, 1, 2, 3, 5, 8, 13, 21, 100. That abstraction is helpful because it pushes the team to make tougher decisions around the difficulty of work. Here are a few reasons to use story points:
- Dates ignore non-project related work that always presents itself during our workdays: emails, meetings, activities, etc.
- Dates have an emotional attachment to them
We started our estimating process by using an exercise called planning poker. The team take an item from the backlog, discuss it, and each member will plan an estimate. Then everyone says the number that reflects their estimate. If everyone is in agreement, great! If not, take some time to discuss what is behind different estimates.
Lately, we moved to estimating in hours instead of points. We are trying to understand if our team could be predictable in a timely manner. Like everything else, estimation is a practice. So you’ll get better and better with time.
What exactly is a code review?
When an engineer has finished working on a task, another engineer looks over the code and asks questions like this:
- Are there any logic errors in the code?
- Are all requirements fully implemented?
- Does the new code match existing style guides?
But why should we spend time on such things? Should these questions only worry the developer working on the task?
Code review helps to learn the codebase, as well as spread the knowledge in the team. The main thing behind all of this is an ability to take a task from the backlog and begin execution by any team member.
Code reviews are also made for better estimates. Estimation is a team thing, and the team makes better estimates as knowledge spreads across. As new features are added to the existing code only the original engineer can provide good feedback and estimation. But with code review, any engineer is also exposed to the complexity and known issues of that area of the codebase. This practice creates many advantages and makes final estimates stronger and reliable.
Nobody wants to dive into a critical piece of code they didn’t write. But with code reviews, any team member can quickly understand what’s going on in that part of the application and start working on it.
Requiring code review before merging ensures that no bad code gets into our product. This means that strange architectural decisions are caught before they have a chance to make a regrettable impact on our customers.
Code review is all about sharing. It’s an effective way to show colleagues how you approach a problem. Initiating code review is a powerful start for dialogue.
So to summarise why we spend time on code review:
- It improves code quality
- It helps find ‘silly’ mistakes
- It assists in creating better estimations
- It provides a better understanding of all parts of the application
- It’s a great tool to spread knowledge
And we never forget that code review involves review, not inspection. So not all feedback needs to be critical. Everybody deserves an animated GIF or thumb up in their PR 🙂
And what about our GitHub Workflow? How does it look?
First and main rule: anything in the master branch is deployable.
We have a bunch of different features or bugs in progress at any given time — some of which are ready to be integrated, and others which are not. Branching exists to help us manage this workflow. When an engineer wants to start work on anything, he creates a named branch from the current dev branch. He is free to experiment and commit changes. This branch won’t be merged until it’s reviewed by someone of our team.
After the engineer adds, edits, changes or deletes a code, he is making a commit and adding them to branch. This process of adding commits keeps track of the progress of work on a new feature. Commits also create a history of work so others can follow up and understand what was done. Each commit has a commit message, which explains why a particular change was made. Furthermore, each commit is considered a separate unit of change. Never forget to push work to GitHub so it is always backed up in the case of hard drive failure.
GitHub has an amazing tool called Pull Request. It can be easily used as an internal code review system, which is what we do. Also, we use it for a feature conversation. We can send Pull Requests from one branch to another in a single project on GitHub. If an engineer is stuck in the progress or simply needs help or advice, or even if they have no code but want to share some ideas, they open a pull request. PRs are tightly integrated with the Git repository so anyone can see what changes would be merged if they accept the request.
Once a Pull Request has been opened, the person reviewing changes may have some questions. Perhaps the coding style doesn’t match our internal guidelines or bad algorithm used. Pull Requests are designed to encourage this type of conversation. Work can continue even in the process of discussion and feedback about code. So if someone comments that there is a bug in the code, an engineer working on it can fix it in and push the changes.
Once your pull request has been reviewed and the branch passes tests, any team member can merge changes to verify them and test on other machines. If this branch causes issues, we roll it back by restoring older commits.
Then it is moved to the staging branch and deployed to staging for testing. Once it is merged and pushed to master from staging, we deploy it immediately to production.
On Github projects, we use coloured labels about themes they are related to. Labels are consistent across repositories. This makes switching between project parts easy. Of course, there is a big list of such labels, but here are some examples:
- Architecture: PRs can cover many parts of the application and contain huge architectural changes. Needs closer attention of the team.
- Problems: Something that makes the product feel broken. High priority, especially if it is present in production.
- Minor: Files cleanup, reorganising folder structure, assets removing and other less impactful tasks.
- Refactoring: Refactoring of existing features and infrastructure. These update speed or improve code quality for better maintainability and readability.
- Feature: Brand new functionality. New pages, endpoints, etc.
And to summarise…
Of course, this process never ends. We study our mistakes on weekly retrospectives and try not to repeat them. Every week we learn something new and these impact the required adjustments to the process. This way is not easy. Building a fast-growing product in times of rapid change is very difficult. We hope our experiences will help you to revise your process and avoid our mistakes.