ConflictsBot: A Plastic SCM DevOps mergebot that detects and reports merge conflicts of task branches with trunk branch at an early stage.
It runs dry-merge operations to detect conflicts on every 'resolved' task branch with the trunk branch every time a new changeset is created in the trunk branch.
It's a perfect partner for Plastic SCM's built-in TrunkBot
Find out more info about ConflictsBot here
ConflictsBot it's a dotnet core console app. So you will need dotnet installed in your computer to compile the sources. Get it at the following link
Once it's installed, download this project onto your computer and use the dotnet
tool to compile, targeting your desired platform (windows-x64 in the example below):
$>git clone https://github.com/JesusMG/conflictsdetector-mergebot .
$>cd ConflictsBot
$>dotnet publish -c Release -o bin\windows -r win-x64
This section breaks down the configuration of the Plastic SCM DevOps feature for a repo with a Trunk Builder mergebot (TrunkBot) and a ConflitsDetector mergebot (ConflictsBot) working together. The initial step is to have a Plastic repo filled with the project code I want to track. In this example, my repo name is pnunit, and my Plastic server is configured with User/Password authentication mode. A special “bot” user was created for the mergebots described above.
Plugs are mergebot connectors to actual external systems supporting the build & merge process. In this example, I used:
- Jira as the issue tracker (optional)
- Jenkins to build & test the project code (mandatory)
- An email notifier based on Gmail (optional)
The configuration of these plugs is pretty easy: they just require URL’s to actual services, and credentials to access them.
TrunkBot is the Plastic SCM's DevOps built-in mergebot that drives the build & merge process for the tracked branches of selected repo. I created mine with the following configuration by clicking the Add a new mergebot button:
No surprises here. I typed the repo name to track, I selected which branch will have the role of trunk branch (/main), the task branches prefix to track & merge to trunk branch, and the Plastic user for the TrunkBot in order to query and execute operations on the tracked repo. Next, I defined which is the attribute name to identify the “status” of a branch, and its possible values:
As you can see in the screenshot above, I also configured the automatic labeling feature to create a new auto-increment label on every new changeset in the trunk branch.
And finally, the configuration of the TrunkBot’s supporting plugs. Jira Issue tracker: I typed the project key (the same as the branch prefix but without the "-" character, so the branch names match with Jira Issues) and the possible status values:
Remember, a task branch won’t be processed by TrunkBot until the branch status attribute is set to resolved, and the related Jira issue status is set to Reviewed.
Jenkins: I just typed the job names to be run by TrunkBot to build & test the merged code of the task branch with trunk branch before checking-in. If this job is executed successfully, the merged code is checked-in and an extra job can be optionally triggered before processing the next task branch (useful to deploy the recently checked-in task branch):
And, the Email notification plug is very simple: I just typed the Plastic profile field to get the email of the task branch owner to perform notifications, plus a fixed list of recipients (Plastic user names or actual email addresses can be entered this way).
The machine hosting the Jenkins server/agents needs a valid Plastic SCM command line client installation, plus the mergebot plugin component. This way, Jenkins is able to download the merged code the TrunkBot takes from Plastic server to the Jenkins job’s workspace prior to running the job steps.
In case of Jenkins, just search & install the mergebot component.
Then, the Source Code management option must be set to Mergebot Plastic SCM in the Jenkins jobs triggered by TrunkBot.
At this stage, TrunkBot is fully functional and ready to process task branches. The screenshot below shows the resultant Branch Explorer after TrunkBot processed the first task branch and the merged code was successfully built in Jenkins:
Since the build was successful, TrunkBot checked-in the merged code in /main branch, it turned the branch status attribute to merged value, as well as the related Jira issue status. Then, it labeled the resultant changeset with an automatic label name: REL_1.0. Finally, TrunkBot triggered the configured post-check-in job in Jenkins.
Now, let’s suppose the project evolves into a more complex scenario, where several users work concurrently on different task branches:
As you can see, a new branch (/main/PNU-3) was processed by TrunkBot and successfully merged in /main branch. Let’s suppose this branch carries several remarkable changes in the project to implement a feature. And therefore, its integration possibly causes other “resolved” queued branches (colored in blue in the screenshot above) to require manual user intervention during their merge.
One of these affected branches is /main/PNU-5. And let’s also suppose TrunkBot will process /main/PNU-2 and /main/PNU-4 before, which don’t have any manual conflicts with /main branch so far. With the current setup (no ConflictsBot yet), we will have to wait until /main/PNU-2 and /main/PNU-4 are processed by TrunkBot to notice the branch /main/PNU-5 requires resolving manual conflicts with /main branch.
But, since /main/PNU-5 is already tagged with the resolved status attribute, we could anticipate the fact the branch requires manual conflict resolution on its merge to /main branch. Here’s where ConflictsBot comes into play.
Download and compile ConflictsBot following the instructions above. Once the bin files are ready, let’s use it in our Plastic server as a custom mergebot.
Go to the DevOps section in Plastic Server WebAdmin > Mergebot Types > Add custom mergebot type now:
And then, complete the form with the proper paths depending on the location of your downloaded ConflictsBot project. No extra parameters are required in the command line to start
. See the example below:
Now, we’re ready to configure an actual instance of ConflictsBot. Go to the DevOps section in Plastic Server WebAdmin > Dashboard > Add a new MergeBot. The configuration values regarding the repo to track, trunk branch and task branches prefix are the same as TrunkBot:
Next, regarding the status attribute of task branches, the recommended configuration is to set the same values as TrunkBot for at least for the following entries:
- The name of the status attribute.
- The Resolved value for the status attribute.
- The Merged value for the status attribute.
Regarding the Issue Tracker configuration, the recommendation here is to use the same configuration as TrunkBot. We can reuse the same Issue Tracker plug, and the same status value except for the Resolved value: Instead of having to wait for the Reviewed status for a task like we do in TrunkBot, we set an early status value in the workflow to trigger the ConflictsBot merge check. In this example, the value is Implemented:
In summary: with this configuration, ConflictsBot will trigger the first conflicts-check for each task branch when the branch status attribute is set to resolved, and the related Jira status is set to Implemented. Finally, with regards to ConflictsBot notifications, we can configure the fixed list of recipients and whether sending a message just when conflicts are detected, or in any conflicts-check performed, even on successful ones. In the example below I used email notifications with the following configuration:
And that’s it! ConflictsBot is ready to work and detect manual conflicts at earlier stages in the workflow!
Let’s see what happened since we started our new ConflictsBot in the pnunit repo: If we open the report of processed branches of ConflictsBot (named uyox in the screenshot above), we can see it already checked the resolved branches (PNU-2, PNU-4 and PNU-5):
Because it detected that /main/PNU-5 has conflicts that require user-intervention, ConflictsBot set the branch attribute to failed, and the Jira status to Open. Also, an email notification is sent to the branch owner’s email and configured fixed recipients:
But as described earlier, the benefits of ConflictsBot don’t finish here. Let’s continue with the example. Since there are conflicts that require user intervention, I switch to branch /main/PNU-5 in my Plastic workspace and I run a merge (rebase) from /main:
Note how the merge operation shows the conflict that require manual user intervention:
- PNUnitTestRunner.cs file modified a method in branch /main/PNU-3 and then, the branch was merged to /main.
- But, /main/PNU-5 deleted the entire file. I resolve the conflict by keeping the file deletion. Once I verify the resultant merged code compiles successfully in my workspace, I check-in the changes and I set the branch attribute to resolved again, and the related Jira Issue’s status to Implemented:
ConflictsBot triggers another conflict check for branch /main/PNU-5:
And, this time no manual conflicts were detected. But… did you notice the branch /main/PNU-4 turned to yellow in the Branch Explorer screenshot? That means TrunkBot picked it in the meantime we were fixing our conflicting branch /main/PNU-5. And, TrunkBot finally succeeds:
And here’s where ConflictsBot really shines (explanation below the screenshot):
Several actions happened since the previous report:
- TrunkBot successfully merged /main/PNU-4 into /main branch, and hence, it set the branch “status” attribute to merged.
- Since the branch status was set to merged, ConflictsBot removes /main/PNU-4 from its queue, and won’t be processed again (it makes sense, as it was already merged).
- A new changeset was created in /main branch as a result of merging branch /main/PNU-4.
- ConflictsBot detects this new changeset in the /main branch, and triggers a new merge conflicts check for the remaining queued, resolved tasks: /main/PNU-2 and /main/PNU-5. In this case, no more manual conflicts appeared as the report shows. But, if new changesets are created in /main branch, and they cause manual conflicts with resolved but pending to integrate branches, the branch owner is posted instantly!
And that’s all! Hopefully, this DevOps setup helps you improving the speed of your deployment pipeline by preventing rejection of code at latter stages because of manual merge conflicts.