From 9debb7702b1d32c60044eb6bc16bbd0a2975a1c9 Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Tue, 9 Jan 2024 15:03:47 -0800 Subject: [PATCH 1/3] [ci] Add API Scan job Context: https://devdiv.visualstudio.com/DevDiv/_wiki/wikis/DevDiv.wiki/25351/APIScan-step-by-step-guide-to-setting-up-a-Pipeline The ApiScan task has been added to pipeline runs against `main`. This task should help us identify related issues earlier, rather than having to wait for a full scan of VS. --- build-tools/automation/azure-pipelines.yaml | 76 ++++++++++++++++++--- 1 file changed, 65 insertions(+), 11 deletions(-) diff --git a/build-tools/automation/azure-pipelines.yaml b/build-tools/automation/azure-pipelines.yaml index f1c79490f..d30c08c35 100644 --- a/build-tools/automation/azure-pipelines.yaml +++ b/build-tools/automation/azure-pipelines.yaml @@ -16,6 +16,10 @@ pr: - README.md - Documentation/* +parameters: +- name: ApiScanSourceBranch + default: 'refs/heads/main' + # Global variables variables: RunningOnCI: true @@ -57,19 +61,11 @@ jobs: - template: templates\fail-on-issue.yaml - - task: ArchiveFiles@2 - displayName: 'Archive build outputs' - inputs: - rootFolderOrFile: 'bin' - archiveType: 'zip' - archiveFile: '$(Build.ArtifactStagingDirectory)/bin-dotnet.zip' - replaceExistingArchive: true - condition: succeededOrFailed() - - task: PublishBuildArtifacts@1 - displayName: 'Publish Artifact: debug' + displayName: Publish build artifacts inputs: - ArtifactName: debug + artifactName: artifacts + targetPath: bin condition: succeededOrFailed() - job: mac_dotnet_build @@ -96,6 +92,64 @@ jobs: - template: templates\fail-on-issue.yaml +- job: api_scan + displayName: API Scan + dependsOn: windows_dotnet_build + pool: + name: Azure Pipelines + vmImage: windows-2022 + timeoutInMinutes: 480 + workspace: + clean: all + variables: + - name: ApiScan.Enabled + value: true + steps: + - task: DownloadPipelineArtifact@2 + displayName: Download build artifacts + inputs: + artifactName: artifacts + downloadPath: $(Build.StagingDirectory) + + - task: APIScan@2 + displayName: Run APIScan + inputs: + softwareFolder: $(Build.StagingDirectory) + symbolsFolder: 'SRV*http://symweb;$(Build.StagingDirectory)' + softwareName: $(ApiScanName) + softwareVersionNum: $(Build.SourceBranchName)-$(Build.SourceVersion)$(System.JobAttempt) + isLargeApp: true + toolVersion: Latest + condition: and(succeeded(), eq(variables['ApiScan.Enabled'], 'true'), eq(variables['Build.SourceBranch'], '${{ parameters.ApiScanSourceBranch }}')) + env: + AzureServicesAuthConnectionString: runAs=App;AppId=$(ApiScanClientId);TenantId=$(ApiScanTenant);AppKey=$(ApiScanSecret) + + - task: SdtReport@2 + displayName: Guardian Export - Security Report + inputs: + GdnExportAllTools: false + GdnExportGdnToolApiScan: true + GdnExportOutputSuppressionFile: source.gdnsuppress + condition: and(succeededOrFailed(), eq(variables['ApiScan.Enabled'], 'true'), eq(variables['Build.SourceBranch'], '${{ parameters.ApiScanSourceBranch }}')) + + - task: PublishSecurityAnalysisLogs@3 + displayName: Publish Guardian Artifacts + inputs: + ArtifactName: APIScan Logs + ArtifactType: Container + AllTools: false + APIScan: true + ToolLogsNotFoundAction: Warning + condition: and(succeededOrFailed(), eq(variables['ApiScan.Enabled'], 'true'), eq(variables['Build.SourceBranch'], '${{ parameters.ApiScanSourceBranch }}')) + + - task: PostAnalysis@2 + displayName: Fail Build on Guardian Issues + inputs: + GdnBreakAllTools: false + GdnBreakGdnToolApiScan: true + condition: and(succeededOrFailed(), eq(variables['ApiScan.Enabled'], 'true'), eq(variables['Build.SourceBranch'], '${{ parameters.ApiScanSourceBranch }}')) + + - job: OneLocBuild displayName: OneLocBuild condition: and(eq(variables['System.TeamProject'], 'DevDiv'), eq(variables['Build.SourceBranch'], 'refs/heads/main')) From 070beea11bf9aa3e8c7d3dc878f0c7519f1a0c8d Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Tue, 9 Jan 2024 15:27:56 -0800 Subject: [PATCH 2/3] Update upload task, conditions --- build-tools/automation/azure-pipelines.yaml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/build-tools/automation/azure-pipelines.yaml b/build-tools/automation/azure-pipelines.yaml index d30c08c35..969360d93 100644 --- a/build-tools/automation/azure-pipelines.yaml +++ b/build-tools/automation/azure-pipelines.yaml @@ -61,7 +61,7 @@ jobs: - template: templates\fail-on-issue.yaml - - task: PublishBuildArtifacts@1 + - task: PublishPipelineArtifact@1 displayName: Publish build artifacts inputs: artifactName: artifacts @@ -95,15 +95,13 @@ jobs: - job: api_scan displayName: API Scan dependsOn: windows_dotnet_build + condition: and(eq(dependencies.windows_dotnet_build.result, 'Succeeded'), eq(variables['Build.SourceBranch'], '${{ parameters.ApiScanSourceBranch }}')) pool: name: Azure Pipelines vmImage: windows-2022 timeoutInMinutes: 480 workspace: clean: all - variables: - - name: ApiScan.Enabled - value: true steps: - task: DownloadPipelineArtifact@2 displayName: Download build artifacts @@ -120,7 +118,6 @@ jobs: softwareVersionNum: $(Build.SourceBranchName)-$(Build.SourceVersion)$(System.JobAttempt) isLargeApp: true toolVersion: Latest - condition: and(succeeded(), eq(variables['ApiScan.Enabled'], 'true'), eq(variables['Build.SourceBranch'], '${{ parameters.ApiScanSourceBranch }}')) env: AzureServicesAuthConnectionString: runAs=App;AppId=$(ApiScanClientId);TenantId=$(ApiScanTenant);AppKey=$(ApiScanSecret) @@ -130,7 +127,6 @@ jobs: GdnExportAllTools: false GdnExportGdnToolApiScan: true GdnExportOutputSuppressionFile: source.gdnsuppress - condition: and(succeededOrFailed(), eq(variables['ApiScan.Enabled'], 'true'), eq(variables['Build.SourceBranch'], '${{ parameters.ApiScanSourceBranch }}')) - task: PublishSecurityAnalysisLogs@3 displayName: Publish Guardian Artifacts @@ -140,14 +136,12 @@ jobs: AllTools: false APIScan: true ToolLogsNotFoundAction: Warning - condition: and(succeededOrFailed(), eq(variables['ApiScan.Enabled'], 'true'), eq(variables['Build.SourceBranch'], '${{ parameters.ApiScanSourceBranch }}')) - task: PostAnalysis@2 displayName: Fail Build on Guardian Issues inputs: GdnBreakAllTools: false GdnBreakGdnToolApiScan: true - condition: and(succeededOrFailed(), eq(variables['ApiScan.Enabled'], 'true'), eq(variables['Build.SourceBranch'], '${{ parameters.ApiScanSourceBranch }}')) - job: OneLocBuild From 26c27776ad3d58622213ead97ab44974cccb34cf Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Wed, 10 Jan 2024 13:57:39 -0800 Subject: [PATCH 3/3] Only scan shipping content --- build-tools/automation/azure-pipelines.yaml | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/build-tools/automation/azure-pipelines.yaml b/build-tools/automation/azure-pipelines.yaml index 969360d93..7c15fbb13 100644 --- a/build-tools/automation/azure-pipelines.yaml +++ b/build-tools/automation/azure-pipelines.yaml @@ -107,13 +107,27 @@ jobs: displayName: Download build artifacts inputs: artifactName: artifacts - downloadPath: $(Build.StagingDirectory) + downloadPath: $(Build.SourcesDirectory) + + ### Copy .dll, .exe, .pdb files for APIScan + - task: CopyFiles@2 + displayName: Collect Files for APIScan + inputs: + Contents: | + $(Build.SourcesDirectory)\$(Build.Configuration)$(NetCoreTargetFrameworkPathSuffix)\**\?(*.dll|*.exe|*.pdb) + !$(Build.SourcesDirectory)\**\jnimarshalmethod-gen.* + !$(Build.SourcesDirectory)\**\Mono.CSharp.dll + !$(Build.SourcesDirectory)\**\SgmlReader.exe + !$(Build.SourcesDirectory)\**\win-*\java-interop.dll + TargetFolder: $(Build.StagingDirectory)\apiscan + OverWrite: true + flattenFolders: true - task: APIScan@2 displayName: Run APIScan inputs: - softwareFolder: $(Build.StagingDirectory) - symbolsFolder: 'SRV*http://symweb;$(Build.StagingDirectory)' + softwareFolder: $(Build.StagingDirectory)\apiscan + symbolsFolder: 'SRV*http://symweb;$(Build.StagingDirectory)\apiscan' softwareName: $(ApiScanName) softwareVersionNum: $(Build.SourceBranchName)-$(Build.SourceVersion)$(System.JobAttempt) isLargeApp: true