Skip to content

Commit

Permalink
Apply latest Library.Template including SDT additions
Browse files Browse the repository at this point in the history
  • Loading branch information
AArnott committed Jan 5, 2022
1 parent 31117de commit be5af81
Show file tree
Hide file tree
Showing 20 changed files with 251 additions and 38 deletions.
4 changes: 4 additions & 0 deletions Directory.Build.props
Expand Up @@ -41,6 +41,10 @@
<PackageReference Include="CSharpIsNullAnalyzer" Version="0.1.300" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
<None Include="$(RepoRootPath)obj/NOTICE" Pack="true" PackagePath="" Visible="false" Condition=" Exists('$(RepoRootPath)obj/NOTICE') " />
</ItemGroup>

<ItemGroup>
<AdditionalFiles Include="$(MSBuildThisFileDirectory)stylecop.json" Link="stylecop.json" />
</ItemGroup>
Expand Down
10 changes: 8 additions & 2 deletions azure-pipelines/Get-SymbolFiles.ps1
Expand Up @@ -5,12 +5,16 @@
The root path to recursively search for PDBs.
.PARAMETER Tests
A switch indicating to find test-related PDBs instead of product-only PDBs.
.PARAMETER ConvertToWindowsPDBs
A switch to convert and return paths to Windows PDBs instead of portable PDBs.
Ignored on non-Windows agents.
#>
[CmdletBinding()]
param (
[parameter(Mandatory=$true)]
[string]$Path,
[switch]$Tests
[switch]$Tests,
[switch]$ConvertToWindowsPDBs=$true
)

$WindowsPdbSubDirName = "symstore"
Expand Down Expand Up @@ -54,7 +58,7 @@ $PDBs |% {

Write-Output $BinaryImagePath

if (-not ($IsMacOS -or $IsLinux)) {
if ($ConvertToWindowsPDBs -and -not ($IsMacOS -or $IsLinux)) {
# Convert the PDB to legacy Windows PDBs
Write-Host "Converting PDB for $_" -ForegroundColor DarkGray
$WindowsPdbDir = "$($_.Directory.FullName)\$WindowsPdbSubDirName"
Expand All @@ -65,5 +69,7 @@ $PDBs |% {
}

Write-Output "$WindowsPdbDir\$($_.BaseName).pdb"
} else {
Write-Output $_.FullName
}
}
10 changes: 10 additions & 0 deletions azure-pipelines/PoliCheckExclusions.xml
@@ -0,0 +1,10 @@
<PoliCheckExclusions>
<!--Each of these exclusions is a folder name -if \[name]\exists in the file path, it will be skipped -->
<Exclusion Type="FolderPathFull">NODE_MODULES|.STORE</Exclusion>
<!--Each of these exclusions is a folder name -if any folder or file starts with "\[name]", it will be skipped -->
<!-- <Exclusion Type="FolderPathStart">ABC|XYZ</Exclusion>-->
<!--Each of these file types will be completely skipped for the entire scan -->
<!-- <Exclusion Type="FileType">.ABC|.XYZ</Exclusion>-->
<!--The specified file names will be skipped during the scan regardless which folder they are in -->
<!-- <Exclusion Type="FileName">ABC.TXT|XYZ.CS</Exclusion>-->
</PoliCheckExclusions>
20 changes: 13 additions & 7 deletions azure-pipelines/artifacts/testResults.ps1
@@ -1,12 +1,18 @@
$result = @{}

if ($env:AGENT_TEMPDIRECTORY) {
# The DotNetCoreCLI uses an alternate location to publish these files
$guidRegex = '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$'
@{
$env:AGENT_TEMPDIRECTORY = (Get-ChildItem $env:AGENT_TEMPDIRECTORY -Directory |? { $_.Name -match $guidRegex } |% { Get-ChildItem "$($_.FullName)\dotnet*.dmp","$($_.FullName)\testhost*.dmp","$($_.FullName)\Sequence_*.xml" -Recurse });
}
} else {
$result[$env:AGENT_TEMPDIRECTORY] = (Get-ChildItem $env:AGENT_TEMPDIRECTORY -Directory |? { $_.Name -match $guidRegex } |% { Get-ChildItem "$($_.FullName)\dotnet*.dmp","$($_.FullName)\testhost*.dmp","$($_.FullName)\Sequence_*.xml" -Recurse });
}
else {
$testRoot = Resolve-Path "$PSScriptRoot\..\..\test"
@{
$testRoot = (Get-ChildItem "$testRoot\TestResults" -Recurse -Directory | Get-ChildItem -Recurse -File);
}
$result[$testRoot] = (Get-ChildItem "$testRoot\TestResults" -Recurse -Directory | Get-ChildItem -Recurse -File)
}

$testlogsPath = "$env:BUILD_ARTIFACTSTAGINGDIRECTORY\test_logs"
if (Test-Path $testlogsPath) {
$result[$testlogsPath] = Get-ChildItem "$testlogsPath\*";
}

$result
11 changes: 10 additions & 1 deletion azure-pipelines/build.yml
Expand Up @@ -5,10 +5,17 @@ parameters:
vmImage: windows-2022
- name: ShouldSkipOptimize
- name: includeMacOS
- name: EnableAPIScan
type: boolean
default: false

jobs:
- job: Windows
pool: ${{ parameters.windowsPool }}
variables:
- ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}:
# https://dev.azure.com/devdiv/DevDiv/_wiki/wikis/DevDiv.wiki/25351/APIScan-step-by-step-guide-to-setting-up-a-Pipeline
- group: VSCloudServices-APIScan
steps:
- checkout: self
clean: true
Expand All @@ -18,7 +25,7 @@ jobs:

