Self-Protecting Projects
I was once attenting a presentation on the topic “Front-End Development”. The talk was held by a senior developer who, at some point, started bragging about the cool conventions he and his team were using in their projects, particularly naming and structure of their CSS files. Then, he also mentioned something about their JavaScript conventions.
At the end of the talk, I asked the guy what their CI/CD pipeline was, how did the build command look like and whether they actually automated any of those rules. The whole room laughed, including him. Afterwards, he said something like: “we rely on our engineers and our ability to review our code”. I was taken by surprise – I was expecting a lame answer, but I did not understand why everyone laughed.
What’s really sad is that, to this day, I get similar reactions when I suggest automation of Quality Gates. In this post, let me ellaborate the idea, maybe it will be clearer afterwards.
Automating quality gates means having some sort of automated checks for the rules and conventions that your team is using in a project. When it comes to CI/CD pipelines, the sky is the limit, but I’ve learned that the most efficient way to achieve this automation is through your build tool.
Building a project usually means fetching dependencies, compiling, running the tests and packaging. Yet, we can add one more step right at the beginning: code analysis. In Java there are a few popular code analysers: Checkstyle, PMD or, if you really want to suffer, qulice. I use Checkstyle in all my pojects.
The key is to configure your code analyser to check all your conventions and even architectural rules. When a rule is broken, the build should fail, period. You won’t have a backlog of old tasks to fix “those red Jenkins jobs” – there will be no backlog simply because you will be forced to fix the errors before you even merge your changes into the master branch.
For instance, in my projects, I have rules ranging from cosmetic matters like naming or indentation to architectural rules such as “Classes are either abstract or final” or “All variables, of any kind, should be final”.
The most common complaint I hear about this scenario is frustration. Can it be frustrating? Of course it can, but only until you learn some discipline. Believe me when I say, you get used to it sooner than you think and you learn to appreciate it. At some point, it even becomes annoying to have to learn other conventions than what you got used to.
Remember, these checks must be blocking! You can also analize your code via an external tool such as SonarQube but such pipelines are usually not blocking so the team just has a backlog of tasks which are never really fixed. When is the last time you went and fixed some complaints in Sonar? My guess is: never.
Now, since we’re talking about self-protecting projects, here is another thing that I sometimes like to do: I let the project open its own bug reports. Usually, when you catch an exception, you just log it and hope someone in your company has a Log Analyzer which is smart enough to handle every logged error. Then, hope that someone actually bothers to verify the logs.
Why not open a ticket right away? As soon as you catch an exception, you can use the RESTful API of your Issue Tracker to open a ticket. Github, GitLab or Jira all offer such APIs. Of course, this is a matter of architecture, you can’t just make HTTP calls anywhere throughout your application. But if your is code object-oriented, you should be able to achieve this goal elegantly. It’s obvious that this approach can be pretty dangerous (for example, in the case of infinite loops), but it’s fun to play with the idea, at least when working on a pet project.
In my case, the project was a chatbot where the highest abstraction was the “Action”. Whatever the chatbot did, we called an Action. Now, Action is a Java interface with a main implementation and a decorator called VigilantAction. The “vigilant” action simply calls the original Action in a try/catch
block and opens a Github ticket with the caught exception. For interacting with Github, I used this library.
Writing about this now, I got an idea: we should have some sort of plugin for Log4J
or slf4J
: a plugin that would automatically open tickets on Github or other trackers, when the .error(...)
method is called. Or, even more elegantly, this kind of functionality could be implemented in our application servers or runtimes: if any exception breaks the application and reaches the server log, we should have an Issue opened automatically.
To conclude, I hope I made my point clear enough and I hope you won’t rely on conventions so much anymore. It’s better if we let the project protect itself. By the way, that’s not to say that Code Review is useless! Code Review is still very important, it just becomes easier.