diff --git a/build/onebranch/botbuilder-dotnet-signed.yml b/build/onebranch/botbuilder-dotnet-signed.yml deleted file mode 100644 index 203013b7d9..0000000000 --- a/build/onebranch/botbuilder-dotnet-signed.yml +++ /dev/null @@ -1,34 +0,0 @@ -# ASP.NET Core (.NET Framework) -# Build and test ASP.NET Core projects targeting the full .NET Framework. -# Add steps that publish symbols, save build artifacts, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core - -trigger: -- main - -pool: - vmImage: 'windows-latest' - -variables: - solution: '**/*.sln' - buildPlatform: 'Any CPU' - buildConfiguration: 'Release' - -steps: -- task: NuGetToolInstaller@1 - -- task: NuGetCommand@2 - inputs: - restoreSolution: '$(solution)' - -- task: VSBuild@1 - inputs: - solution: '$(solution)' - msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site"' - platform: '$(buildPlatform)' - configuration: '$(buildConfiguration)' - -- task: VSTest@2 - inputs: - platform: '$(buildPlatform)' - configuration: '$(buildConfiguration)' diff --git a/build/onebranch/ci-api-validation-steps.yml b/build/onebranch/ci-api-validation-steps.yml new file mode 100644 index 0000000000..dfb8d1cbf1 --- /dev/null +++ b/build/onebranch/ci-api-validation-steps.yml @@ -0,0 +1,129 @@ +steps: +- task: DownloadPipelineArtifact@2 + displayName: 'Download BotBuilderDLLs from Artifacts' + inputs: + artifactName: 'BotBuilderDLLs-Debug-Windows-netcoreapp31' + targetPath: '$(System.ArtifactsDirectory)/OutputDlls' + +- task: DownloadPipelineArtifact@2 + displayName: 'Download ContractDlls from Artifacts' + inputs: + artifactName: 'ContractDlls' + targetPath: '$(System.ArtifactsDirectory)/ContractDlls' + +- powershell: | + Write-Host "The following API compatibility issues are suppressed:"; + Get-Content "ApiCompatBaseline.txt"; + displayName: 'Show API compat issue suppressions in ApiCompatBaseline.txt' + continueOnError: true + +- task: SOUTHWORKS.binaries-comparer.custom-build-release-task.binaries-comparer@0 + displayName: 'Compare Binaries' + inputs: + contractsRootFolder: '$(System.ArtifactsDirectory)/ContractDlls' + contractsFileName: '$(PackageName).dll' + implFolder: '$(System.ArtifactsDirectory)/OutputDlls' + failOnIssue: false + resolveFx: false + generateLog: true + outputFilename: '$(PackageName).$(ApiContractVersion).CompatResults.txt' + outputFolder: '$(Build.ArtifactStagingDirectory)' + useBaseline: true + baselineFile: ApiCompatBaseline.txt + continueOnError: false + +- powershell: | + $filePath = "$(Build.ArtifactStagingDirectory)\$(PackageName).$(ApiContractVersion).CompatResults.txt" + $nugetLink = "compared against [version $(ApiContractVersion)](https://www.nuget.org/packages/$(PackageName)/$(ApiContractVersion))."; + Write-Host "Compatibility Check:"; + + if (-not (Test-Path $filePath)) { + $content = "The binary compatibility report for library '$(PackageName)' wasn't generated. This may have happened because the NuGet library '$(PackageName)' for version '$(ApiContractVersion)' was unavailable or a connectivity issue." + New-Item -Path '$(Build.ArtifactStagingDirectory)' -Name '$(PackageName).$(ApiContractVersion).CompatResults.txt' -ItemType "file" -Value $content + $content; + Write-Host "##vso[task.complete result=Failed;]"; + return; + } + + $baseline = Get-Content $filePath -Raw; + Write-Host "`n[Compare binaries task]"; + Write-Host "`nOriginal result:"; + $baseline; + + # When the Api Compat task has Binary compatibility issues, this process will filter out the Classes + # and then validates if still exists remaining issues. + if ($baseline.ToString().Trim().StartsWith(':x:')) { + Write-Host "`n[Class exclusion]"; + $excludeClasses = "$($env:ApiCompatExcludeClasses)".Trim().Split(',') | Where-Object { ($_.Trim().Length -gt 0) } | ForEach-Object { $_.Trim() }; + + if ($excludeClasses) { + Write-Host "`nList of classes to exclude:"; + $excludeClasses | ForEach-Object { " - " + $_ } + } + else { + Write-Host "`nThere are no classes to exclude."; + } + + $content = ($baseline -split '|<\/details\>'); + $header = $content[0].SubString($content[0].IndexOf('Binary') - 1).Trim(); + $issues = $content[1].Trim(); + $issues = ($issues -replace '```', '').Split([Environment]::NewLine); + + # Filter out issues based on Class name. + $issues = @( + $issues | Where-Object { + $line = $_; + if (-not $line.Trim()) { + return $false; + } + if ($excludeClasses) { + foreach ($class in $excludeClasses) { + $pattern = "'$class"; + if ($line -match $pattern) { + return $false; + } + } + } + return $true; + } | ForEach-Object { $_.Trim() } + ) + + # Creates new file content. + if ($issues) { + $newFile = @(); + $newfile += ":x: $($issues.Length) $header $nugetLink"; + $newFile += '
'; + $newFile += ""; + $newFile += '```'; + $newfile += $issues; + $newFile += '```'; + $newFile += ""; + $newFile += '
'; + + $newFile = $newFile -join [Environment]::NewLine; + Write-Host "##vso[task.complete result=Failed;]"; + } + else { + $newFile = ":heavy_check_mark: No Binary Compatibility issues for **$(PackageName)** $nugetLink"; + } + + $baseline = $newFile; + [system.io.file]::WriteAllText($filePath, $baseline); + Write-Host "`nProcessed result:"; + $baseline; + } + displayName: 'Compatibility Check' + continueOnError: false + condition: succeededOrFailed() + +- task: PublishBuildArtifacts@1 + displayName: 'Publish Compat Results artifact' + inputs: + ArtifactName: '$(PackageName).$(ApiContractVersion).CompatResults' + condition: succeededOrFailed() + +- script: | + dir .. /s + displayName: 'Dir workspace' + continueOnError: true + condition: succeededOrFailed() diff --git a/build/onebranch/ci-build-steps.yml b/build/onebranch/ci-build-steps.yml new file mode 100644 index 0000000000..ad4cf8eced --- /dev/null +++ b/build/onebranch/ci-build-steps.yml @@ -0,0 +1,44 @@ +steps: +- powershell: 'gci env:* | sort-object name | Format-Table -AutoSize -Wrap' + displayName: 'Display env vars' + +# Variables ReleasePackageVersion and PreviewPackageVersion are consumed by projects in Microsoft.Bot.Builder.sln. +# For the signed build, they should be settable at queue time. To set that up, define the variables in Azure on the Variables tab. +- task: NuGetToolInstaller@1 + displayName: 'Use NuGet ' + +- template: sdk_dotnet_v4_org-feed-setup-steps.yml + +- task: NuGetToolInstaller@1 + displayName: 'Use NuGet latest' + +- task: NuGetCommand@2 + inputs: + command: 'restore' + feedsToUse: 'config' + nugetConfigPath: 'nuget.config' + restoreSolution: '$(Parameters.solution)' + displayName: 'NuGet restore' + +- task: VSBuild@1 + displayName: 'Build solution Microsoft.Bot.Builder.sln' + inputs: + solution: '$(Parameters.solution)' + vsVersion: 17.0 + msbuildArgs: '$(MSBuildArguments)' + platform: '$(BuildPlatform)' + configuration: '$(BuildConfiguration)' + maximumCpuCount: true + logProjectEvents: false + +#- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 +# displayName: 'Component Detection' +# inputs: +# failOnAlert: true + +#- script: | +# cd .. +# dir *.* /s +# displayName: 'Dir workspace' +# continueOnError: true +# condition: succeededOrFailed() diff --git a/build/onebranch/ci-component-detection-steps.yml b/build/onebranch/ci-component-detection-steps.yml new file mode 100644 index 0000000000..258426b12d --- /dev/null +++ b/build/onebranch/ci-component-detection-steps.yml @@ -0,0 +1,8 @@ +steps: +- task: ComponentGovernanceComponentDetection@0 + displayName: Component Detection + inputs: + scanType: "Register" + verbosity: "Verbose" + alertWarningLevel: "High" + failOnAlert: true diff --git a/build/onebranch/ci-post-to-github-steps.yml b/build/onebranch/ci-post-to-github-steps.yml new file mode 100644 index 0000000000..e870edc924 --- /dev/null +++ b/build/onebranch/ci-post-to-github-steps.yml @@ -0,0 +1,38 @@ +steps: +- task: DownloadBuildArtifacts@0 + displayName: 'Download compat results artifact' + inputs: + downloadType: specific + itemPattern: '**\*.txt' + downloadPath: '$(System.ArtifactsDirectory)\ApiCompat' + +- task: CopyFiles@2 + displayName: 'Copy results for publish to Artifacts' + inputs: + SourceFolder: '$(System.ArtifactsDirectory)\ApiCompat' + Contents: '**\*.txt' + TargetFolder: '$(System.ArtifactsDirectory)\ApiCompatibilityResults' + flattenFolders: true + +- task: PublishPipelineArtifact@1 + inputs: + artifactName: 'ApiCompatibilityResults' + targetPath: '$(System.ArtifactsDirectory)\ApiCompatibilityResults' + displayName: 'Publish compat results to Artifacts' + continueOnError: true + +- task: SOUTHWORKS.github-pr-comment.custom-publish-comment-task.github-pr-comment@0 + displayName: 'Publish compat results to GitHub' + inputs: + userToken: '$(GitHubCommentApiKey)' + bodyFilePath: '$(System.ArtifactsDirectory)\ApiCompat' + getSubFolders: true + keepCommentHistory: false + # Skip for forks, as secret tokens are not available to them. + condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'), ne(variables['System.PullRequest.IsFork'], 'True')) + +- script: | + dir .. /s + displayName: 'Dir workspace' + continueOnError: true + condition: succeededOrFailed() diff --git a/build/onebranch/ci-test-steps.yml b/build/onebranch/ci-test-steps.yml new file mode 100644 index 0000000000..061a1168a9 --- /dev/null +++ b/build/onebranch/ci-test-steps.yml @@ -0,0 +1,106 @@ +#variables: +# DotNetCoverallsToken: define this in Azure +# PublishCoverage: (optional) set to true in the calling template. +steps: +- powershell: | + Remove-Item CodeCoverage -Force -Recurse -ErrorAction Ignore + New-Item CodeCoverage -ItemType Directory -Force + displayName: 'Create Code Coverage directory' + +- task: NodeTool@0 + displayName: 'install Node.js v14.x' + inputs: + versionSpec: '14.x' + +- task: Npm@1 + displayName: 'install botframework-cli to set up for Schema merge tests' + inputs: + command: custom + verbose: false + customCommand: 'install -g @microsoft/botframework-cli@next' + +- task: UseDotNet@2 + displayName: "Install .NET Core 3.1.415" + continueOnError: true + inputs: + packageType: "sdk" + version: 3.1.415 + condition: and(succeeded(), eq(variables['BuildConfiguration'],'Release-Windows'), eq(variables['BuildTarget'],'netcoreapp31')) + +- task: DotNetCoreCLI@2 + displayName: 'dotnet test (release) 3.1' + inputs: + command: test + projects: | + Tests/**/*Tests.csproj + + arguments: '-v n -f netcoreapp3.1 --configuration release --no-build --no-restore --filter "TestCategory!=IgnoreInAutomatedBuild&TestCategory!=FunctionalTests" --collect:"Code Coverage" --settings $(Build.SourcesDirectory)\CodeCoverage.runsettings' + condition: and(succeeded(), eq(variables['BuildConfiguration'],'Release-Windows'), eq(variables['BuildTarget'],'netcoreapp31')) + +- task: DotNetCoreCLI@2 + displayName: 'dotnet test (release) 6.0' + inputs: + command: test + projects: | + Tests/**/*Tests.csproj + + arguments: '-v n -f net6.0 --configuration release --no-build --no-restore --filter "TestCategory!=IgnoreInAutomatedBuild&TestCategory!=FunctionalTests" --collect:"Code Coverage" --settings $(Build.SourcesDirectory)\CodeCoverage.runsettings' + condition: and(succeeded(), eq(variables['BuildConfiguration'],'Release-Windows'), eq(variables['BuildTarget'],'net6')) + +- powershell: | + # This task copies the code coverage file created by dotnet test into a well known location. In all + # checks I've done, dotnet test ALWAYS outputs the coverage file to the temp directory. + # My attempts to override this and have it go directly to the CodeCoverage directory have + # all failed, so I'm just doing the copy here. (cmullins) + + Get-ChildItem -Path "D:\a\_temp" -Include "*.coverage" -Recurse | Copy-Item -Destination CodeCoverage + displayName: 'Copy .coverage Files to CodeCoverage folder' + condition: and(succeeded(), eq(variables['PublishCoverage'], 'true')) + +- powershell: 'echo ''##vso[task.setvariable variable=CoverallsToken]$(DotNetCoverallsToken)''' + displayName: 'Set CoverallsToken for PublishToCoveralls.ps1 if token exists' + continueOnError: true + condition: and(succeeded(), eq(variables['PublishCoverage'], 'true')) + +- powershell: | + dotnet nuget remove source SDK_Dotnet_V4_org + displayName: Remove SDK_Dotnet_V4_org feed source reference from nuget.config + continueOnError: true + condition: and(succeeded(), eq(variables['PublishCoverage'], 'true'), ne(variables['System.PullRequest.IsFork'], 'True')) + +- task: PowerShell@2 + displayName: 'Upload Coverage Files to Coveralls.io https://coveralls.io/github/microsoft/botbuilder-dotnet' + inputs: + targetType: filePath + filePath: '$(Build.SourcesDirectory)\build\PublishToCoveralls.ps1' + arguments: '-pathToCoverageFiles "$(Build.SourcesDirectory)\CodeCoverage" -serviceName "CI-PR build"' + continueOnError: true + # Skip for forks because it errors: "Couldn't find a repository matching this job." + condition: and(succeeded(), eq(variables['PublishCoverage'], 'true'), ne(variables['System.PullRequest.IsFork'], 'True')) + +- powershell: | + New-Item -ItemType directory -Path "outputLibraries\" -Force + + $buildTarget = $env:BuildConfiguration.Split("-")[0]; + + $env:PackagesToValidate.Split(",") | ForEach { + $library = $_.Trim() + Write-Host $library + + Get-ChildItem -Path "*/$library/bin/$buildTarget/netstandard2.0/$library.dll" -Recurse | Copy-Item -Destination 'outputLibraries\' -Force + Get-ChildItem -Path "*/*/$library/bin/$buildTarget/netstandard2.0/$library.dll" -Recurse | Copy-Item -Destination 'outputLibraries\' -Force + } + displayName: 'Copy DLLs to outputLibraries folder' + +- task: PublishPipelineArtifact@0 + displayName: 'Publish Microsoft.Bot.Builder DLLs artifact' + inputs: + artifactName: 'BotBuilderDLLs-$(BuildConfiguration)-$(BuildTarget)' + targetPath: outputLibraries + continueOnError: true + +- script: | + dir .. /s + displayName: 'Dir workspace' + continueOnError: true + condition: succeededOrFailed() diff --git a/build/onebranch/ci.yml b/build/onebranch/ci.yml new file mode 100644 index 0000000000..0b8bba30c3 --- /dev/null +++ b/build/onebranch/ci.yml @@ -0,0 +1,61 @@ +# +# Replaces the classic BotBuilder-DotNet-master-Signed-daily. +# + +# "name" here defines the build number format. Build number is accessed via $(Build.BuildNumber) +#name: $(Date:yyyyMMdd).$(Build.BuildId) + +#pool: +# vmImage: $[ coalesce( variables['VMImage'], 'windows-2022' ) ] # or 'windows-latest' +# demands: +# - msbuild +# - visualstudio + +#trigger: none # ci trigger is set in ADO +#pr: none # pr trigger is set in ADO + +variables: + BuildConfiguration: Release-Windows + TestConfiguration: Release + BuildPlatform: any cpu + MSBuildArguments: -p:PublishRepositoryUrl=true -p:GeneratePackages=true -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg + Packaging.EnableSBOMSigning: true + Parameters.solution: Microsoft.Bot.Builder.sln +# PreviewPackageVersion: 4.8.0-preview-$(Build.BuildNumber) # Consumed by projects in Microsoft.Bot.Builder.sln. Define this in Azure to be settable at queue time. +# ReleasePackageVersion: 4.8.0-preview-$(Build.BuildNumber) # Consumed by projects in Microsoft.Bot.Builder.sln. Define this in Azure to be settable at queue time. +# SDK_Dotnet_V4_org_Url: define this in Azure + +jobs: +- job: Build_and_Sign + steps: + - powershell: | + # Replace {DateStamp} and {CommitHash} tokens with the actual values in vars ReleasePackageVersion and PreviewPackageVersion + $dateStamp = (Get-Date -format "yyyyMMdd"); + $commitHash = "$(Build.SourceVersion)".SubString(0,7); + + "Raw ReleasePackageVersion = $(ReleasePackageVersion)"; + $v = "$(ReleasePackageVersion)".Replace("{DateStamp}",$dateStamp).Replace("{CommitHash}",$commitHash); + Write-Host "##vso[task.setvariable variable=ReleasePackageVersion;]$v"; + "Resolved ReleasePackageVersion = $v"; + + "Raw PreviewPackageVersion = $(PreviewPackageVersion)"; + $ppv = "$(PreviewPackageVersion)".Replace("{DateStamp}",$dateStamp).Replace("{CommitHash}",$commitHash); + Write-Host "##vso[task.setvariable variable=PreviewPackageVersion;]$ppv"; + "Resolved PreviewPackageVersion = $ppv"; + displayName: 'Resolve package version variables' + + - task: colinsalmcorner.colinsalmcorner-buildtasks.tag-build-task.tagBuildOrRelease@0 + displayName: 'Tag build with release and preview versions' + inputs: + tags: | + Release: $(ReleasePackageVersion) + Preview: $(PreviewPackageVersion) + continueOnError: true + + - template: ci-build-steps.yml + - template: sign-steps.yml + + #- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 + # displayName: 'Component Detection' + # inputs: + # failOnAlert: false diff --git a/build/onebranch/onebranch-dotnet-signed.yml b/build/onebranch/onebranch-dotnet-signed.yml new file mode 100644 index 0000000000..fd06666693 --- /dev/null +++ b/build/onebranch/onebranch-dotnet-signed.yml @@ -0,0 +1,64 @@ +################################################################################# +# OneBranch Pipelines # +# This pipeline was created by EasyStart from a sample located at: # +# https://aka.ms/obpipelines/easystart/samples # +# Documentation: https://aka.ms/obpipelines # +# Yaml Schema: https://aka.ms/obpipelines/yaml/schema # +# Retail Tasks: https://aka.ms/obpipelines/tasks # +# Support: https://aka.ms/onebranchsup # +################################################################################# +# https://aka.ms/obpipelines/triggers +trigger: none # ci trigger is set in ADO + +variables: + Codeql.TSAEnabled: true # Needed for Security Development Lifecycle (SDL) requirements http://aka.ms/codeql + WindowsContainerImage: onebranch.azurecr.io/windows/ltsc2019/vse2022:latest # for Windows jobs + LinuxContainerImage: cdpxlinux.azurecr.io/user/lsg-linux/lsg-yocto-project:latest # for Linux jobs + IsOfficialBuild: True + +name: $(Date:yyyyMMdd).$(Build.BuildId) + +resources: + repositories: + - repository: templates + type: git + name: OneBranch.Pipelines/GovernedTemplates + ref: refs/heads/main + +extends: + template: v2/OneBranch.Official.CrossPlat.yml@templates + parameters: + globalSdl: # https://aka.ms/obpipelines/sdl + tsa: + enabled: true # SDL results of official builds ar uploaded to TSA by default. + codeql: + tsaEnabled: true + compiled: + enabled: true + policheck: + break: false # always break the build on policheck issues. You can disable it by setting to 'false' + suppression: + suppressionFile: $(Build.SourcesDirectory)\.gdn\global.gdnsuppress + suppressionSet: default + git: + persistCredentials: true + stages: + - stage: build + jobs: + - job: main + pool: + type: windows # read more about custom job pool types at https://aka.ms/obpipelines/yaml/jobs + variables: + ob_outputDirectory: '$(Build.SourcesDirectory)\out' + ob_symbolsPublishing_enabled: true # Default is false + ob_symbolsPublishing_symbolsFolder: '$(Build.SourcesDirectory)/libraries' # Default is ob_outputDirectory + ob_symbolsPublishing_searchPattern: '**/bin/Debug/netstandard2.0/*.pdb' # Default is **/*.pdb + ob_symbolsPublishing_indexSources: true # Default is true + ob_sdl_tsa_configFile: '$(Build.SourcesDirectory)\.config\tsaoptions.json' + ob_sdl_binskim_scanOutputDirectoryOnly: true + LGTM_INDEX_FILTERS: 'exclude: **/dotnet*.js,**/underscore*.js,**/doctools.js' # excluding javascript files that come from .net blazor framework and vcpkg(for installing Brotli) as we consider these framework and dependency safe + # ob_sdl_suppression_suppressionFile: $(Build.SourcesDirectory)\.gdn\job.gdnsuppress + # ob_sdl_suppression_suppressionSet: default + steps: + - template: build/onebranch/ci.yml@self + \ No newline at end of file diff --git a/build/onebranch/pr.yml b/build/onebranch/pr.yml new file mode 100644 index 0000000000..4c01e03e65 --- /dev/null +++ b/build/onebranch/pr.yml @@ -0,0 +1,181 @@ +# +# Replaces the classic BotBuilder-DotNet-master-CI-PR +# + +# "name" here defines the build number format. Build number is accessed via $(Build.BuildNumber) +name: $(Build.BuildId) + +pool: + vmImage: $[ coalesce( variables['VMImage'], 'windows-latest' ) ] # or 'windows-latest' + demands: + - msbuild + - visualstudio + +trigger: none # ci trigger is set in ADO +pr: none # pr trigger is set in ADO + +variables: + ApiContractVersion: 4.6.3 + PackagesToValidate: Microsoft.Bot.Builder.AI.Luis,Microsoft.Bot.Builder.AI.QnA,Microsoft.Bot.Builder.ApplicationInsights,Microsoft.Bot.Builder.Azure,Microsoft.Bot.Builder.Dialogs,Microsoft.Bot.Builder.Integration.ApplicationInsights.Core,Microsoft.Bot.Builder.Integration.AspNet.Core,Microsoft.Bot.Builder.TemplateManager,Microsoft.Bot.Builder.Testing,Microsoft.Bot.Builder,Microsoft.Bot.Configuration,Microsoft.Bot.Connector,Microsoft.Bot.Schema,Microsoft.Bot.Streaming + BuildConfiguration: Debug-Windows + BuildPlatform: any cpu + IsBuildServer: true # This is consumed by tests\Microsoft.Bot.Builder.Dialogs.Declarative.Tests\SchemaTestsFixture.cs. + MSBuildArguments: -p:SignAssembly=false -p:delaySign=false + Parameters.solution: Microsoft.Bot.Builder.sln + PreviewPackageVersion: 4.9.0-preview-$(Build.BuildNumber) # This is consumed by projects in Microsoft.Bot.Builder.sln. + ReleasePackageVersion: 4.9.0-preview-$(Build.BuildNumber) # This is consumed by projects in Microsoft.Bot.Builder.sln. + runCodesignValidationInjection: false # Disables unnecessary CodeSign Validation step + system_accesstoken: $(System.AccessToken) + LGTM.UploadSnapshot: true + Semmle.SkipAnalysis: true +# ApiCompatExcludeClasses: (optional) define this in Azure + DisableApiCompatibityValidation: true +# DotNetCoverallsToken: define this in Azure +# GitHubCommentApiKey: define this in Azure +# SDK_Dotnet_V4_org_Url: define this in Azure + +# The following 2 stages run multi-configuration, multi-agent parallel jobs. +# Debug-Windows/Release-Windows => Builds everything in Debug/Release + the ASP.NET Desktop. +# Debug/Release => would build all .NET Standard libs and test them. +# The .NET 4.X asp.net integrations libraries do not build and test on non-windows boxes. +# If we drop support for .NET 4.x then we can drop to just Debug/Release. +stages: +- stage: Build + jobs: + - job: Debug_Windows_Configuration_31 + variables: + BuildConfiguration: Debug-Windows + BuildTarget: 'netcoreapp31' # set the TargetFramework property for tests to use netcoreapp3.1 + steps: + - template: ci-build-steps.yml + - template: ci-test-steps.yml + - template: ci-component-detection-steps.yml + - job: Debug_Windows_Configuration_6 + variables: + BuildConfiguration: Debug-Windows + BuildTarget: 'net6' # set the TargetFramework property for tests to use net6.0 + steps: + - template: ci-build-steps.yml + - template: ci-test-steps.yml + - template: ci-component-detection-steps.yml + - job: Release_Windows_Configuration_31 + variables: + BuildConfiguration: Release-Windows + BuildTarget: 'netcoreapp31' # set the TargetFramework property for tests to use netcoreapp3.1 + steps: + - template: ci-build-steps.yml + - template: ci-test-steps.yml + - template: ci-component-detection-steps.yml + - job: Release_Windows_Configuration_6 + variables: + BuildConfiguration: Release-Windows + BuildTarget: 'net6' # set the TargetFramework property for tests to use net6.0 + PublishCoverage: true + steps: + - template: ci-build-steps.yml + - template: ci-test-steps.yml + - template: ci-component-detection-steps.yml + +- stage: API_Compatibility_Validation + dependsOn: Build + condition: and(succeeded(), ne(variables['DisableApiCompatibityValidation'], 'true')) + variables: + skipComponentGovernanceDetection: true # the task is already injected into the build jobs, so unnecessary here. + jobs: + - job: generate_multiconfig_var + steps: + # Download contract .dlls from nuget.org. + - powershell: | + $PackageNames = "$(PackagesToValidate)"; + $ApiContractVersion = "$(ApiContractVersion)"; + $TempContractInstallDirectory = ".\TempContractInstallDir"; + $OutputDirectory = ".\ContractDlls"; + + Write-Host "`nDownloading packages version $ApiContractVersion."; + + New-Item -ItemType directory -Path $OutputDirectory -Force | Out-Null; + + $Names = $PackageNames.Split(','); + + foreach ($Name in $Names) { + "---- $Name ------------------"; + nuget install $Name -Version $ApiContractVersion -OutputDirectory $TempContractInstallDirectory -DirectDownload -NonInteractive; + + if ($LASTEXITCODE -eq 0) { + Copy-Item "$TempContractInstallDirectory\$Name.$ApiContractVersion\lib\netstandard2.0\$Name.dll" $OutputDirectory; + } + else { + Write-Host "##vso[task.complete result=Failed;]"; + } + } + displayName: 'Download Contract DLLs to ContractDlls folder' + continueOnError: true + + - task: PublishPipelineArtifact@0 + inputs: + artifactName: 'ContractDlls' + targetPath: ContractDlls + displayName: 'Push to ContractDlls in Artifacts' + continueOnError: true + + - powershell: | + $multiconfig = '{'; + if ("$(Build.Reason)" -in ('Schedule', 'Manual')) { + $env:PackagesToValidate.Split(",") | ForEach { + $library = $_.Trim() + $threadName = $library -replace "Microsoft.", ""; + $multiconfig += "'" + $threadName + "':{'PackageName':'" + $library + "'}, "; + } + } + else { + $updatedFiles = $(git diff HEAD HEAD~ --name-only) + + $updatedFiles | ForEach-Object { + $changedLibrary = '' + Switch -Wildcard ($_) { + '*/Microsoft.Bot.Builder.AI.Luis/*' { $changedLibrary = 'Microsoft.Bot.Builder.AI.Luis' } + '*/Microsoft.Bot.Builder.AI.QnA/*' { $changedLibrary = 'Microsoft.Bot.Builder.AI.QnA' } + '*/Microsoft.Bot.Builder.ApplicationInsights/*' { $changedLibrary = 'Microsoft.Bot.Builder.ApplicationInsights' } + '*/Microsoft.Bot.Builder.Azure/*' { $changedLibrary = 'Microsoft.Bot.Builder.Azure' } + '*/Microsoft.Bot.Builder.Dialogs/*' { $changedLibrary = 'Microsoft.Bot.Builder.Dialogs' } + '*/Microsoft.Bot.Builder.Integration.ApplicationInsights.Core/*' { $changedLibrary = 'Microsoft.Bot.Builder.Integration.ApplicationInsights.Core' } + '*/Microsoft.Bot.Builder.Integration.AspNet.Core/*' { $changedLibrary = 'Microsoft.Bot.Builder.Integration.AspNet.Core' } + '*/Microsoft.Bot.Builder.TemplateManager/*' { $changedLibrary = 'Microsoft.Bot.Builder.TemplateManager' } + '*/Microsoft.Bot.Builder.Testing/*' { $changedLibrary = 'Microsoft.Bot.Builder.Testing' } + '*/Microsoft.Bot.Builder/*' { $changedLibrary = 'Microsoft.Bot.Builder' } + '*/Microsoft.Bot.Configuration/*' { $changedLibrary = 'Microsoft.Bot.Configuration' } + '*/Microsoft.Bot.Connector/*' { $changedLibrary = 'Microsoft.Bot.Connector' } + '*/Microsoft.Bot.Schema/*' { $changedLibrary = 'Microsoft.Bot.Schema' } + '*/Microsoft.Bot.Streaming/*' { $changedLibrary = 'Microsoft.Bot.Streaming' } + } + if ($changedLibrary.Length -gt 0) { + Write-Host $changedLibrary + $threadName = $changedLibrary.Split(".")[-1]; + $multiconfig += "'" + $threadName + "':{'PackageName':'" + $changedLibrary + "'}, "; + } + } + } + $multiconfig = $multiconfig.TrimEnd(' ').TrimEnd(',') + "}"; + echo 'Matrix variable:' + echo $multiconfig + "##vso[task.setVariable variable=MULTICONFIG;isOutput=true]$multiconfig" + name: generate_var + displayName: Generate matrix variable + + - job: check_api_for + dependsOn: generate_multiconfig_var + condition: ne(dependencies.generate_multiconfig_var.outputs['generate_var.MULTICONFIG'], '{}') + timeoutInMinutes: 10 + strategy: + maxParallel: 10 + matrix: $[ dependencies.generate_multiconfig_var.outputs['generate_var.MULTICONFIG'] ] + steps: + - template: ci-api-validation-steps.yml + + - job: post_results_to_gitHub + dependsOn: check_api_for + condition: ne(dependencies.generate_multiconfig_var.outputs['generate_var.MULTICONFIG'], '{}') + variables: + BuildConfiguration: Release-Windows + steps: + - template: ci-post-to-github-steps.yml diff --git a/build/onebranch/sdk_dotnet_v4_org-feed-setup-steps.yml b/build/onebranch/sdk_dotnet_v4_org-feed-setup-steps.yml new file mode 100644 index 0000000000..bb620e3d62 --- /dev/null +++ b/build/onebranch/sdk_dotnet_v4_org-feed-setup-steps.yml @@ -0,0 +1,33 @@ +# Create nuget.config for resolving dependencies exclusively from SDK_Dotnet_V4_org feed. +# Resolve from nuget.org when PR is from a fork, as forks do not have access to our private feed. +steps: +- powershell: | + if ("$(System.PullRequest.IsFork)" -eq 'True') { + $key = "nuget.org"; + $value = "https://api.nuget.org/v3/index.json"; + Write-Host 'System.PullRequest.IsFork = True'; + } + else { + $key = "SDK_Dotnet_V4_org"; + $value = "$(SDK_Dotnet_V4_org_Url)"; + } + + $file = "$(Build.SourcesDirectory)\nuget.config"; + + $content = @" + + + + + + + + + + + + "@; + + New-Item -Path $file -ItemType "file" -Value $content -Force; + '-------------'; get-content "$file"; '==================='; + displayName: Create nuget.config for SDK_Dotnet_V4_org feed \ No newline at end of file diff --git a/build/onebranch/sign-steps.yml b/build/onebranch/sign-steps.yml new file mode 100644 index 0000000000..18aa75a5ec --- /dev/null +++ b/build/onebranch/sign-steps.yml @@ -0,0 +1,10 @@ +steps: +- task: onebranch.pipeline.signing@1 + displayName: "Sign output" + inputs: + command: "sign" + signing_profile: "external_distribution" + signing_environment: "azure-ado" + files_to_sign: "**/*.exe;**/*.dll;**/*.ps1;**/*.psm1" + search_root: "libraries" +