In this blog, we'll focus on rules, Quality Profiles and Quality Gates. These elements are the building blocks of an effective Clean As You Code strategy. After reading this article, you’ll have a better understanding of what they are and how they’re used in the pursuit of clean, quality code for all!
The Forest for the Trees - aka the Big Picture
Before we jump into Quality Profiles and Quality Gates, it’s important to understand WHY we went through all the effort to create this building block functionality in the first place. The answer is simple: we need them so we can answer a super fundamental and super important question: YOU WROTE SOME NEW/CHANGED CODE - IS IT ACCEPTABLE?
And yes, we have a definitive way to determine that! Read on…!
The Trees for the Forest - Rules, Quality Profiles and Quality Gates
Rules are the most basic elements of a Quality Profile (QP). Each language requires a QP. For a given language, there are rules we may want to apply during an analysis and others we don’t. The QP is a rule container that determines which rules are active and applied during analysis and which are deactivated. The choice of which rules to apply is yours and your teammates'. Here you have two paths: 1) use the built-in, default QP called Sonar way or 2) customize a QP. While the built-in QP is great, sitting down with your team to discuss and reach a common consensus on what code quality and code security looks like, for your context, brings two BIG things:
- If you’ve never performed this exercise, it’s a great opportunity for an ad-hoc conversation to get everyone on the same page and gain clarity on clean, safe coding expectations.
- It forms the playbook for building a custom QP for each language that reflects your team’s ideal.
For example, if your team is less concerned with code smells, you can use the facets and filtering capabilities on the SonarQube/SonarCloud Rules Tab to narrow down or broaden the rules to activate in your Quality Profiles.
Here’s the built-in Sonar way Quality Profile for Java. You can see that it includes a subset of the overall Java rule count.
Now we have our container of rules, one for each language, called a Quality Profile. Each time an analysis is run against a particular language, all the active rules in that language’s Quality Profile are applied to the code being analyzed. Behind the scenes, auto-detection, via filename extension, is ensuring that the proper QP and language analyzer are invoked during the analysis.
Any rule violations are flagged in the analysis results as issues. Just flagging issues found in your code doesn’t do us much good though. At this point, we don’t know enough to answer the original question about whether we should merge your new/changed code or not.
We need a way to compare the analysis results against a set of acceptance criteria (aka conditions). This is where the Quality Gate (QG) comes into play. In SonarSource terms, the enforcement of these conditions is called a Quality Gate and it’s binary in nature - either pass or fail.
The Quality Gate
The Quality Gate lets you set your own code quality and security conditions by selecting a metric and then setting the pass/fail threshold. If any of the conditions in the QG fail, the overall QG fails and you know not to merge your code until you remedy the situation. The QG is dynamically updated so you’ll know immediately if a fix gives you the ‘GREEN’ light!
Just like with the QP, you can use the built-in Quality Gate called Sonar way or customize your own based on your team’s clean, secure coding definition that we talked about earlier. An example will demonstrate how it all comes together. The graphic below shows you how the Reliability (bugs) Rating metric is calculated.
Think of a QG as a report card with an overall pass or fail recommendation. The pass or fail nature is key because we want to make the Go/No-Go decision absolutely clear and not up for debate. The code is either passing from a code quality and code security perspective or it’s not. The notion that the code is ‘good enough’ or ‘I’ll fix that later’ doesn’t fly. The graphic below shows the QG applied to the New Code period on the SonarSource Java Code Analyzer (at SonarSource we dogfood our own products). 🙂
There you have it. Now you’re an expert on Quality Profiles and Quality Gates. Feels good doesn’t it 😎
What’s key here is the following: we’re going for a reliable, efficient, repeatable process that becomes ingrained in your team's workflow. Monitoring the QG on your new/changed code becomes second nature and you can’t imagine a time when it wasn’t part of your process.
Quality Gate Application
New Code Period
The Quality Gate is utilized in a few scenarios. One important scenario is the analysis of new code. SonarQube/SonarCloud utilize a concept called the New Code Period and by default, it’s set to ‘previous version’ for SonarQube. The New Code Period is intended to cover what you’re working on in the short term. Perhaps this is a current sprint or the next version of your app. While SQ/SC can analyze your entire codebase, that information, while interesting, isn't immediately useful because it’s not very actionable. You’re likely not going to stop what you’re doing and go refactor your codebase. In fact, after initially scanning all your projects, the 'report cards' returned might be quite depressing! However, this is OK - Rome wasn’t built in a day! Your team can’t fix past problems, that accumulated over weeks or even years, overnight.
However, the code associated with your current software version or current sprint is VERY actionable. And that’s where you should focus your code quality remediation efforts! There are a number of ways to define your New Code period such as comparing against a reference branch, a previous analysis or specifying a number of days (e.g., sprint length) to best fit how your team works.
This approach highlights the beauty of the Clean As You Code methodology - it says that by focusing on the New Code Period and only committing passing code, you'll eventually refactor and clean up all the parts of your codebase that matter.
Pull | Merge Requests
Another valuable use of the Quality Gate is against Pull / Merge Requests. We’ve established that only actionable metrics are relevant to code quality and a pull request is an ideal place to utilize a QG. Here’s what a Quality Gate integrated into your workflow looks like:
SonarQube/SonarCloud QG decoration is supported for GitHub, Bitbucket, Azure DevOps and GitLab. To see it in action for your DevOps Platform of choice, visit the SonarSource YouTube page where we have short demo videos for each platform. Below is a nicely green Quality Gate decoration on a GitHub Pull Request.
PRs are super actionable and represent the most immediate code you’re creating/changing so keeping that code clean and safe is the number one thing you can do to improve quality and security in your projects and apps.
Proper Quality Profile Maintenance
While a thorough discussion on QP care and feeding is beyond the scope of this article, it’s useful to review the basics. If you choose to stick with the built-in Sonar way quality profiles, then there’s nothing to maintain. Installing the latest version of SonarQube automatically updates all of the built-in language QPs*. For SonarCloud, the QPs are updated periodically by SonarSource.
*Any of your customized QPs, that retain inheritance, are also updated (covered in the ‘Quality Profile Extend’ section below)
On the other hand, if you and your team decide to customize some of all of your language QPs, then there are some important maintenance considerations to keep in mind. There are two ways to customize a Quality Profile: Copy or Extend.
Quality Profile Copy
To perform a copy, you just copy a built-in profile, give it a unique name and then make it your own. When you copy a QP, you are free to activate/deactivate rules contained in the original QP. When you copy a QP, you’re breaking inheritance with the built-in profile and any future changes to the parent QP will NOT be picked up by the copied QP. To remedy this, you’ll need to periodically perform a check against that language’s built-in QP to bring things up to date. A Compare functionality is included in SQ/SC to make this periodic sync more efficient.
Remember: If you go the copy route, you’re signing up for periodic QP care and feeding. i.e., if you don’t maintain your QPs you’ll get more and more out of date with every product release/update.
Quality Profile Extend
When you extend a QP, future changes to the parent QP ARE picked up by the child QP, however, you’re unable to deactivate rules. Extending a QP is useful when you want to extend from a baseline QP and inherit changes from it. i.e. you want an organizational QP but you want to inherit new rules added to Sonar way (the built-in QP) in the future, you’d extend instead of copy it. When you Extend a QP, you can activate rules that aren’t active in the profile(s) you inherited from. It’s a way to be more strict, not a way to relax the rules coming from the parent.
If you think deactivating some rules makes sense for your organization, one approach can be to create a top level profile as a copy of ‘Sonar way’. Copying allows you to deactivate what you feel doesn’t fit. From this Copy, you can then Extend to create specific department/team level profiles as needed. This ‘nested’ approach gives you the best of both worlds - the Copy QP allows you to enforce organizational-wide standards and the Extend QPs let you get more granular for teams. Because of the way inheritance is set up, you only have to periodically sync the parent Copy profile and the updates will cascade to the Extend QPs. The example below shows how you can nest Quality Profiles to fit your team's needs.
In either case, if you choose to customize a QP, it’s imperative to consider the impact changes will have on the development team and the noise generated. For example, turning on too many rules could result in developers ignoring issues and undermining the effectiveness of the tool. To learn more about Quality Gate functionality, visit the SonarQube Quality Profile documentation page.
Wrap-up
In wrapping up, I urge you to remember what I’ve emphasized all along - an effective code quality and security practice should become second nature and nicely integrated into your team’s workflow. It shouldn’t be disruptive or require the developers to become code quality and security experts. A Quality Gate brings this consistency along with a clear Go/No-Go signal into the workflow.
It’s important that you establish what code quality and security looks like for your team. What is your organization’s playbook? Sure, everyone can have an opinion on code quality, however, this isn’t ultimately useful as it’s not transparent and readily available to all team members. You can’t expect folks to adhere to an opaque or collective knowledge-based standard. Having this code quality ‘playbook’ is especially valuable to newly hired employees and novice developers as it’s a clear indicator of expectations.
The time for opinions is during the team discussion to establish the standard that forms your Quality Profiles and Quality Gate! Discuss it, agree on it and adopt it! Then you can rely on SonarSource and the Quality Gate to enforce it!