- template: install-dependencies.yml

- powershell: '& (./azure-pipelines/Get-nbgv.ps1) cloud'
- powershell: '& (./azure-pipelines/Get-nbgv.ps1) cloud -ca'
displayName: Set build number

- ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}:
Expand All @@ -30,6 +37,8 @@ jobs:

- ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}:
- template: microbuild.after.yml
parameters:
EnableAPIScan: ${{ parameters.EnableAPIScan }}

- job: Linux
condition: ne(variables['OptProf'], 'true')
Expand Down
8 changes: 4 additions & 4 deletions azure-pipelines/dotnet.yml
@@ -1,5 +1,5 @@
steps:
# We use VSBuild instead of "dotnet build" on Windows where MicroBuild tasks have to run (since they don't support MSBuild Core yet).
# We use VSBuild instead of "dotnet build" on Windows because dllexport doesn't work on dotnet build.
- task: VSBuild@1
displayName: Build Visual Studio solution
inputs:
Expand All @@ -16,15 +16,15 @@ steps:
displayName: dotnet test -f net472
inputs:
command: test
arguments: --no-build -c $(BuildConfiguration) -f net472 --filter "TestCategory!=FailsInCloudTest" -v n /p:CollectCoverage=true --settings "$(Build.Repository.LocalPath)/azure-pipelines/$(Agent.OS).runsettings" /bl:"$(Build.ArtifactStagingDirectory)/build_logs/test_net472.binlog"
arguments: --no-build -c $(BuildConfiguration) -f net472 --filter "TestCategory!=FailsInCloudTest" -v n /p:CollectCoverage=true --settings "$(Build.Repository.LocalPath)/azure-pipelines/$(Agent.OS).runsettings" /bl:"$(Build.ArtifactStagingDirectory)/build_logs/test_net472.binlog" --diag "$(Build.ArtifactStagingDirectory)/test_logs/net472.txt"
testRunTitle: net472-$(Agent.JobName)
condition: and(ne(variables['OptProf'], 'true'), eq(variables['Agent.OS'], 'Windows_NT'))

