parameters: - name: Artifacts type: object default: [] - name: ServiceDirectory type: string default: not-specified - name: TestPipeline type: boolean default: false - name: CtestRegex type: string default: .* - name: CtestExcludeRegex type: string default: '' - name: CoverageReportPath type: string default: 'sdk/*/*/*cov_xml.xml' - name: CoverageEnabled type: boolean default: true # Matrix generation: # https://github.com/Azure/azure-sdk-tools/blob/main/eng/common/scripts/job-matrix/README.md - name: Matrix type: string - name: LineCoverageTarget type: number default: 95 - name: BranchCoverageTarget type: number default: 70 - name: TestEnv type: object default: [] # Supplied by archetype-sdk-tests-generate.yml dynamic matrix generator - name: CloudConfig type: object default: {} # Supplied by archetype-sdk-tests-generate.yml dynamic matrix generator. # Must be wired up to ensure population of parameters.Matrix - name: DependsOn type: string default: '' # Supplied by archetype-sdk-tests-generate.yml dynamic matrix generator - name: UsePlatformContainer type: boolean default: false - name: PreTestSteps type: stepList default: [] - name: PostTestSteps type: stepList default: [] jobs: - job: displayName: "Validate" dependsOn: ${{ parameters.DependsOn }} condition: and(succeededOrFailed(), ne(variables['Skip.Test'], 'true'), ne(${{ parameters.Matrix }}, '{}')) strategy: matrix: $[ ${{ parameters.Matrix }} ] maxParallel: 12 pool: vmImage: $(OSVmImage) name: $(Pool) variables: - name: CMOCKA_XML_FILE value: "%g-test-results.xml" - name: CMOCKA_MESSAGE_OUTPUT value: "xml" - name: BuildArgs value: "" - name: CmakeEnvArg value: "" - name: CmakeArgs value: "" - name: VcpkgArgs value: "" # Apply to all services running public pipeline - name: AZURE_TEST_MODE value: "PLAYBACK" - name: AZURE_LOG_LEVEL value: "verbose" - ${{ each testEnvVar in parameters.TestEnv }}: - name: ${{ testEnvVar.Name }} value: ${{ testEnvVar.Value }} steps: - template: /eng/common/pipelines/templates/steps/verify-agent-os.yml parameters: AgentImage: $(OsVmImage) - pwsh: sudo apt update && sudo apt install -y $(AptDependencies) condition: and(succeeded(), ne(variables['AptDependencies'], '')) displayName: Install dependencies from apt - pwsh: sudo xcode-select -s /Applications/Xcode_$(XCODE_VERSION).app/Contents/Developer condition: >- and( succeeded(), contains(variables['OSVmImage'], 'macOS'), ne(variables['XCODE_VERSION'], '') ) displayName: Set Xcode version - template: /eng/pipelines/templates/steps/vcpkg.yml # Validate all the files are formatted correctly according to the # .clang-format file. This step runs on linux only only and assumes that # clang-format-11 is installed. - bash: | # Run clang-format recursively on each source and header file within the repo sdk folder. echo "Check clang-formatting" clang-format --version find ./sdk \( -iname '*.hpp' -o -iname '*.cpp' \) ! -iname 'json.hpp' -exec clang-format -i {} \; if [[ `git status | grep modified | awk '{print $2}'` ]]; then echo Some files were not formatted correctly according to the .clang-format file. echo Please run clang-format version 10 or greater to fix the issue by using this bash command at the root of the repo: echo "find ./sdk \( -iname '*.hpp' -o -iname '*.cpp' \) ! -iname 'json.hpp' -exec clang-format -i {} \;" echo "" echo "List of files not formatted correctly:" git status | grep modified | awk '{print $2}' exit 1 fi echo Success, all files are formatted correctly according to the .clang-format file. exit 0 displayName: Validate Clang Format condition: and(succeededOrFailed(), eq(variables['CHECK_CLANG_FORMAT'], 1)) - ${{ each artifact in parameters.Artifacts }}: - template: /eng/common/pipelines/templates/steps/set-test-pipeline-version.yml parameters: PackageName: ${{ artifact.Name }} ServiceDirectory: ${{ parameters.ServiceDirectory }} TestPipeline: ${{ parameters.TestPipeline }} - template: /eng/pipelines/templates/steps/cmake-build.yml parameters: ServiceDirectory: ${{ parameters.ServiceDirectory }} GenerateArgs: "$(CmakeArgs)" BuildArgs: "$(BuildArgs)" VcpkgArgs: "$(VcpkgArgs)" Env: "$(CmakeEnvArg)" - ${{ parameters.PreTestSteps }} - pwsh: | ctest ` -C Debug ` -V ` --tests-regex '${{ parameters.CtestRegex }}' ` --exclude-regex '${{ parameters.CtestExcludeRegex }}' ` --no-compress-output ` -T Test workingDirectory: build displayName: Test - ${{ parameters.PostTestSteps }} - task: PublishTestResults@2 inputs: testResultsFormat: cTest testResultsFiles: Testing/*/Test.xml testRunTitle: $(Agent.JobName) searchFolder: build mergeTestResults: true publishRunAttachments: true displayName: Publish test results condition: succeededOrFailed() - ${{ if eq(parameters.CoverageEnabled, true) }}: - pwsh: | $toolsDirectory = "$(Agent.TempDirectory)/coveragetools" dotnet tool install -g dotnet-reportgenerator-globaltool dotnet tool install dotnet-reportgenerator-globaltool --tool-path $toolsDirectory Write-Host "##vso[task.setvariable variable=ToolsDirectory]$toolsDirectory" displayName: Install coverage tools condition: and(succeeded(), eq(variables['CODE_COVERAGE'], 'enabled')) # Make coverage targets (specified in coverage_targets.txt) and assemble # coverage report - bash: | make VERBOSE=1 `cat ${{ parameters.ServiceDirectory }}-targets-coverage.txt` $(ToolsDirectory)/reportgenerator "-reports:${{ parameters.CoverageReportPath }}" "-targetdir:." "-reporttypes:Cobertura" workingDirectory: build displayName: Generate Code Coverage Data condition: and(succeededOrFailed(), eq(variables['CODE_COVERAGE'], 'enabled')) - task: PublishCodeCoverageResults@1 inputs: codeCoverageTool: Cobertura summaryFileLocation: '$(Build.SourcesDirectory)/**/Cobertura.xml' displayName: Publish Code Coverage to DevOps condition: and(succeededOrFailed(), eq(variables['CODE_COVERAGE'], 'enabled')) - task: mspremier.BuildQualityChecks.QualityChecks-task.BuildQualityChecks@8 displayName: Check line coverage inputs: checkCoverage: true coverageFailOption: fixed coverageType: line # Minimum baseline for line coverage coverageThreshold: ${{ parameters.LineCoverageTarget }} condition: and(succeededOrFailed(), eq(variables['CODE_COVERAGE'], 'enabled'), eq(variables['Skip.LineCoverageEnforcement'], '')) - task: mspremier.BuildQualityChecks.QualityChecks-task.BuildQualityChecks@8 displayName: Check branch coverage inputs: checkCoverage: true coverageFailOption: fixed coverageType: branches # Minimum baseline for branch coverage coverageThreshold: ${{ parameters.BranchCoverageTarget }} condition: and(succeededOrFailed(), eq(variables['CODE_COVERAGE'], 'enabled'), eq(variables['Skip.BranchCoverageEnforcement'], '')) - task: Powershell@2 inputs: filePath: $(Build.SourcesDirectory)/eng/scripts/Get-BinarySizes.ps1 arguments: >- -ServiceDirectory ${{parameters.ServiceDirectory}} -OsVMImage '$(OSVmImage)' -CmakeEnvArg '$(CmakeEnvArg)' -BuildArgs '$(BuildArgs)' -VcpkgArgs '$(VcpkgArgs)' -Job '$(Agent.JobName)' -BuildReason '$(Build.Reason)' -SourceBranch '$(Build.SourceBranch)' -ExtraLabels @{ MetricVersion = 1; } pwsh: true workingDirectory: $(Pipeline.Workspace) displayName: Report Binary Sizes # Use the job name to create the artifact name for MAP file publishing. # Attempts are also noted starting with 1 # "Validate Windows2019_UWP_debug_x86" -> "Windows2019_UWP_debug_x86_attempt_1" - pwsh: | $artifactName = "$(Agent.JobName)_attempt_$(System.JobAttempt)" $parts = $artifactName -split ' ' if ($parts[1]) { $artifactName = $parts[1] } Write-Host "##vso[task.setvariable variable=MapFileArtifactName;]$artifactName" displayName: Set map file artifact name condition: eq(variables['PublishMapFiles'], 'true') - task: CopyFiles@2 inputs: contents: "**/*.map" targetFolder: $(Build.ArtifactStagingDirectory) flattenFolders: true condition: eq(variables['PublishMapFiles'], 'true') displayName: Stage map files - task: PublishPipelineArtifact@1 inputs: artifactName: map-files-$(MapFileArtifactName) path: $(Build.ArtifactStagingDirectory) condition: eq(variables['PublishMapFiles'], 'true') displayName : Publish map file artifacts - pwsh: | $artifactName = "$(Agent.JobName)" $parts = $artifactName -split ' ' if ($parts[1]) { $artifactName = $parts[1] } Write-Host "##vso[task.setvariable variable=BomArtifactName;]$artifactName" displayName: Set bom file artifact name condition: succeededOrFailed() - ${{if eq(variables['System.TeamProject'], 'internal') }}: - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 displayName: 'Generate BOM' condition: succeededOrFailed() inputs: BuildDropPath: $(Build.ArtifactStagingDirectory) - template: /eng/common/pipelines/templates/steps/publish-artifact.yml parameters: ArtifactPath: '$(Build.ArtifactStagingDirectory)/_manifest' ArtifactName: 'bom_manifest_$(BomArtifactName)'