Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :

Enforce best practice check for every check-in

nmaenpaa Profile Picture nmaenpaa 101,146
Would you like to run mandatory best practice checks for your Dynamics 365 for Finance / Supply Chain Management code before every check-in? In this article I will demonstrate how to do it.

First of all, you need to create a PowerShell script that analyses the build logs and identifies any BP issues. Then you add this script to be executed as part of your build pipeline. Finally you activate gated check-in for the pipeline. Please be aware that you can only enable this check once you have a codebase that is completely free of BP issues. Until that, the check will always fail and it would prevent you from checking in anything.

You can also use this script to simply show you the number of BP issues on each build, without using gated check-in.

Analyze BP violations with a PowerShell script

Let's write a script that analyzes the build logs and detects any best practice violations. First, login to your build VM via RDP and create a file called CheckBP.ps1 in C:\DynamicsSDK folder (you can actually write this script directly in ADO build definition in the browser, but it's easier to test if you have it locally on build VM). The script should have following contents.
$applFolder = "C:\DynamicsSDK\VSOAgent\_work\2\Logs"
$folders = Get-ChildItem($applFolder)
$pattern = "xppbp.log"
$issuesFound;
Write-Output 'Counting best practice violations:'
foreach ($folder in $folders){
 $logFiles = Get-ChildItem($folder.FullName)
 foreach ($logFile in $logFiles){
  if($logFile.Name -match $pattern){
      $logFile.FullName |% {$n = $_; $c = 0; Get-Content -Path $_ -ReadCount 1000 |% { $c  = $_.Count }; "$n; $c"}
      $issuesFound = 1;
  }
 }
}
if ($issuesFound =  1){
    Write-Host "##vso[task.LogIssue type=error;]BP issues found."
    exit 1;
}

The last command ("exit 1") will cause the script to return an error to Azure DevOps.
Test the script. If there are BP issues, the script will tell you how many issues were found in each package.

Set up your build pipeline

You can use your existing build pipeline, or create a new one. I suggest creating a dedicated pipeline for gated check-in. This way you can disable all time consuming build steps that you don't need.
Start by cloning your existing build pipeline: in ADO, go to Pipelines - Builds - select your pipeline and click Clone. Then edit the new pipeline: Go to Tasks section, and add a new task of type PowerShell. The task should be added directly after "Build the solution" task.
  • Display name: "Check best practices"
  • Script path: "C:\DynamicsSDK\CheckBP.ps1" (or, select Type: "Inline Script" and write the script directly in the build definition.
  • Continue on error: false (this will make the build fail if there are BP violations). If you want to use this script simply for showing you the count of BP issues during your normal build, set this option to true.

Build-tasks3.png

Go to Variables section, and adjust some settings in order to make the build as quick as possible for the gated check-in (not mandatory):

  • DeployReports: 0 (we don't need to deploy reports)
  • SkipRuntimePackageGeneration: 1 (we can skip the package generation)
  • SkipSourcePackageGeneration: 1 (we can skip the model file generation)
  • SkipSyncEngine: If you think that you don't need db sync, you can set this to 1. However in that case you will not be able to run any unit tests that would require your database schema changes.
Now the pipeline is ready to be tested. You can trigger it from ADO to verify that everything works as expected. If there are BP issues, the build will fail. Finally, go to Triggers section of your pipeline and enable Gated check-in. You can use the default settings. Also remember to remove any schedules that you might have copied from your original pipeline.
BP-error.png

Test gated check-in

Check in something from Visual Studio. During check-in you will now see a dialog that tells you that the changes need to be built before the check-in is accepted.

Click "Build changes" and your changeset will end up in queue. You can see the build status if you click the link in the notification message in Team Explorer ("Click here to see the status of the validation build"). If there are no BP issues, your check-in is accepted. Otherwise it's rejected.
Gated-check-in.png

Comments

*This post is locked for comments

  • nmaenpaa Profile Picture nmaenpaa 101,146
    Posted at
    Benjamin, I think you might need to enhance the script a bit, and not make it fail with exit code 1 if there are 0 errors.
  • Benjamin Stebing Profile Picture Benjamin Stebing
    Posted at
    Nikolaos, I set this up and it runs, but it creates a log file every time. If there are no errors, the file contains 4 lines(2 blank and 2 summary). Because the file exists, it always sets the $issuesFound = 1; Is there some settings I need to get this to not produce the file when no violations and to limit the file contents to the errors without the summary lines? vvvv Dynamics.AX.TAS.xppbp.log vvvv Warnings: 0 Errors: 0 ^^^^ Dynamics.AX.TAS.xppbp.log ^^^^ I appreciate any assistance you can provide.
  • Artem Tymofyeyev Profile Picture Artem Tymofyeyev
    Posted at
    @Jonas_CD : thanks for the great tip! Does it mean that your code should contain zero BP warnings before applying BP enforcement? Do you mind sharing your custom BP suite?
  • Jonas DC Profile Picture Jonas DC
    Posted at
    We (delaware) have been doing this for almost 2 years now but the setup is a bit different. We do this by changing the build.targets file, if you change this file on your build server(s) your build will fail on all xppbp errors. We just have a powershell that corrects the build.targets file as it's reset after every quality or one version update of the build server. This is a lot quicker as it actually fails on the build step, you are now running the BP's twice, increasing your build time. If you are interested, this is the PowerShell you can execute at the start of your build pipeline. It doesn't need to be executed everytime, only after an update, but we just run it every time as it takes less than a second. Param([string]$dynamicsSdkPath) $buildFile = "$($dynamicsSdkPath)\Metadata\Microsoft.Dynamics.AX.Application.Build.targets" $path = [XML](Get-Content $buildFile) if([System.IO.File]::Exists($buildFile)) { $target = (($path.Project.Target|where {$_.Name -eq "Xppbp"})).Xppbp $target.FailOnLogWarnings = "TRUE" $target.ContinueOnError = "ErrorAndStop" $path.Save($BuildFile) Write-Host "Updated Xppbp attributes." } else { Write-Error ("File + $path not found.") exit 1 } Another tip is to include the BPRules.xml file of your model that holds the enabled / disabled best practices in your version control system, this way the build will take those into account as well. Hope this helps, it's always nice to see there are still people that do worry about best practices :-) We have even written a suite of our own best practices on top of the Microsoft ones.