- task: DotNetCoreCLI@2
displayName: dotnet test -f netcoreapp3.1
inputs:
command: test
arguments: --no-build -c $(BuildConfiguration) -f netcoreapp3.1 --filter "TestCategory!=FailsInCloudTest" -v n /p:CollectCoverage=true --settings "$(Build.Repository.LocalPath)/azure-pipelines/$(Agent.OS).runsettings" /bl:"$(Build.ArtifactStagingDirectory)/build_logs/test_netcoreapp3.1.binlog"
arguments: --no-build -c $(BuildConfiguration) -f netcoreapp3.1 --filter "TestCategory!=FailsInCloudTest" -v n /p:CollectCoverage=true --settings "$(Build.Repository.LocalPath)/azure-pipelines/$(Agent.OS).runsettings" /bl:"$(Build.ArtifactStagingDirectory)/build_logs/test_netcoreapp3.1.binlog" --diag "$(Build.ArtifactStagingDirectory)/test_logs/netcoreapp3.1.txt"
testRunTitle: netcoreapp3.1-$(Agent.JobName)
workingDirectory: test/Microsoft.VisualStudio.Threading.Tests
condition: ne(variables['OptProf'], 'true')
Expand All @@ -33,7 +33,7 @@ steps:
displayName: dotnet test -f net5.0
inputs:
command: test
arguments: --no-build -c $(BuildConfiguration) -f net5.0 --filter "TestCategory!=FailsInCloudTest" -v n /p:CollectCoverage=true --settings "$(Build.Repository.LocalPath)/azure-pipelines/$(Agent.OS).runsettings" /bl:"$(Build.ArtifactStagingDirectory)/build_logs/test_net5.0.binlog"
arguments: --no-build -c $(BuildConfiguration) -f net5.0 --filter "TestCategory!=FailsInCloudTest" -v n /p:CollectCoverage=true --settings "$(Build.Repository.LocalPath)/azure-pipelines/$(Agent.OS).runsettings" /bl:"$(Build.ArtifactStagingDirectory)/build_logs/test_net5.0.binlog" --diag "$(Build.ArtifactStagingDirectory)/test_logs/net5.0.txt"
testRunTitle: net5.0-$(Agent.JobName)
workingDirectory: test/Microsoft.VisualStudio.Threading.Tests
condition: ne(variables['OptProf'], 'true')
Expand Down
72 changes: 72 additions & 0 deletions azure-pipelines/falsepositives.gdnsuppress
@@ -0,0 +1,72 @@
{
"version": "latest",
"suppressionSets": {
"falsepositives": {
"name": "falsepositives",
"createdDate": "2022-01-05 21:55:03Z",
"lastUpdatedDate": "2022-01-05 21:55:03Z"
}
},
"results": {
"f2d4b996c6d7c4016ec4fcd8ffee323140ad820bf3e162080d3def56e8341e91": {
"signature": "f2d4b996c6d7c4016ec4fcd8ffee323140ad820bf3e162080d3def56e8341e91",
"alternativeSignatures": [],
"target": "src/Microsoft.VisualStudio.Threading.Analyzers.CSharp/VSTHRD003UseJtfRunAsyncAnalyzer.cs",
"memberOf": [
"falsepositives"
],
"tool": "policheck",
"ruleId": "80411",
"justification": null,
"createdDate": "2022-01-05 21:55:03Z",
"expirationDate": null,
"type": null
},
"5bd7dbbf8a0e638bc4ee65d7db6dc4ab9054ddd64f8ec5cf4031380b01100b63": {
"signature": "5bd7dbbf8a0e638bc4ee65d7db6dc4ab9054ddd64f8ec5cf4031380b01100b63",
"alternativeSignatures": [],
"target": "src/Microsoft.VisualStudio.Threading.Analyzers.CSharp/VSTHRD003UseJtfRunAsyncAnalyzer.cs",
"memberOf": [
"falsepositives"
],
"tool": "policheck",
"ruleId": "80411",
"justification": null,
"createdDate": "2022-01-05 21:55:03Z",
"expirationDate": null,
"type": null
},
"ed020ef10e60a1a49245aad9cd8922514ac643fe6f2f689cabdfc2205d725de5": {
"signature": "ed020ef10e60a1a49245aad9cd8922514ac643fe6f2f689cabdfc2205d725de5",
"alternativeSignatures": [
"2b12d128e16023e34f3070e5d1c3014207692966829acbf838fe1ec92ddf6798"
],
"target": "microsoft.visualstudio.threading/release/net472/microsoft.visualstudio.threading.dll",
"memberOf": [
"falsepositives"
],
"tool": "apiscan",
"ruleId": "documentationnotfound",
"justification": null,
"createdDate": "2022-01-05 21:55:03Z",
"expirationDate": null,
"type": null
},
"72600e5e09c73929820080a3d7fbbd591c4aac41a606251af6755e2ea3e96286": {
"signature": "72600e5e09c73929820080a3d7fbbd591c4aac41a606251af6755e2ea3e96286",
"alternativeSignatures": [
"e0697b669d792491bda5ab3c49a1c1bc71adc6c2a4cd903163c8d956aec5d16f"
],
"target": "microsoft.visualstudio.threading/release/netstandard2.0/microsoft.visualstudio.threading.dll",
"memberOf": [
"falsepositives"
],
"tool": "apiscan",
"ruleId": "documentationnotfound",
"justification": null,
"createdDate": "2022-01-05 21:55:03Z",
"expirationDate": null,
"type": null
}
}
}
9 changes: 6 additions & 3 deletions azure-pipelines/microbuild.after.yml
@@ -1,3 +1,7 @@
parameters:
- name: EnableAPIScan
type: boolean

