In the first post we talked about the tech lead responsibilities around people, and in the second one, we talked about the technology stack and about how code evolves and changes all the time. Now let’s dive into the systems and processes that glue all these things together allowing teams to achieve excellent results.
How long does it take a developer to do a change in the code and see it reflected inside of the product? How long does it take to build and deploy on a device a new version of your app? How long does it take to use a new version on a staging or live environment and until you see new data in your analytics dashboards?
Introduce continuous integration right from the start of the project. Simple code style issues or prevention of duplicated code can ensure consistency and readability across all project. New developers will be able to adjust faster to the team’s standards, and no effort will be spent during the review process on trivial formatting violations. In the begging start with one or two rules and as the team grows, add more to support the new conventions.
The code review process is another element that has to be integrated as early as possible and made a routine for all developers. This process is a great way to share knowledge among the team members and to prevent technical debt to increase. Coach your developers to be open to give and receive feedback and to have constructive discussions that ensure better implementations. Nowadays, branches can be merged only if one or more developers reviewed the code, so use this functionality to make all your changes examined by at least one other person. Here are some tools that I recommend and like: GitHub, Bitbucket or Gitlab.
Integrate as early as possible automatic tests that validate the functionality and integrity of the system. You can use unit tests, functional test, integration tests, or whatever testing methodology to ensures that the system behaves like you want it to behave. There is no need to start a holy war on unit tests vs integrations tests, or TDD vs BDD, since all of them have advantages and disadvantages and any of them is better than manual testing or no testing at all. My advice is to test all of them and see what gives the best result to your team and product. In time your product will grow and with so many new features will become impossible to expect that a human will capture defects or edge cases. Here are some tools that I had very positive experience with and I would recommend to others to try: Cucumber, FitNesse, Behave, Codeception, Mochajs, CasperJS.
Use continuous delivery to bring the features build by your team in the hand of live users at least once per day. This process will force a completely different mindset in the way you develop a new feature through the whole development team, not only programmers but also designers, artists, etc. Sometimes, it can be a little scary, knowing that a typo can affect thousands of live users on the next day, but the benefit of receiving fast feedback on your changes makes more than worth it. In addition, external components and infrastructure elements will give you also feedback, like a performance issue, that is not visible in a staging environment with three thousand users but became pretty clear on a three hundred thousand users market.
Does this mean that features are being developed on separate long-living branches and only when they are entirely done and tested merged to master? Definitely not, since long leaving branches had been proved over and over that they are quite an antipattern. To control the impact to the users, use feature flags or staged rollouts. You can have a “beta market” that can benefit earlier from the newest version, but make sure that this market is big enough to get qualitative feedback.
Feedback is not only an essential element when dealing with people, but it also plays a critical role in the process and on the product side. I think to build great products we need to iterate fast and often, so we bring value to our customers as early and as often as possible. That being said, a last element that has to be taken into consideration is:
All daily or weekly processes involving the team, have to be reviewed and refined by the people or systems that are using them. A rigid process will create friction in the team and it will lower the ownership level of the team members. Collect observations on the good things or on the ones that need to be improved after each loop and after a couple of iteration implement the feedback and have all processes grow organically from the needs of your team or end-users. I recommend including feedback loops whenever setting a new process and proactively ask people for their observations and advice how to make it better as time passes.
- keep your iteration time small to maximize your ability to adapt
- integrate and deliver changes fast and often to bring value continuously to your users
- include feedback loops across all processes to keep them up to date with the latest needs of your team
Over these three blog posts, we discussed the main areas of responsibilities for all tech leads. There is no right balance between them since all of them are important and will play a crucial role in the success of your team and product. Mastering all of them requires effort, and hard work, especially as our industry changes and new tools or process are being created all the time. However, it is our duty as tech leads to push forward and chose the ones that bring the best results to our team.
I hope these posts give you the right direction on our responsibilities. It is up to you to build your way to lead your team. You must empower, encourage and grow your team members so at the end your users benefit from the best version of your product that you can build.