1. Use the same deployment mechanism for all environments
When you do something often, you get good at it. So deploy to all environments using the same mechanism. That way, when you deploy to production things less likely to go wrong.
2. If a requirement impacts on all user stories add it to the definition of done
The definition of done is a great place to catch global requirements. This is particularly true of quality related issues (like code coverage) and non-functional requirements like performance and response time.
If, however, you have a technical requirement that is specific to a story, make it part of the stories acceptance criteria.
3. Estimation is important, estimates less so
The process of estimation is great at beating out a better understanding of a story. To estimate something, you need to understand it and you need to collapse as many unknowns as possible.
But software development is inherently unpredictable so the value of estimates has to be taken in context. The smaller the estimate, the more likely it is to be right.
4. Improving your estimation process does not guarantee better estimates
To achieve highly accurate estimates you need to reduce the likelihood of change and eliminate uncertainty. This is difficult to do and it is often a counter-productive approach.
Typically there is inherent uncertainty in software development, which introduces a limit to how much accuracy can be achieved. As you near that limit, spending more time on estimating becomes pure waste.
5. Failed builds in continuous integration are the responsibility of the whole team
The value of continuous integration comes from the early detection of issues and consequently their early resolution. It has been show that fixing an issue gets increasingly more difficult the longer the time between when the code was written and when the issue was detected.
If the responsibility for failed builds is ambiguous then you run the risk of delays before the build gets fixed. The longer the delay, the less effective continuous integration is. The best approach is to spread the responsibility for broken builds across the whole team. This encourages early resolution of issues and maximises the value of continuous integration.
6. All code should have at least two sets of eyes on it before it reaches production
Nobody is perfect. Even the best developers make the occasional mistake. One way to reduce the impact of mistakes is to catch them either during code reviews or as a result of using pair programming techniques.
Also, if a production bug occurs it is usually fixed more quickly by developers who are familiar with the offending code. If you have at least two developers familiar with every bit of code then you often reduce the impact of holidays and sickness on the response time to production bugs.
7. Adding people to a late software project makes it later (Brooks's Law)
Adding new members to a development team has many side effects. Firstly, it is necessary to train the new team members so that they can be productive. Typically this will place an additional burdon on the original team members. Secondly, the more people there are in a team the more lines of communication are open (the so called n+1 problem). And finally, new people change the dynamics of a team. This can be a good thing, but rarely is the benefit immediate. Typically the team has to re-learn how to work together.
8. Write a regression test for every bug you find
It is very common for a bug to resurface two or more times during the life of a product. The reasons for this include code merges and different developers repeating the same mistakes.
A great way to avoid this happening is to ensure that every bug found is covered by a corresponding automated regression test. Best of all, write the test prior to fixing the bug. This ensures that the bug is fixed and that the test is valid.
Check out the roadmap for test automation
The Mythical Man Month - Fred Brooks
Continuous Delivery - Jez Humble, David Farley
No Silver Bullet - Fred Brooks