steps:
- task: MicroBuildCodesignVerify@3
displayName: Verify Signed Files
Expand All @@ -9,9 +13,6 @@ steps:
condition: succeededOrFailed()
displayName: MicroBuild Cleanup

- task: ComponentGovernanceComponentDetection@0
displayName: Component Detection

- task: ms-vscs-artifact.build-tasks.artifactDropTask-1.artifactDropTask@0
inputs:
dropServiceURI: https://devdiv.artifacts.visualstudio.com
Expand Down Expand Up @@ -45,3 +46,5 @@ steps:
continueOnError: true

- template: secure-development-tools.yml
parameters:
EnableAPIScan: ${{ parameters.EnableAPIScan }}
9 changes: 9 additions & 0 deletions azure-pipelines/microbuild.before.yml
Expand Up @@ -2,6 +2,15 @@ parameters:
- name: ShouldSkipOptimize

steps:
- task: ComponentGovernanceComponentDetection@0
displayName: Component Detection

- task: notice@0
displayName: Generate NOTICE file
inputs:
outputfile: $(System.DefaultWorkingDirectory)/obj/NOTICE
outputformat: text

- task: MicroBuildOptProfPlugin@6
inputs:
ProfilingInputsDropName: ProfilingInputs/$(System.TeamProject)/$(Build.Repository.Name)/$(Build.SourceBranchName)/$(Build.BuildNumber)
Expand Down
5 changes: 5 additions & 0 deletions azure-pipelines/official.yml
Expand Up @@ -35,6 +35,10 @@ parameters:
displayName: Build on macOS
type: boolean
default: false # macOS is often bogged down in Azure Pipelines
- name: EnableAPIScan
displayName: Run APIScan
type: boolean
default: true

