The current model of branches in SQ makes a distinction between 2 types: long and short-living branches. It gives users the information they need to understand the quality of code in a branch depending on its lifecycle:
- New code info but also overall info about issues and measures, historical data, with a configurable leak period for branches that live for a long period of time
- New code info only for temporary branches that are set to be merged and deleted.
But, as it is, the model has a main drawback: it's hard for users to understand how branches work in SQ since what is displayed in ALMs and what they see in SQ is different.
Short-lived and long-living branches are just branches. The concept will be simplified and these 2 types merged in a single concept of branch, with a same and flat representation for all branches.
Whatever the branch, we expect users to focus on the New Code Period. SQ should then give a clear priority to issues and code quality measures on New Code in the UI.
And whenever we consider branches or PRs, the New Code Period relates to a same concept: code that relates to a changeset. To define a New Code Period, a reference point is required.
In PRs, the changeset can be clearly identified with the parameters of the PRs themselves:. It's the nature of a PR to have a clear base and target. And, whether the CI triggers the analysis of the branch from where the PR is created or whether it analyzes the merge of the PR, the changeset has a similar meaning: the code that was changed with the PR compared to the branch that is taken as a reference.
For branches, it's less obvious to identify a changeset that will always be relevant to all users.
We could try to automatically apply a strategy for the configuration of the new code that adapts with the lifecycle of the branch. But this would bring complexity for users who expect to get a single and consistent representation for all branches. We want to keep it simple and apply a single default behavior for all branches. And we need to embrace the fact that, when users want to display info that relate to a specific changeset, it requires first that they define the reference.
By default, we could expect the new code of a new branch to correspond to the code that was added or updated since the branch was created. But, even if the mechanism that relies on the SCM and that we experimented with
MMF-1792 works well when the branch starts, we know that it suffers from important limitations:
- The creation commit of a branch in git is subject to changes: history of the branch can be rewritten (force push), and this is even something that we extensively use in our development workflow at SonarSource in order to remove temporary commit, rebase on master... The start of a branch can change at any point in time.
- It requires the CI to do a full clone of the repository to get the knowledge of the project entire git history.
Then, we can at least expect the New Code period to correspond, by default, to the changes from the time SonarQube knows the branch. The behavior that consists in starting the New Code period with the second analysis has for main benefit that the user always know what the leak refers to.
Of course, for the "main" branches which contain multiple versions (such as develop with GitFlow, or some maintenance branches), it would be confusing to consistently show old legacy code as part the new code period. We should display by default changes since the last version (what is applying so far to LLBs).
As a consequence, whatever the branch, the default new code period should be "Since previous version" and initially starts with the second analysis.
- We don't expect users to analyze all branches. With a development workflow that favours PRs (ex: GitFlow) analyzing the main branches such as master, develop, the maintenance branches can already bring a lot.
- Still, not every ALM offers Draft PRs, and it might be useful to analyze some branches that last for a couple of weeks or months (ex: features branches).
- Also, when PRs can't apply because an ALM is not used, analyzing selected features branches can be useful.
For cases 2. and 3., using the default value for the New Code (i.e. from the first analysis) may not be accurate enough. In the past, we had to put in place different strategies to not show in the branch, after a rebase, new code and issues that comes from the master.
We'll give the users the ability to define the New Code as a changeset compared to another branch. In other words, users should be able to choose a branch as a reference for the New Code.
It should thus be possible to set a reference to a branch already analyzed as the New Code period, in the UI and through WS.
As for any New Code period value, the change will be taken into account with the next analysis. From there, the New Code will then dynamically adjust to the state of the designated branch.
Of course, if the designed reference branch has no link with the branched analyzed, the default New Code period should still apply and a warning should be displayed in the UI.
All branches should now be displayed the same way across all SQ pages.
PRs will still be linked to the branch they target, without distinction from now on between short and long-lived branches.
With the merge of SLB and LLB, we want to give precedence to the New Code period over the overall information.
However, the overall info may be useful to follow what happens in the branch, to fix critical/blocker bugs or vulnerabilities in the existing code, to review some hotspots. Users should have the possibility, at any point in time, to see overall info for the branches they are interested in. Ideally, the info should always be available.
To benefit "at best" from the effort of review that was done on existing branches (FP, WP, comments, ...), new branches should reuse all info from the non-closed issues in the reference branch (by default the Main branch). But we don't expect status of issues to be the same over all branches.
At first, we expect the activity of branch to be empty: we don't want to inherit from events of the other branches.
The Quality Gate definition, with both conditions on New Code and conditions on overall code, will apply without distinction of the branch which is analyzed.
The need to specify a target should disappear. Analysis should become similar for any kind of branches.
The sonar.branch.target should then be deprecated and ignored, and analysis should raised a warning when this parameter is passed.
- SLBs will be migrated to regular branches
- Before a branch is re-analyzed, it will have values for the New Code period only, no values for the overall measures. This has to be taken into account in the Overview page, Measures and Code pages
- Once the branch is analyzed again, overall measures will become available.
- There should not be any impact on New Code values and thus, most of time, on the Quality Gate status.
However, in the case conditions on overall code are set in the Quality Gate definition, the Quality Gate status might change with a new analysis.
For the New Code period, we'll apply to all branches the "light issue tracking" we've experimented with
SONAR-11859: We'll report in the New Code period only the issues that have at least one location on the lines touched in the branch. As we only show here issues on changed lines in the branch, we don't expect to have many issues that already exist in other branches.
For PRs, the target branch is well known and SQ propagates the info of the new issues detected in the PRs to the target branch. Thus, with a workflow where PRs are always used to merge a branch to another, info of new issues are preserved across branches.
Ideally, when a branch is merged without a PR, as of today for ex SLB, SQ should keep the info on issues that were detected with this branch (WP/WF/confirmed status, comments...).
If a reference branch is specified, we can expect this branch, in most cases, to be target branch. Also, SQ should propagate the info of new issues detected in a branch to its target branch.
And to handle cases where the issue status changes several times in a branch or the same issue appears in several branch, issue tracking should keep the status of the most recently updated match.
All branches should keep inheriting from the settings and permissions of the project without having the ability to override them, except for the New Code period which should be configurable for every branch.
The configuration setting sonar.branch.longLivedBranches.regex to detect long vs short lived branches doesn't make sense any longer and will be dropped.
As explained previously, we don't expect users to analyze all branches.
Still, once the main branch of the project is configured to be analyzed in CI/CD, other branches created from the main branch are likely to be automatically analyzed. Indeed, after a YAML pipeline file is pushed on the main branch to activate its analysis, the YAML file will naturally spread in the new branches.
Analyzing all branches can have an important impact on the user experience: it generates noise for the user who is interested in analyzing a few branches, but also it can extend the time needed to get analysis results. SonarQube should thus provide a way to select the branches to be analyzed.
A new configuration will be introduced (both at global and project level) to choose the branches to be analyzed. It can correspond to a list of branch names, with simple regular expressions (in order to accept wildcard).
By default, "master", "trunk" and "develop" branches should be selected as well as all the long-lived branches already analyzed.
If a branch is not part of the ones that should be analyzed, scanner should skip the analysis with a clear warning message explaining that the analysis for this branch should be enabled in SonarQube.
Also, SonarQube should help the user understand (for example during the project creation) which branches are analyzed out of the box and how the analysis of the other branches can be activated.
With this MMF, as it is today, users will have add a condition in their pipeline script to avoid analyzing the branches they are not interested in. Documentation could help them with examples on the way to do it.
Ideally, old branches and PRs should disappear from SQ when they are merged / closed. This may be possible one day with a tighter integration with ALMs.
Currently, a purge mechanism is useful to remove from SQ all those branches and PRs that become useless once they are closed. Defining the purge policy requires to choose:
1/ what are the branches to be kept
- Project administrator should be able to select explicitly the branches to be retained.
- By default: "master", "develop" and "trunk" branches should be kept.
- For existing users, other analyzed long-lived branches should be also retained.
Solution: Introduce a new configuration, both at global and project level, to define the branches to be kept.
- At global level, a list of branch names should be configurable, with simple regular expressions (in order to accept wildcard).
By default: "master", "develop" and "trunk" branches should be kept as well as the branches previously considered to be long-living branches. The value previously set for sonar.branch.longLivedBranches.regex can be reused.
- On top of this, at project level, projects administrators should be able to add some branches to be retain, for ex from the list of branches.
2/ when inactive branches and PRs should be deleted from SonarQube
The parameter sonar.dbcleaner.daysBeforeDeletingInactiveShortLivingBranches will be turned into a parameter to delete inactive branches and PRs.
(nice to have) A few days (ex: 7) before the branch is deleted, a warning should inform the user of the removal and explain how to configure the branch for it to be retained.
Project Overview must highlight metrics on New Code
Since applications have the same overview as projects, the same design will also apply to applications.
- How might we avoid the purge of feature branches?
A new configuration is introduced at global level under Administration>Analysis and branches Cleanup (all settings related to purge and cleanup that are currently in Administration>General should be moved in this new tab). The new configuration gives the possibility to the instance administrators to add keywords (e.g feature..) that will results in the exclusion from the purge of the branches that contain one of the configured keyword. By default: "main", "master", "trunk" and "develop" branches are kept as well as the branches previously considered to be long-living branches (the sonar.branch.longLivedBranches.regex can be reused).