Sometimes there comes a point in the development of software products when you need to step back and fix the foundation that the entire system sits on. Code writing can get messy, and in many cases, so messy that moving forward becomes increasingly more difficult.
You can spend a lot of time wondering how you get into this kind of position where things are so messy that you can’t even make sense of it. My first inclination is to think that somehow we just doesn’t know what we’re doing. But that’s not true. In fact we got here because we do know what we’re doing. The root cause of this kind of condition in my opinion is “going fast before going smart”. I believe sometimes teams get into a mindset where developing fast is better than developing smart. It is really easy to say “we can organize this later” and ignore foundational practices to organizing your software projects.
But that mindset is wrong.
There are a few very foundational things you must organize and remain vigilant about in any software project. These things, when done smartly, provide intangible benefits for your software team (and inevitably the products you build).
No matter what you use whether it’s git, subversion, mercurial or Visual Source Safe be sure to organize it in a way that allows your project to grow and change quickly. A few things to decide on very early and be sure to enforce going forward:
- The location of the code that you work on and change everyday
- Be sure you have an easy to understand location in your source control where all team members know that the code is changing everyday. Call it “trunk” or “master” or whatever you want. Just be sure to have one. Knowing this can assure that everyone agrees to work there without obligation to protect the build.
- The location of the code that is being built for a release
- Most often this location is the same as the location that you work on everyday. Sometimes it can be a separate location. The biggest point is make sure it is completely understood by all. If your build location is confusing or moves all the time forget about making organized releases – you’ll never do it.
- The location of the code that is frozen for a release
- This location is most important for teams that release a lot and provides a sense of comfort for post-release issues. This is where the code never changes and is versioned according to some sensible release pattern. Having this location organized means you can release code anytime you want knowing that if it goes really bad you can always find the last release if you need to rollback.
There are only a few important things about the build system. But they are critical to the success of your software project.
- Your build system must be able to work with no manual intervention. Use whatever system you like just be sure that your team doesn’t have to start the build. If it’s manual you must rely on developers to run it and usually that is tedium they will avoid. And if it’s manual it ends up broken with the excuses like “works on my machine”.
- If you aren’t building every time you check in code you’re not helping yourself at all. This is why builds should be automated so that you can do them often. Automated builds that happen often will provide comfort to everyone that at any moment at least the project is deployable. And that’s a big thing – don’t underestimate that or confuse it with “working”. Deployment is on this list too.
- Emails should go out after every build. For good and bad. Everyone should know. It’s not spam.
Every language has some form of dependency management system or tool. Whichever you use be sure to use it in a way that is useful.
- Software developers should not “copy” dependencies into their local environment. Your project shouldn’t come with instructions on how to get and install them. The project should have a dependency management system that takes care of that for you with no manual intervention.
- Every software project has dependencies, so make sure that every time a developer opens the project they can get them each time in the proper way. If you get some dependencies but then have to manually get others or a few are missing you’ve failed. I would also add that if dependencies are downloaded from some central repo a public one is always best. If you have to login or VPN in, that creates a barrier and can stop work from happening.
With so many options for developers to use as their operating system and desktops, it is critical to assure that the software product runs the same way as it would on your production environment. But don’t sacrifice the developers choices of tools to write code.
- Leave code editors alone
- If your developers want to use Notepad++ let them. You want them using their favorite tool. This makes them happy and happy means faster. Seriously. Stay out of their hair with this.
- Servers are the same
- Provide a way for developers to install/run locally the exact same server on their machine that would run the software in production. It is critical that the developer sees the software run in the exact way it would in production (don’t confuse this with production data, that is different). This removes the “works on my machine” excuse.
- It is very important that the developers have a way to install/run locally the exact same servers in an automated way. If it’s a manual installation then you will lose time for setting up local machines and inevitably create situations where developers install it in funky ways and deviate from what’s in production.
This is so important that I could write a book on it. Luckily I don’t have to because there are hundreds already on this topic. However there are a few things that are critical.
- Deployments should be easy. The best way to make them easy is automation. You should be able to deploy at any time and on demand. Push button deployment is critical to improving the speed of product development. If you spend days on deployment you’ve lost multiples of days for development.
- Every deployment should happen identically. If there are conditionals or circumstances to your deployments those conditions will fail you in production. If software doesn’t land in production the exact same way every time, you instantly create an un-debuggable system. There is no way to trace issues.
Fix the foundation
If any of these things isn’t happening in your environment, fix it. Step back and make it happen. The rest of your code will be useless in many cases if you miss any of these foundational items.
It’s easy to see how some of these things can provide organization and benefit a software development team. I used the word automated a bunch and also the word reliable. It’s also easy now to understand that if you don’t organize these things very early and be vigilant about it how you could end up creating a software development environment where almost no progress occurs. And in many cases it’s a lot of work and often gets put off. That’s fine as long as you take a step back and make sure that these foundational things are organized and enforced. Sometimes you need to rebuild them as well. This is not a bad thing and you should do it. Getting the foundation right will always improve your product.