11# Build Pipeline - Continuous Integration
2- # if trigger is not merge commit from pull request, then pipeline will abort
2+ # if commit is not from a pull request, then the pipeline will abort - bypass this check by setting the SkipPullRequestCheck variable at queue time
33
44trigger :
55- main
@@ -12,41 +12,124 @@ pool:
1212variables :
1313 solution : ' **/*.sln'
1414 buildPlatform : ' Any CPU'
15- buildConfiguration : ' Release '
15+ NUGET_PACKAGES : $(Pipeline.Workspace)/.nuget/packages
1616
1717steps :
18+ - checkout : self
19+ persistCredentials : true
20+
1821- task : PowerShell@2
1922 displayName : Get Pull Request
23+ condition : and(succeeded(), eq(variables['SkipPullRequestCheck'], ''))
2024 inputs :
2125 targetType : ' inline'
2226 script : |
2327 try {
2428 $headers = @{ "Authorization" = "Bearer $(GitHubToken)"}
2529 $uri = 'https://api.github.com/repos/$(Build.Repository.Name)/commits/$(Build.SourceVersion)/pulls'
30+ Write-Output "uri = $uri"
2631 $response = Invoke-WebRequest -Uri $uri -Headers $headers -Method Get
2732 $content = $response.content | ConvertFrom-Json
28- if (-not($content -and $content[0] -and $content[0].id)) {
29- throw "** abort non-PR commit"
33+ # Check if the $content is not empty and iterate through each pull request
34+ if (-not ($content -and $content.Count -gt 0)) {
35+ Write-Host "##vso[task.logissue type=error;]Failed: Commit is not from a pull request."
36+ exit 1
37+ }
38+ $matchedPullRequest = $null
39+ foreach ($pullRequest in $content) {
40+ if ($pullRequest.merge_commit_sha -eq "$(Build.SourceVersion)") {
41+ $matchedPullRequest = $pullRequest
42+ break
43+ }
44+ }
45+ # Check if a matching pull request was found
46+ if (-not $matchedPullRequest) {
47+ Write-Host "##vso[task.logissue type=error;]Failed: No pull request found with merge commit SHA = '$(Build.SourceVersion)'."
48+ exit 1
3049 }
50+ # If a matching pull request is found, set the variables and continue
51+ Write-Host "##vso[task.setvariable variable=pullRequestHeadRef;]$($matchedPullRequest.head.ref)"
52+ Write-Host "##vso[task.setvariable variable=pullRequestBaseRef;]$($matchedPullRequest.base.ref)"
3153 } catch {
32- Write-Host "Error getting pull request | $_"
54+ Write-Host "##vso[task.logissue type=error;] Error getting pull request - | $_"
3355 exit 1
3456 }
57+
58+ - task : PowerShell@2
59+ displayName : Reset Development Branch
60+ condition : and(succeeded(), eq(variables['SkipPullRequestCheck'], ''))
61+ inputs :
62+ targetType : ' inline'
63+ script : |
64+ if ("$(pullRequestHeadRef)" -eq "development" -and "$(pullRequestBaseRef)" -eq "main") {
65+ # Define required headers for Azure DevOps | url is pulled from 'common' variable group in library
66+ $azureDevOpsAuthenicationHeader = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$(AzureDevOpsToken)")); "Content-Type" = "application/json"}
67+ # Define the base URL for Azure DevOps API
68+ $azureDevOpsRequestUri = "$(AzureDevOpsBuildApiUrl)/_apis/build/definitions/$(System.DefinitionId)?api-version=7.0"
69+ try {
70+ $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "", "$(GitHubToken)")))
71+ # Get the current pipeline definition
72+ $current_definition = Invoke-RestMethod -Method Get -Uri $azureDevOpsRequestUri -Headers $azureDevOpsAuthenicationHeader
73+ # Disable build pipeline
74+ $current_definition.queueStatus = "disabled"
75+ $disabled_definition = $current_definition | ConvertTo-Json -Depth 100
76+ Invoke-RestMethod -Method Put -Uri $azureDevOpsRequestUri -Headers $azureDevOpsAuthenicationHeader -Body $disabled_definition
77+ # Perform the reset
78+ git config user.email "no-reply@intuitionps.com"
79+ git config user.name "intuitionps Azure DevOps"
80+ git checkout development
81+ if ($LASTEXITCODE -ne 0) { throw "git checkout development" }
82+ git fetch origin
83+ if ($LASTEXITCODE -ne 0) { throw "git fetch origin" }
84+ git reset --hard origin/main
85+ if ($LASTEXITCODE -ne 0) { throw "git reset --hard origin/main" }
86+ git push --force origin development
87+ if ($LASTEXITCODE -ne 0) { throw "git push --force origin development" }
88+ Write-Host "Successfully reset development branch from main branch."
89+ } catch {
90+ Write-Host "##vso[task.logissue type=error;]Error resetting development branch with main branch - | $_"
91+ } finally {
92+ try {
93+ # Get the current pipeline definition
94+ $current_definition = Invoke-RestMethod -Method Get -Uri $azureDevOpsRequestUri -Headers $azureDevOpsAuthenicationHeader
95+ # Enable build pipeline
96+ $current_definition.queueStatus = "enabled"
97+ $enabled_definition = $current_definition | ConvertTo-Json -Depth 100
98+ Invoke-RestMethod -Method Put -Uri $azureDevOpsRequestUri -Headers $azureDevOpsAuthenicationHeader -Body $enabled_definition
99+ } catch {
100+ Write-Host "##vso[task.logissue type=error;]Error re-enabling build pipeline - | $_"
101+ }
102+ }
103+ } else {
104+ Write-Host "##vso[task.logissue type=warning;]Aborted: Only reset if base branch is 'main' and head branch is 'development'."
105+ }
106+ ignoreLASTEXITCODE : true
35107
36108- task : NuGetToolInstaller@1
37109 displayName : Install NuGet Tool
38110
111+ - task : Cache@2
112+ displayName : Cache NuGet packages
113+ inputs :
114+ key : ' nuget | "$(Agent.OS)" | **/packages.lock.json,!**/bin/**,!**/obj/**'
115+ restoreKeys : |
116+ nuget | "$(Agent.OS)"
117+ nuget
118+ path : ' $(NUGET_PACKAGES)'
119+
39120- task : NuGetCommand@2
40121 displayName : Restore Solution
41122 inputs :
42123 restoreSolution : ' $(solution)'
124+ feedsToUse : ' select'
125+ vstsFeed : ' 01c84548-9607-4655-80e7-6ad95390a38c/3823d26d-e8ca-40c4-a6f3-c3bd13f9658b'
43126
44127- task : SonarQubePrepare@5
45128 displayName : SonarQube - Prepare Analysis Configuration
46129 inputs :
47130 SonarQube : ' SonarQube'
48131 scannerMode : ' MSBuild'
49- projectKey : ' Ethos-Integration-SDK '
132+ projectKey : ' $(SonarQubeProjectKey) '
50133
51134- task : VSBuild@1
52135 displayName : Build Solution
@@ -64,9 +147,30 @@ steps:
64147 inputs :
65148 pollingTimeoutSec : ' 300'
66149
67- - task : sonar-buildbreaker@8
150+ - task : PowerShell@2
151+ displayName : SonarQube - Get Project Status
68152 inputs :
69- SonarQube : ' SonarQube'
153+ targetType : ' inline'
154+ script : |
155+ try {
156+ $headers = @{
157+ "Content-Type" = "application/json"
158+ "Authorization" = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$(SonarQubeToken):"))
159+ }
160+ $uri = 'https://ca-intuition-devops-sonarqube.azurewebsites.net/api/qualitygates/project_status?projectKey=$(SonarQubeProjectKey)&branch=$(Build.SourceBranchName)'
161+ Write-Output "uri = $uri"
162+ $response = Invoke-WebRequest -Uri $uri -Headers $headers -Method Get
163+ $content = $response.Content | ConvertFrom-Json
164+ $status = $content.projectStatus.status
165+ Write-Output "SonarQube Project Status = $status"
166+ if ($content.projectStatus.status -eq "ERROR") {
167+ Write-Host "##vso[task.logissue type=error;]Failed: Code analysis did not pass SonarQube quality gate."
168+ exit 1
169+ }
170+ } catch {
171+ Write-Host "##vso[task.logissue type=error;]Error getting project status - | $_"
172+ exit 1
173+ }
70174
71175 - task : PublishBuildArtifacts@1
72176 displayName : Publish Pipeline Artifacts
0 commit comments