variables:
NugetSecurityAnalysisWarningLevel: none # nuget.config requires signed packages by trusted owners
Expand All @@ -53,6 +57,7 @@ stages:
jobs:
- template: build.yml
parameters:
EnableAPIScan: ${{ parameters.EnableAPIScan }}
windowsPool: VSEngSS-MicroBuild2022-1ES
ShouldSkipOptimize: ${{ parameters.ShouldSkipOptimize }}
includeMacOS: ${{ parameters.includeMacOS }}
Expand Down
6 changes: 3 additions & 3 deletions azure-pipelines/publish-codecoverage.yml
Expand Up @@ -18,10 +18,10 @@ steps:
- powershell: |
dotnet tool install --tool-path obj dotnet-reportgenerator-globaltool --version 4.8.5 --configfile azure-pipelines/justnugetorg.nuget.config
Copy-Item -Recurse $(Pipeline.Workspace)/coverageResults-Windows/obj/* $(System.DefaultWorkingDirectory)/obj
Write-Host "Substituting {reporoot} with $(System.DefaultWorkingDirectory)"
$reports = Get-ChildItem -Recurse "$(Pipeline.Workspace)/coverage.*cobertura.xml"
Write-Host 'Substituting {reporoot} with $(System.DefaultWorkingDirectory)'
$reports = Get-ChildItem -Recurse '$(Pipeline.Workspace)/coverage.*cobertura.xml'
$reports |% {
$content = Get-Content -Path $_ |% { $_.Replace("{reporoot}", "$(System.DefaultWorkingDirectory)") }
$content = Get-Content -Path $_ |% { $_.Replace('{reporoot}', '$(System.DefaultWorkingDirectory)') }
Set-Content -Path $_ -Value $content -Encoding UTF8
}
$Inputs = [string]::join(';', ($reports |% { Resolve-Path -relative $_ }))
Expand Down
6 changes: 3 additions & 3 deletions azure-pipelines/release.yml
Expand Up @@ -47,8 +47,8 @@ stages:
{ "label" : "enhancement", "displayName": "Enhancements", "state" : "closed" }
]
- stage: push_packages
displayName: Push packages
- stage: nuget_org
displayName: nuget.org
dependsOn: GitHubRelease
jobs:
- deployment: push
Expand All @@ -67,7 +67,7 @@ stages:
inputs:
versionSpec: 5.x
- task: NuGetCommand@2
displayName: nuget.org
displayName: NuGet push
inputs:
command: push
packagesToPush: $(Pipeline.Workspace)/CI/deployables-Windows/NuGet/*.nupkg
Expand Down
73 changes: 68 additions & 5 deletions azure-pipelines/secure-development-tools.yml
@@ -1,11 +1,74 @@
parameters:
- name: EnableAPIScan
type: boolean

steps:

### Check for checked in credentials.
- task: CredScan@3
displayName: 'Run CredScan'
displayName: Run CredScan

### Run PoliCheck to check for disallowed terms. targetType: F indicates we're searching files and folders.
- task: PoliCheck@1
displayName: 'Run PoliCheck'
- task: PoliCheck@2
displayName: Run PoliCheck
inputs:
targetType: F
targetArgument: $(System.DefaultWorkingDirectory)
optionsUEPATH: $(System.DefaultWorkingDirectory)\azure-pipelines\PoliCheckExclusions.xml

- task: BinSkim@3
displayName: Run BinSkim
inputs:
InputType: Basic
Function: analyze
AnalyzeTarget: $(BinSkimTargets)

- task: CopyFiles@2
displayName: Collect APIScan inputs
inputs:
SourceFolder: $(Build.ArtifactStagingDirectory)/Symbols-$(Agent.JobName)
# Exclude any patterns from the Contents (e.g. `!**/git2*`) that we have symbols for but do not need to run APIScan on.
Contents: |
**
TargetFolder: $(Build.ArtifactStagingDirectory)/APIScanInputs
condition: and(succeeded(), ${{ parameters.EnableAPIScan }}, ne(variables.ApiScanClientId, ''))

- task: APIScan@2
displayName: Run APIScan
inputs:
softwareFolder: $(Build.ArtifactStagingDirectory)/APIScanInputs
softwareName: $(SymbolsFeatureName)
softwareVersionNum: $(NBGV_MajorMinorVersion)
isLargeApp: false
toolVersion: Latest
condition: and(succeeded(), ${{ parameters.EnableAPIScan }}, ne(variables.ApiScanClientId, ''))
env:
AzureServicesAuthConnectionString: runAs=App;AppId=$(ApiScanClientId);TenantId=$(ApiScanTenant);AppKey=$(ApiScanSecret)

- task: SdtReport@2
displayName: Create Security Analysis Report
inputs:
GdnExportAllTools: true

- task: PublishSecurityAnalysisLogs@3
displayName: Publish Code Analysis Logs
inputs:
ArtifactName: CodeAnalysisLogs
ArtifactType: Container
PublishProcessedResults: true
AllTools: true
ToolLogsNotFoundAction: Standard

- task: PostAnalysis@2
displayName: Break on compliance issues
inputs:
GdnBreakAllTools: true
GdnBreakGdnToolBinSkimSeverity: Warning
GdnBreakSuppressionFiles: $(System.DefaultWorkingDirectory)/azure-pipelines/falsepositives.gdnsuppress
GdnBreakSuppressionSets: falsepositives
GdnBreakOutputSuppressionFile: $(Build.ArtifactStagingDirectory)/guardian_failures_as_suppressions/
GdnBreakOutputSuppressionSet: falsepositives

# This is useful when false positives appear so we can copy some of the output into the suppressions file.
- publish: $(Build.ArtifactStagingDirectory)/guardian_failures_as_suppressions
artifact: guardian_failures_as_suppressions
displayName: Publish Guardian failures
condition: failed()

0 comments on commit be5af81

Please sign in to comment.