diff --git a/LICENSE.md b/LICENSE.md index c9506aa..501ca59 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2024-2025, Matthew25187. +Copyright (c) 2024-2026, Matthew25187. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/build/build-apply-project-version.yml b/build/build-apply-project-version.yml new file mode 100644 index 0000000..4506ca1 --- /dev/null +++ b/build/build-apply-project-version.yml @@ -0,0 +1,25 @@ +parameters: # expected parameters +- name: packageName + type: string +- name: condition + type: string +- name: searchPath + type: string +- name: versionNumber + type: string +- name: fieldName + type: string + +steps: +# Version .NET Assemblies (Core/5/6 and later) +# Description - Applies a version to a .NET Assemblies (Core/5/6 and later) via the .csproj files based on the build number. Based on Microsoft sample from https://msdn.microsoft.com/Library/vs/alm/Build/overview +- task: VersionDotNetCoreAssemblies@3 + condition: ${{ parameters.condition }} + displayName: '[${{parameters.packageName}}] Set assembly ${{parameters.fieldName}}' + inputs: + # Required arguments + Path: ${{parameters.searchPath}} + VersionNumber: ${{parameters.versionNumber}} + Injectversion: True + Field: ${{parameters.fieldName}} + AddDefault: True \ No newline at end of file diff --git a/build/build-dependency-version.yml b/build/build-dependency-version.yml new file mode 100644 index 0000000..e5079ed --- /dev/null +++ b/build/build-dependency-version.yml @@ -0,0 +1,105 @@ +parameters: +- name: packageName + type: string +- name: packageNames + type: string +- name: packageInfos + type: string +- name: encodedPackageVersions + type: string +- name: enableVerboseOutput + type: boolean + default: false +- name: enableDebug + type: boolean + default: false +- name: traceLevel + type: number + default: 0 + +steps: +- ${{ each dependencyPackageName in split(parameters.packageNames, ',') }}: + - ${{ if ne(dependencyPackageName, parameters.packageName) }}: + - pwsh: | # Required as first property. Inline PowerShell script. + Import-Module "$(Build.SourcesDirectory)/build/psmodules/CommonHelpers/CommonHelpers.psm1" -Force -Scope Local + + if (${{parameters.traceLevel}} -gt 0) { + Set-PSDebug -Trace ${{parameters.traceLevel}} + } + + $packageInfo = '${{parameters.packageInfos}}' + | ConvertFrom-Json + | Where-Object -Property packageName -EQ -Value '${{dependencyPackageName}}' + if ($null -eq $packageInfo) { + Write-Error 'Package information not found for ${{dependencyPackageName}}' + } + $projectSourcePath = '$(Build.SourcesDirectory)' | Join-Path -ChildPath "$($packageInfo.packageSourcePath)" + + $packageVersions = '${{parameters.encodedPackageVersions}}' + | ConvertFrom-Base64String + | ConvertFrom-Json + | Where-Object -Property PackageName -EQ -Value '${{dependencyPackageName}}' + if ($null -eq $packageVersions) { + Write-Error 'Package versions not found for ${{dependencyPackageName}}' + } + [version]$productionAssemblyVersion = $packageVersions.AssemblyProductionVersion + + Write-Host "##vso[task.setvariable variable=projectPathArg]$projectSourcePath" + Write-Host "##vso[task.setvariable variable=assemblyVersionNumberArg]$productionAssemblyVersion" + # errorActionPreference: string # Unless otherwise specified, the error action preference defaults to the value stop. See the following section for more information. + # failOnStderr: string # Fail the task if output is sent to Stderr? + # ignoreLASTEXITCODE: string # Check the final exit code of the script to determine whether the step succeeded? + # workingDirectory: string # Start the script with this working directory. + # condition: string # Evaluate this condition expression to determine whether to run this task. + # continueOnError: boolean # Continue running even on failure? + displayName: '[${{parameters.packageName}}] Prepare arguments for Assembly Version' # Human-readable name for the task. + # Version .NET Assemblies (Core/5/6 and later) + # Description - Applies a version to a .NET Assemblies (Core/5/6 and later) via the .csproj files based on the build number. Based on Microsoft sample from https://msdn.microsoft.com/Library/vs/alm/Build/overview + - task: VersionDotNetCoreAssemblies@3 + displayName: '[${{parameters.packageName}}] Apply Assembly Version to ${{dependencyPackageName}}' # Human-readable name for the task. + inputs: + # Required arguments + Path: $(projectPathArg) + VersionNumber: $(assemblyVersionNumberArg) + Injectversion: True + FilenamePattern: .csproj + AddDefault: true + Field: AssemblyVersion + OutputVersion: AppliedVersion + # PowerShell v2 + # Run a PowerShell script on Linux, macOS, or Windows. + - task: PowerShell@2 + displayName: '[${{parameters.packageName}}] Confirm Assembly Version for ${{dependencyPackageName}}' # Human-readable name for the task. + inputs: + targetType: 'inline' # 'filePath' | 'inline'. Type. Default: filePath. + # filePath: # string. Required when targetType = filePath. Script Path. + #arguments: # string. Optional. Use when targetType = filePath. Arguments. + script: | # string. Required when targetType = inline. Script. + if (${{parameters.traceLevel}} -gt 0) { + Set-PSDebug -Trace ${{parameters.traceLevel}} + } + + # Get version numbers. + [version]$productionAssemblyVersion = '$(assemblyVersionNumberArg)' + [version]$appliedVersion = '$(AppliedVersion)' + + # Show version number applied. + if ($appliedVersion -ne $productionAssemblyVersion) { + Write-Error "Failed to apply Assembly version $productionAssemblyVersion; actual version was $appliedVersion." + } + + Write-Information "Applied version $appliedVersion to ${{dependencyPackageName}}." + # Preference Variables + #errorActionPreference: 'stop' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. ErrorActionPreference. Default: stop. + #warningPreference: 'default' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. WarningPreference. Default: default. + informationPreference: 'continue' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. InformationPreference. Default: default. + verbosePreference: ${{ iif(eq(parameters.enableVerboseOutput, 'true'), 'continue', 'default') }} # 'default' | 'stop' | 'continue' | 'silentlyContinue'. VerbosePreference. Default: default. + debugPreference: ${{ iif(eq(parameters.enableDebug, 'true'), 'continue', 'default') }} # 'default' | 'stop' | 'continue' | 'silentlyContinue'. DebugPreference. Default: default. + #progressPreference: 'silentlyContinue' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. ProgressPreference. Default: silentlyContinue. + # Advanced + #failOnStderr: false # boolean. Fail on Standard Error. Default: false. + #showWarnings: false # boolean. Show warnings as Azure DevOps warnings. Default: false. + #ignoreLASTEXITCODE: false # boolean. Ignore $LASTEXITCODE. Default: false. + #pwsh: false # boolean. Use PowerShell Core. Default: false. + #workingDirectory: # string. Working Directory. + #runScriptInSeparateScope: false # boolean. Run script in the separate scope. Default: false. \ No newline at end of file diff --git a/build/build-pipeline-vars.yml b/build/build-pipeline-vars.yml index 1e7d31e..120e39b 100644 --- a/build/build-pipeline-vars.yml +++ b/build/build-pipeline-vars.yml @@ -1,47 +1,47 @@ parameters: -- name: requirePackageDataStandardizerCore +- name: packageActionDataStandardizerCore type: string default: Build -- name: requirePackageDataStandardizerBcp47 +- name: packageActionDataStandardizerBcp47 type: string default: None -- name: requirePackageDataStandardizerChronology +- name: packageActionDataStandardizerChronology type: string default: None -- name: requirePackageDataStandardizerCommunication +- name: packageActionDataStandardizerCommunication type: string default: None -- name: requirePackageDataStandardizerFile +- name: packageActionDataStandardizerFile type: string default: None -- name: requirePackageDataStandardizerFileCSV +- name: packageActionDataStandardizerFileCSV type: string default: None -- name: requirePackageDataStandardizerGeography +- name: packageActionDataStandardizerGeography type: string default: None -- name: requirePackageDataStandardizerIso15924 +- name: packageActionDataStandardizerIso15924 type: string default: None -- name: requirePackageDataStandardizerIso3166 +- name: packageActionDataStandardizerIso3166 type: string default: None -- name: requirePackageDataStandardizerIso4217 +- name: packageActionDataStandardizerIso4217 type: string default: None -- name: requirePackageDataStandardizerIso639 +- name: packageActionDataStandardizerIso639 type: string default: None -- name: requirePackageDataStandardizerLanguage +- name: packageActionDataStandardizerLanguage type: string default: None -- name: requirePackageDataStandardizerLanguageTag +- name: packageActionDataStandardizerLanguageTag type: string default: None -- name: requirePackageDataStandardizerMoney +- name: packageActionDataStandardizerMoney type: string default: None -- name: requirePackageDataStandardizerUnM49 +- name: packageActionDataStandardizerUnM49 type: string default: None - name: packageNames @@ -140,8 +140,8 @@ variables: value: ${{ replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(variables.packageNames, 'DataStandardizer.Communication,', iif(contains(variables.packageInfos, 'DataStandardizer.Communication'), 'DataStandardizer.Communication,', '')), 'DataStandardizer.File.CSV,', iif(contains(variables.packageInfos, 'DataStandardizer.File.CSV'), 'DataStandardizer.File.CSV,', '')), 'DataStandardizer.LanguageTag,', iif(contains(variables.packageInfos, 'DataStandardizer.LanguageTag'), 'DataStandardizer.LanguageTag,', '')), 'DataStandardizer.Geography,', iif(contains(variables.packageInfos, 'DataStandardizer.Geography'), 'DataStandardizer.Geography,', '')), 'DataStandardizer.Language,', iif(contains(variables.packageInfos, 'DataStandardizer.Language'), 'DataStandardizer.Language,', '')), 'DataStandardizer.File,', iif(contains(variables.packageInfos, 'DataStandardizer.File'), 'DataStandardizer.File,', '')), 'DataStandardizer.Chronology,', iif(contains(variables.packageInfos, 'DataStandardizer.Chronology'), 'DataStandardizer.Chronology,', '')), 'DataStandardizer.Money,', iif(contains(variables.packageInfos, 'DataStandardizer.Money'), 'DataStandardizer.Money,', '')), 'DataStandardizer.UNM49,', iif(contains(variables.packageInfos, 'DataStandardizer.UNM49'), 'DataStandardizer.UNM49,', '')), 'DataStandardizer.ISO639,', iif(contains(variables.packageInfos, 'DataStandardizer.ISO639'), 'DataStandardizer.ISO639,', '')), 'DataStandardizer.ISO4217,', iif(contains(variables.packageInfos, 'DataStandardizer.ISO4217'), 'DataStandardizer.ISO4217,', '')), 'DataStandardizer.ISO3166,', iif(contains(variables.packageInfos, 'DataStandardizer.ISO3166'), 'DataStandardizer.ISO3166,', '')), 'DataStandardizer.ISO15924,', iif(contains(variables.packageInfos, 'DataStandardizer.ISO15924'), 'DataStandardizer.ISO15924,', '')), 'DataStandardizer.BCP47,', iif(contains(variables.packageInfos, 'DataStandardizer.BCP47'), 'DataStandardizer.BCP47,', '')), 'DataStandardizer.Core,', iif(contains(variables.packageInfos, 'DataStandardizer.Core'), 'DataStandardizer.Core,', '')), ',^Z', ''), '^Z', '') }} readonly: true - name: buildRequiredPackageNames - value: ${{ replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(variables.packageNames, 'DataStandardizer.Communication,', iif(eq(parameters.requirePackageDataStandardizerCommunication, 'Build'), 'DataStandardizer.Communication,', '')), 'DataStandardizer.File.CSV,', iif(eq(parameters.requirePackageDataStandardizerFileCSV, 'Build'), 'DataStandardizer.File.CSV,', '')), 'DataStandardizer.LanguageTag,', iif(eq(parameters.requirePackageDataStandardizerLanguageTag, 'Build'), 'DataStandardizer.LanguageTag,', '')), 'DataStandardizer.Geography,', iif(eq(parameters.requirePackageDataStandardizerGeography, 'Build'), 'DataStandardizer.Geography,', '')), 'DataStandardizer.Language,', iif(eq(parameters.requirePackageDataStandardizerLanguage, 'Build'), 'DataStandardizer.Language,', '')), 'DataStandardizer.File,', iif(eq(parameters.requirePackageDataStandardizerFile, 'Build'), 'DataStandardizer.File,', '')), 'DataStandardizer.Chronology,', iif(eq(parameters.requirePackageDataStandardizerChronology, 'Build'), 'DataStandardizer.Chronology,', '')), 'DataStandardizer.Money,', iif(eq(parameters.requirePackageDataStandardizerMoney, 'Build'), 'DataStandardizer.Money,', '')), 'DataStandardizer.UNM49,', iif(eq(parameters.requirePackageDataStandardizerUnM49, 'Build'), 'DataStandardizer.UNM49,', '')), 'DataStandardizer.ISO639,', iif(eq(parameters.requirePackageDataStandardizerIso639, 'Build'), 'DataStandardizer.ISO639,', '')), 'DataStandardizer.ISO4217,', iif(eq(parameters.requirePackageDataStandardizerIso4217, 'Build'), 'DataStandardizer.ISO4217,', '')), 'DataStandardizer.ISO3166,', iif(eq(parameters.requirePackageDataStandardizerIso3166, 'Build'), 'DataStandardizer.ISO3166,', '')), 'DataStandardizer.ISO15924,', iif(eq(parameters.requirePackageDataStandardizerIso15924, 'Build'), 'DataStandardizer.ISO15924,', '')), 'DataStandardizer.BCP47,', iif(eq(parameters.requirePackageDataStandardizerBcp47, 'Build'), 'DataStandardizer.BCP47,', '')), 'DataStandardizer.Core,', iif(eq(parameters.requirePackageDataStandardizerCore, 'Build'), 'DataStandardizer.Core,', '')), ',^Z', ''), '^Z', '') }} + value: ${{ replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(variables.packageNames, 'DataStandardizer.Communication,', iif(eq(parameters.packageActionDataStandardizerCommunication, 'Build'), 'DataStandardizer.Communication,', '')), 'DataStandardizer.File.CSV,', iif(eq(parameters.packageActionDataStandardizerFileCSV, 'Build'), 'DataStandardizer.File.CSV,', '')), 'DataStandardizer.LanguageTag,', iif(eq(parameters.packageActionDataStandardizerLanguageTag, 'Build'), 'DataStandardizer.LanguageTag,', '')), 'DataStandardizer.Geography,', iif(eq(parameters.packageActionDataStandardizerGeography, 'Build'), 'DataStandardizer.Geography,', '')), 'DataStandardizer.Language,', iif(eq(parameters.packageActionDataStandardizerLanguage, 'Build'), 'DataStandardizer.Language,', '')), 'DataStandardizer.File,', iif(eq(parameters.packageActionDataStandardizerFile, 'Build'), 'DataStandardizer.File,', '')), 'DataStandardizer.Chronology,', iif(eq(parameters.packageActionDataStandardizerChronology, 'Build'), 'DataStandardizer.Chronology,', '')), 'DataStandardizer.Money,', iif(eq(parameters.packageActionDataStandardizerMoney, 'Build'), 'DataStandardizer.Money,', '')), 'DataStandardizer.UNM49,', iif(eq(parameters.packageActionDataStandardizerUnM49, 'Build'), 'DataStandardizer.UNM49,', '')), 'DataStandardizer.ISO639,', iif(eq(parameters.packageActionDataStandardizerIso639, 'Build'), 'DataStandardizer.ISO639,', '')), 'DataStandardizer.ISO4217,', iif(eq(parameters.packageActionDataStandardizerIso4217, 'Build'), 'DataStandardizer.ISO4217,', '')), 'DataStandardizer.ISO3166,', iif(eq(parameters.packageActionDataStandardizerIso3166, 'Build'), 'DataStandardizer.ISO3166,', '')), 'DataStandardizer.ISO15924,', iif(eq(parameters.packageActionDataStandardizerIso15924, 'Build'), 'DataStandardizer.ISO15924,', '')), 'DataStandardizer.BCP47,', iif(eq(parameters.packageActionDataStandardizerBcp47, 'Build'), 'DataStandardizer.BCP47,', '')), 'DataStandardizer.Core,', iif(eq(parameters.packageActionDataStandardizerCore, 'Build'), 'DataStandardizer.Core,', '')), ',^Z', ''), '^Z', '') }} readonly: true - name: publicationRequiredPackageNames - value: ${{ replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(variables.packageNames, 'DataStandardizer.Communication,', iif(eq(parameters.requirePackageDataStandardizerCommunication, 'Publication'), 'DataStandardizer.Communication,', '')), 'DataStandardizer.File.CSV,', iif(eq(parameters.requirePackageDataStandardizerFileCSV, 'Publication'), 'DataStandardizer.File.CSV,', '')), 'DataStandardizer.LanguageTag,', iif(eq(parameters.requirePackageDataStandardizerLanguageTag, 'Publication'), 'DataStandardizer.LanguageTag,', '')), 'DataStandardizer.Geography,', iif(eq(parameters.requirePackageDataStandardizerGeography, 'Publication'), 'DataStandardizer.Geography,', '')), 'DataStandardizer.Language,', iif(eq(parameters.requirePackageDataStandardizerLanguage, 'Publication'), 'DataStandardizer.Language,', '')), 'DataStandardizer.File,', iif(eq(parameters.requirePackageDataStandardizerFile, 'Publication'), 'DataStandardizer.File,', '')), 'DataStandardizer.Chronology,', iif(eq(parameters.requirePackageDataStandardizerChronology, 'Publication'), 'DataStandardizer.Chronology,', '')), 'DataStandardizer.Money,', iif(eq(parameters.requirePackageDataStandardizerMoney, 'Publication'), 'DataStandardizer.Money,', '')), 'DataStandardizer.UNM49,', iif(eq(parameters.requirePackageDataStandardizerUnM49, 'Publication'), 'DataStandardizer.UNM49,', '')), 'DataStandardizer.ISO639,', iif(eq(parameters.requirePackageDataStandardizerIso639, 'Publication'), 'DataStandardizer.ISO639,', '')), 'DataStandardizer.ISO4217,', iif(eq(parameters.requirePackageDataStandardizerIso4217, 'Publication'), 'DataStandardizer.ISO4217,', '')), 'DataStandardizer.ISO3166,', iif(eq(parameters.requirePackageDataStandardizerIso3166, 'Publication'), 'DataStandardizer.ISO3166,', '')), 'DataStandardizer.ISO15924,', iif(eq(parameters.requirePackageDataStandardizerIso15924, 'Publication'), 'DataStandardizer.ISO15924,', '')), 'DataStandardizer.BCP47,', iif(eq(parameters.requirePackageDataStandardizerBcp47, 'Publication'), 'DataStandardizer.BCP47,', '')), 'DataStandardizer.Core,', iif(eq(parameters.requirePackageDataStandardizerCore, 'Publication'), 'DataStandardizer.Core,', '')), ',^Z', ''), '^Z', '') }} + value: ${{ replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(variables.packageNames, 'DataStandardizer.Communication,', iif(eq(parameters.packageActionDataStandardizerCommunication, 'Publication'), 'DataStandardizer.Communication,', '')), 'DataStandardizer.File.CSV,', iif(eq(parameters.packageActionDataStandardizerFileCSV, 'Publication'), 'DataStandardizer.File.CSV,', '')), 'DataStandardizer.LanguageTag,', iif(eq(parameters.packageActionDataStandardizerLanguageTag, 'Publication'), 'DataStandardizer.LanguageTag,', '')), 'DataStandardizer.Geography,', iif(eq(parameters.packageActionDataStandardizerGeography, 'Publication'), 'DataStandardizer.Geography,', '')), 'DataStandardizer.Language,', iif(eq(parameters.packageActionDataStandardizerLanguage, 'Publication'), 'DataStandardizer.Language,', '')), 'DataStandardizer.File,', iif(eq(parameters.packageActionDataStandardizerFile, 'Publication'), 'DataStandardizer.File,', '')), 'DataStandardizer.Chronology,', iif(eq(parameters.packageActionDataStandardizerChronology, 'Publication'), 'DataStandardizer.Chronology,', '')), 'DataStandardizer.Money,', iif(eq(parameters.packageActionDataStandardizerMoney, 'Publication'), 'DataStandardizer.Money,', '')), 'DataStandardizer.UNM49,', iif(eq(parameters.packageActionDataStandardizerUnM49, 'Publication'), 'DataStandardizer.UNM49,', '')), 'DataStandardizer.ISO639,', iif(eq(parameters.packageActionDataStandardizerIso639, 'Publication'), 'DataStandardizer.ISO639,', '')), 'DataStandardizer.ISO4217,', iif(eq(parameters.packageActionDataStandardizerIso4217, 'Publication'), 'DataStandardizer.ISO4217,', '')), 'DataStandardizer.ISO3166,', iif(eq(parameters.packageActionDataStandardizerIso3166, 'Publication'), 'DataStandardizer.ISO3166,', '')), 'DataStandardizer.ISO15924,', iif(eq(parameters.packageActionDataStandardizerIso15924, 'Publication'), 'DataStandardizer.ISO15924,', '')), 'DataStandardizer.BCP47,', iif(eq(parameters.packageActionDataStandardizerBcp47, 'Publication'), 'DataStandardizer.BCP47,', '')), 'DataStandardizer.Core,', iif(eq(parameters.packageActionDataStandardizerCore, 'Publication'), 'DataStandardizer.Core,', '')), ',^Z', ''), '^Z', '') }} readonly: true \ No newline at end of file diff --git a/build/build-steps.yml b/build/build-steps.yml new file mode 100644 index 0000000..3c5fcf0 --- /dev/null +++ b/build/build-steps.yml @@ -0,0 +1,224 @@ +parameters: # expected parameters +- name: packageName + type: string +- name: buildSolution + type: string +- name: assemblyVersionNumberCondition + type: string +- name: assemblyFileVersionNumberCondition + type: string +- name: assemblyInformationalVersionNumberCondition + type: string +- name: packageNames + type: string +- name: packageInfos + type: string +- name: encodedPackageVersions + type: string +- name: buildConfiguration + type: string +- name: buildPlatform + type: string +- name: isContinuousIntegration + type: boolean +- name: enableVerboseOutput + type: boolean +- name: enableDebug + type: boolean +- name: traceLevel + type: number + +steps: +# Use .NET Core v2 +# Acquires a specific version of the .NET Core SDK from the internet or the local cache and adds it to the PATH. Use this task to change the version of .NET Core used in subsequent tasks. Additionally provides proxy support. +- task: UseDotNet@2 + displayName: '[${{parameters.packageName}}] Install .NET SDK' + inputs: + #packageType: 'sdk' # 'runtime' | 'sdk'. Package to install. Default: sdk. + useGlobalJson: true # boolean. Optional. Use when packageType = sdk. Use global json. Default: false. + #workingDirectory: # string. Optional. Use when useGlobalJson = true. Working Directory. + #version: # string. Optional. Use when useGlobalJson = false || packageType = runtime. Version. + #includePreviewVersions: false # boolean. Optional. Use when useGlobalJson = false || packageType = runtime. Include Preview Versions. Default: false. + #requestTimeout: '300000' # string. Set timeout for package download request. Default: 300000. +- template: /build/build-dependency-version.yml # reference to template + parameters: # provided parameters + packageName: ${{parameters.packageName}} + packageNames: ${{parameters.packageNames}} + packageInfos: ${{parameters.packageInfos}} + encodedPackageVersions: ${{parameters.encodedPackageVersions}} + enableVerboseOutput: ${{parameters.enableVerboseOutput}} + enableDebug: ${{parameters.enableDebug}} + traceLevel: ${{parameters.traceLevel}} +- task: DotNetCoreCLI@2 + displayName: '[${{parameters.packageName}}] Restore solution package dependencies' + inputs: + #azureSubscription: # string. Alias: ConnectedServiceName. Azure Resource Manager connection. + command: 'restore' # 'build' | 'push' | 'pack' | 'publish' | 'restore' | 'run' | 'test' | 'custom'. Required. Command. Default: build. + #publishWebProjects: true # boolean. Optional. Use when command = publish. Publish web projects. Default: true. + projects: '${{parameters.buildSolution}}' # string. Optional. Use when command = build || command = restore || command = run || command = test || command = custom || publishWebProjects = false. Path to project(s) or solution(s). + #custom: # string. Required when command = custom. Custom command. + #arguments: # string. Optional. Use when command = build || command = publish || command = run || command = test || command = custom. Arguments. + restoreArguments: '-p:DisableWorkloadAutoImportPropsLocator=true' # string. Optional. Use when command = restore. Arguments. + #publishTestResults: true # boolean. Optional. Use when command = test. Publish test results and code coverage. Default: true. + #testRunTitle: # string. Optional. Use when command = test. Test run title. + #zipAfterPublish: true # boolean. Optional. Use when command = publish. Zip published projects. Default: true. + #modifyOutputPath: true # boolean. Optional. Use when command = publish. Add project's folder name to publish path. Default: true. + #packagesToPush: '$(Build.ArtifactStagingDirectory)/*.nupkg' # string. Alias: searchPatternPush. Required when command = push. Path to NuGet package(s) to publish. Default: $(Build.ArtifactStagingDirectory)/*.nupkg. + #nuGetFeedType: 'internal' # 'internal' | 'external'. Required when command = push. Target feed location. Default: internal. + #publishVstsFeed: # string. Alias: feedPublish. Required when command = push && nuGetFeedType = internal. Target feed. + #publishFeedCredentials: # string. Alias: externalEndpoint. Required when command = push && nuGetFeedType = external. NuGet server. + #packagesToPack: '**/*.csproj' # string. Alias: searchPatternPack. Required when command = pack. Path to csproj or nuspec file(s) to pack. Default: **/*.csproj. + #configuration: '$(BuildConfiguration)' # string. Alias: configurationToPack. Optional. Use when command = pack. Configuration to Package. Default: $(BuildConfiguration). + #packDirectory: '$(Build.ArtifactStagingDirectory)' # string. Alias: outputDir. Optional. Use when command = pack. Package Folder. Default: $(Build.ArtifactStagingDirectory). + #nobuild: false # boolean. Optional. Use when command = pack. Do not build. Default: false. + #includesymbols: false # boolean. Optional. Use when command = pack. Include Symbols. Default: false. + #includesource: false # boolean. Optional. Use when command = pack. Include Source. Default: false. + #requestTimeout: '300000' # string. Set timeout for package download request. Default: 300000. + # Feeds and authentication + feedsToUse: 'config' # 'select' | 'config'. Alias: selectOrConfig. Required when command = restore. Feeds to use. Default: select. + #vstsFeed: # string. Alias: feedRestore. Optional. Use when selectOrConfig = select && command = restore. Use packages from this Azure Artifacts feed. Select from the dropdown or enter [project name/]feed name. + #includeNuGetOrg: true # boolean. Optional. Use when selectOrConfig = select && command = restore. Use packages from NuGet.org. Default: true. + nugetConfigPath: '$(Build.SourcesDirectory)/nuget.config' # string. Optional. Use when selectOrConfig = config && command = restore. Path to NuGet.config. + #externalFeedCredentials: # string. Alias: externalEndpoints. Optional. Use when selectOrConfig = config && command = restore. Credentials for feeds outside this organization/collection. + # Advanced + noCache: false # boolean. Optional. Use when command = restore. Disable local cache. Default: false. + #restoreDirectory: # string. Alias: packagesDirectory. Optional. Use when command = restore. Destination directory. + verbosityRestore: 'Detailed' # '-' | 'Quiet' | 'Minimal' | 'Normal' | 'Detailed' | 'Diagnostic'. Optional. Use when command = restore. Verbosity. Default: Normal. +- task: PowerShell@2 + displayName: '[${{parameters.packageName}}] Set build arguments' + inputs: + #targetType: 'filePath' # 'filePath' | 'inline'. Type. Default: filePath. + filePath: 'build/scripts/SetBuildTemplateArguments.ps1' # string. Required when targetType = filePath. Script Path. + arguments: '-PackageName ${{parameters.packageName}} -EncodedPackageVersions ''${{parameters.encodedPackageVersions}}'' -TraceLevel ${{parameters.traceLevel}}' # string. Optional. Use when targetType = filePath. Arguments. + #script: # string. Required when targetType = inline. Script. + # Preference Variables + #errorActionPreference: 'stop' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. ErrorActionPreference. Default: stop. + #warningPreference: 'default' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. WarningPreference. Default: default. + informationPreference: 'continue' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. InformationPreference. Default: default. + verbosePreference: ${{ iif(eq(parameters.enableVerboseOutput, 'true'), 'continue', 'default') }} # 'default' | 'stop' | 'continue' | 'silentlyContinue'. VerbosePreference. Default: default. + debugPreference: ${{ iif(eq(parameters.enableDebug, 'true'), 'continue', 'default') }} # 'default' | 'stop' | 'continue' | 'silentlyContinue'. DebugPreference. Default: default. + #progressPreference: 'silentlyContinue' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. ProgressPreference. Default: silentlyContinue. + # Advanced + #failOnStderr: false # boolean. Fail on Standard Error. Default: false. + #showWarnings: false # boolean. Show warnings as Azure DevOps warnings. Default: false. + #ignoreLASTEXITCODE: false # boolean. Ignore $LASTEXITCODE. Default: false. + pwsh: true # boolean. Use PowerShell Core. Default: false. + #workingDirectory: # string. Working Directory. + #runScriptInSeparateScope: false # boolean. Run script in the separate scope. Default: false. +- template: /build/build-apply-project-version.yml # reference to template + parameters: # provided parameters + packageName: ${{parameters.packageName}} + condition: ${{parameters.assemblyFileVersionNumberCondition}} + searchPath: $(Build.SourcesDirectory)/$(sourceFolderPath) + versionNumber: $(buildFileVersion) + fieldName: 'FileVersion' +- template: /build/build-apply-project-version.yml # reference to template + parameters: # provided parameters + packageName: ${{parameters.packageName}} + condition: ${{parameters.assemblyInformationalVersionNumberCondition}} + searchPath: $(Build.SourcesDirectory)/$(sourceFolderPath) + versionNumber: $(buildInformationalVersion) + fieldName: 'InformationalVersion' +- template: /build/build-apply-project-version.yml # reference to template + parameters: # provided parameters + packageName: ${{parameters.packageName}} + condition: ${{parameters.assemblyVersionNumberCondition}} + searchPath: $(Build.SourcesDirectory)/$(sourceFolderPath) + versionNumber: $(buildAssemblyVersion) + fieldName: 'AssemblyVersion' +# - task: VSBuild@1 +# displayName: 'Build package solution' +# inputs: +# solution: '$(buildSolution)' # string. Required. Solution. Default: **\*.sln. +# #vsVersion: 'latest' # 'latest' | '17.0' | '16.0' | '15.0' | '14.0' | '12.0' | '11.0'. Visual Studio Version. Default: latest. +# msbuildArgs: '/p:ProduceReferenceAssembly=true;ProduceReferenceAssemblyInOutDir=true;ContinuousIntegrationBuild=$(isContinuousIntegrationBuild)' # string. MSBuild Arguments. +# platform: $(BuildPlatform) # string. Platform. +# configuration: $(BuildConfiguration) # string. Configuration. +# #clean: false # boolean. Clean. Default: false. +# # Advanced +# #maximumCpuCount: false # boolean. Build in Parallel. Default: false. +# #restoreNugetPackages: false # boolean. Restore NuGet Packages. Default: false. +# #msbuildArchitecture: 'x86' # 'x86' | 'x64'. MSBuild Architecture. Default: x86. +# #logProjectEvents: true # boolean. Record Project Details. Default: true. +# #createLogFile: false # boolean. Create Log File. Default: false. +# #logFileVerbosity: 'normal' # 'quiet' | 'minimal' | 'normal' | 'detailed' | 'diagnostic'. Optional. Use when createLogFile = true. Log File Verbosity. Default: normal. +# #enableDefaultLogger: true # boolean. Enable Default Logger. Default: true. +# #customVersion: # string. Custom Version. +# .NET Core v2 +# Build, test, package, or publish a .NET application, or run a custom .NET CLI command. +- task: DotNetCoreCLI@2 + displayName: '[${{parameters.packageName}}] Build package solution' + inputs: + #azureSubscription: # string. Alias: ConnectedServiceName. Azure Resource Manager connection. + command: 'build' # 'build' | 'push' | 'pack' | 'publish' | 'restore' | 'run' | 'test' | 'custom'. Required. Command. Default: build. + #publishWebProjects: true # boolean. Optional. Use when command = publish. Publish web projects. Default: true. + projects: '${{parameters.buildSolution}}' # string. Optional. Use when command = build || command = restore || command = run || command = test || command = custom || publishWebProjects = false. Path to project(s) or solution(s). + #custom: # string. Required when command = custom. Custom command. + arguments: '-c ${{parameters.buildConfiguration}} -p:Platform="${{parameters.buildPlatform}}";ProduceReferenceAssembly=true;ProduceReferenceAssemblyInOutDir=true;ContinuousIntegrationBuild=${{parameters.isContinuousIntegration}};DisableWorkloadAutoImportPropsLocator=true;UseSharedCompilation=false' # string. Optional. Use when command = build || command = publish || command = run || command = test || command = custom. Arguments. + #restoreArguments: # string. Optional. Use when command = restore. Arguments. + #publishTestResults: true # boolean. Optional. Use when command = test. Publish test results and code coverage. Default: true. + #testRunTitle: # string. Optional. Use when command = test. Test run title. + #zipAfterPublish: true # boolean. Optional. Use when command = publish. Zip published projects. Default: true. + #modifyOutputPath: true # boolean. Optional. Use when command = publish. Add project's folder name to publish path. Default: true. + #packagesToPush: '$(Build.ArtifactStagingDirectory)/*.nupkg' # string. Alias: searchPatternPush. Required when command = push. Path to NuGet package(s) to publish. Default: $(Build.ArtifactStagingDirectory)/*.nupkg. + #nuGetFeedType: 'internal' # 'internal' | 'external'. Required when command = push. Target feed location. Default: internal. + #publishVstsFeed: # string. Alias: feedPublish. Required when command = push && nuGetFeedType = internal. Target feed. + #publishFeedCredentials: # string. Alias: externalEndpoint. Required when command = push && nuGetFeedType = external. NuGet server. + #packagesToPack: '**/*.csproj' # string. Alias: searchPatternPack. Required when command = pack. Path to csproj or nuspec file(s) to pack. Default: **/*.csproj. + #configuration: '$(BuildConfiguration)' # string. Alias: configurationToPack. Optional. Use when command = pack. Configuration to Package. Default: $(BuildConfiguration). + #packDirectory: '$(Build.ArtifactStagingDirectory)' # string. Alias: outputDir. Optional. Use when command = pack. Package Folder. Default: $(Build.ArtifactStagingDirectory). + #nobuild: false # boolean. Optional. Use when command = pack. Do not build. Default: false. + #includesymbols: false # boolean. Optional. Use when command = pack. Include Symbols. Default: false. + #includesource: false # boolean. Optional. Use when command = pack. Include Source. Default: false. + #requestTimeout: '300000' # string. Set timeout for package download request. Default: 300000. + # Advanced + #workingDirectory: # string. Optional. Use when command != restore && command != push && command != pack. Working directory. +- task: PublishSymbols@2 + displayName: '[${{parameters.packageName}}] Publish symbols' + inputs: + #SymbolsFolder: '$(Build.SourcesDirectory)' # string. Path to symbols folder. Default: $(Build.SourcesDirectory). + SearchPattern: 'src/**/bin/**/${{parameters.buildConfiguration}}/**/*.pdb' # string. Required. Search pattern. Default: **/bin/**/*.pdb. + #Manifest: # string. Manifest. + IndexSources: false # boolean. Index sources. Default: true. # Disable indexing since GitHub is unsupported + PublishSymbols: true # boolean. Publish symbols. Default: true. + SymbolServerType: 'TeamServices' # Or 'FileShare'. Required when PublishSymbols = true. Symbol server type. + #SymbolsPath: # string. Optional. Use when PublishSymbols = true && SymbolServerType = FileShare. Path to publish symbols. + #CompressSymbols: false # boolean. Optional. Use when SymbolServerType = FileShare. Compress symbols. Default: false. + #SymbolExpirationInDays: '36530' # string. Optional. Use when PublishSymbols = true && SymbolServerType = TeamServices. Symbol Expiration (in days). Default: 36530. + # Advanced + #IndexableFileFormats: 'Default' # 'Default' | 'Pdb' | 'SourceMap' | 'All'. Optional. Use when PublishSymbols = true && SymbolServerType = TeamServices. Symbol file formats to publish. Default: Default. + #DetailedLog: true # boolean. Verbose logging. Default: true. + #TreatNotIndexedAsWarning: false # boolean. Warn if not indexed. Default: false. + #UseNetCoreClientTool: false # boolean. Use NetCore client tool. Default: false. + #SymbolsMaximumWaitTime: # string. Max wait time (min). + #SymbolsProduct: # string. Product. + #SymbolsVersion: # string. Version. + #SymbolsArtifactName: 'Symbols_$(BuildConfiguration)' # string. Artifact name. Default: Symbols_$(BuildConfiguration). +- task: CopyFiles@2 + displayName: '[${{parameters.packageName}}] Copy build output to staging area' + inputs: + #SourceFolder: # string. Source Folder. + Contents: | # string. Required. Contents. Default: **. + src\${{parameters.packageName}}\**\bin\**\${{parameters.buildConfiguration}}\** + tests\${{parameters.packageName}}*\**\bin\**\${{parameters.buildConfiguration}}\** + TargetFolder: '$(Build.ArtifactStagingDirectory)' # string. Required. Target Folder. + # Advanced + #CleanTargetFolder: false # boolean. Clean Target Folder. Default: false. + #OverWrite: false # boolean. Overwrite. Default: false. + #flattenFolders: false # boolean. Flatten Folders. Default: false. + #preserveTimestamp: false # boolean. Preserve Target Timestamp. Default: false. + #retryCount: '0' # string. Retry count to copy the file. Default: 0. + #delayBetweenRetries: '1000' # string. Delay between two retries. Default: 1000. + #ignoreMakeDirErrors: false # boolean. Ignore errors during creation of target folder. Default: false. +- task: PublishBuildArtifacts@1 + displayName: '[${{parameters.packageName}}] Publish build artifacts to pipeline' + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)' # string. Required. Path to publish. Default: $(Build.ArtifactStagingDirectory). + ArtifactName: 'drop' # string. Required. Artifact name. Default: drop. + publishLocation: 'Container' # 'Container' | 'FilePath'. Alias: ArtifactType. Required. Artifact publish location. Default: Container. + #MaxArtifactSize: '0' # string. Max Artifact Size. Default: 0. + #TargetPath: # string. Required when ArtifactType = FilePath. File share path. + #Parallel: false # boolean. Optional. Use when ArtifactType = FilePath. Parallel copy. Default: false. + #ParallelCount: '8' # string. Optional. Use when ArtifactType = FilePath && Parallel = true. Parallel count. Default: 8. + # Advanced + #StoreAsTar: false # boolean. Tar the artifact before uploading. Default: false. \ No newline at end of file diff --git a/build/datastandardizer-ci-build-pipeline.yml b/build/datastandardizer-ci-build-pipeline.yml index 45b7665..a6d7c75 100644 --- a/build/datastandardizer-ci-build-pipeline.yml +++ b/build/datastandardizer-ci-build-pipeline.yml @@ -18,7 +18,7 @@ parameters: displayName: "Build x64 targets" type: boolean default: true - - name: requirePackageDataStandardizerCore + - name: forcePackageDataStandardizerCore displayName: 'Force DataStandardizer.Core package' type: string default: Build @@ -26,7 +26,7 @@ parameters: - None - Build - Publication - - name: requirePackageDataStandardizerBcp47 + - name: forcePackageDataStandardizerBcp47 displayName: 'Force DataStandardizer.BCP47 package' type: string default: None @@ -34,7 +34,7 @@ parameters: - None - Build - Publication - - name: requirePackageDataStandardizerChronology + - name: forcePackageDataStandardizerChronology displayName: 'Force DataStandardizer.Chronology package' type: string default: None @@ -42,7 +42,7 @@ parameters: - None - Build - Publication - - name: requirePackageDataStandardizerCommunication + - name: forcePackageDataStandardizerCommunication displayName: 'Force DataStandardizer.Communication package' type: string default: None @@ -50,7 +50,7 @@ parameters: - None - Build - Publication - - name: requirePackageDataStandardizerFile + - name: forcePackageDataStandardizerFile displayName: 'Force DataStandardizer.File package' type: string default: None @@ -58,7 +58,7 @@ parameters: - None - Build - Publication - - name: requirePackageDataStandardizerFileCSV + - name: forcePackageDataStandardizerFileCSV displayName: 'Force DataStandardizer.File.CSV package' type: string default: None @@ -66,7 +66,7 @@ parameters: - None - Build - Publication - - name: requirePackageDataStandardizerGeography + - name: forcePackageDataStandardizerGeography displayName: 'Force DataStandardizer.Geography package' type: string default: None @@ -74,7 +74,7 @@ parameters: - None - Build - Publication - - name: requirePackageDataStandardizerIso15924 + - name: forcePackageDataStandardizerIso15924 displayName: 'Force DataStandardizer.ISO15924 package' type: string default: None @@ -82,7 +82,7 @@ parameters: - None - Build - Publication - - name: requirePackageDataStandardizerIso3166 + - name: forcePackageDataStandardizerIso3166 displayName: 'Force DataStandardizer.ISO3166 package' type: string default: None @@ -90,7 +90,7 @@ parameters: - None - Build - Publication - - name: requirePackageDataStandardizerIso4217 + - name: forcePackageDataStandardizerIso4217 displayName: 'Force DataStandardizer.ISO4217 package' type: string default: None @@ -98,7 +98,7 @@ parameters: - None - Build - Publication - - name: requirePackageDataStandardizerIso639 + - name: forcePackageDataStandardizerIso639 displayName: 'Force DataStandardizer.ISO639 package' type: string default: None @@ -106,7 +106,7 @@ parameters: - None - Build - Publication - - name: requirePackageDataStandardizerLanguage + - name: forcePackageDataStandardizerLanguage displayName: 'Force DataStandardizer.Language package' type: string default: None @@ -114,7 +114,7 @@ parameters: - None - Build - Publication - - name: requirePackageDataStandardizerLanguageTag + - name: forcePackageDataStandardizerLanguageTag displayName: 'Force DataStandardizer.LanguageTag package' type: string default: None @@ -122,7 +122,7 @@ parameters: - None - Build - Publication - - name: requirePackageDataStandardizerMoney + - name: forcePackageDataStandardizerMoney displayName: 'Force DataStandardizer.Money package' type: string default: None @@ -130,7 +130,7 @@ parameters: - None - Build - Publication - - name: requirePackageDataStandardizerUnM49 + - name: forcePackageDataStandardizerUnM49 displayName: 'Force DataStandardizer.UNM49 package' type: string default: None @@ -138,6 +138,10 @@ parameters: - None - Build - Publication + - name: overrideChangedPackageNames + displayName: 'Override changed package names' + type: string + default: ' ' - name: forceTagging displayName: 'Force tagging' type: boolean @@ -184,21 +188,21 @@ variables: value: $[eq(variables['Build.SourceBranch'], 'refs/heads/develop')] - template: /build/build-pipeline-vars.yml parameters: - requirePackageDataStandardizerCore: ${{ parameters.requirePackageDataStandardizerCore }} - requirePackageDataStandardizerBcp47: ${{ parameters.requirePackageDataStandardizerBcp47 }} - requirePackageDataStandardizerChronology: ${{ parameters.requirePackageDataStandardizerChronology }} - requirePackageDataStandardizerCommunication: ${{ parameters.requirePackageDataStandardizerCommunication }} - requirePackageDataStandardizerFile: ${{ parameters.requirePackageDataStandardizerFile }} - requirePackageDataStandardizerFileCSV: ${{ parameters.requirePackageDataStandardizerFileCSV }} - requirePackageDataStandardizerGeography: ${{ parameters.requirePackageDataStandardizerGeography }} - requirePackageDataStandardizerIso15924: ${{ parameters.requirePackageDataStandardizerIso15924 }} - requirePackageDataStandardizerIso3166: ${{ parameters.requirePackageDataStandardizerIso3166 }} - requirePackageDataStandardizerIso4217: ${{ parameters.requirePackageDataStandardizerIso4217 }} - requirePackageDataStandardizerIso639: ${{ parameters.requirePackageDataStandardizerIso639 }} - requirePackageDataStandardizerLanguage: ${{ parameters.requirePackageDataStandardizerLanguage }} - requirePackageDataStandardizerLanguageTag: ${{ parameters.requirePackageDataStandardizerLanguageTag }} - requirePackageDataStandardizerMoney: ${{ parameters.requirePackageDataStandardizerMoney }} - requirePackageDataStandardizerUnM49: ${{ parameters.requirePackageDataStandardizerUnM49 }} + packageActionDataStandardizerCore: ${{ parameters.forcePackageDataStandardizerCore }} + packageActionDataStandardizerBcp47: ${{ parameters.forcePackageDataStandardizerBcp47 }} + packageActionDataStandardizerChronology: ${{ parameters.forcePackageDataStandardizerChronology }} + packageActionDataStandardizerCommunication: ${{ parameters.forcePackageDataStandardizerCommunication }} + packageActionDataStandardizerFile: ${{ parameters.forcePackageDataStandardizerFile }} + packageActionDataStandardizerFileCSV: ${{ parameters.forcePackageDataStandardizerFileCSV }} + packageActionDataStandardizerGeography: ${{ parameters.forcePackageDataStandardizerGeography }} + packageActionDataStandardizerIso15924: ${{ parameters.forcePackageDataStandardizerIso15924 }} + packageActionDataStandardizerIso3166: ${{ parameters.forcePackageDataStandardizerIso3166 }} + packageActionDataStandardizerIso4217: ${{ parameters.forcePackageDataStandardizerIso4217 }} + packageActionDataStandardizerIso639: ${{ parameters.forcePackageDataStandardizerIso639 }} + packageActionDataStandardizerLanguage: ${{ parameters.forcePackageDataStandardizerLanguage }} + packageActionDataStandardizerLanguageTag: ${{ parameters.forcePackageDataStandardizerLanguageTag }} + packageActionDataStandardizerMoney: ${{ parameters.forcePackageDataStandardizerMoney }} + packageActionDataStandardizerUnM49: ${{ parameters.forcePackageDataStandardizerUnM49 }} stages: - stage: Configure @@ -211,12 +215,11 @@ stages: persistCredentials: true fetchDepth: 0 - task: PowerShell@2 - name: ChangedPackages displayName: 'Find changed packages' inputs: #targetType: 'filePath' # 'filePath' | 'inline'. Type. Default: filePath. filePath: 'build/scripts/FindChangedPackages.ps1' # string. Required when targetType = filePath. Script Path. - arguments: '-PackageList ''${{variables.packageInfos}}'' -SourceCommitHash $(Build.SourceVersion) -TraceLevel ${{parameters.traceLevel}}' # string. Optional. Use when targetType = filePath. Arguments. + arguments: '-TraceLevel ${{parameters.traceLevel}}' # string. Optional. Use when targetType = filePath. Arguments. #script: # string. Required when targetType = inline. Script. # Preference Variables #errorActionPreference: 'stop' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. ErrorActionPreference. Default: stop. @@ -232,13 +235,50 @@ stages: pwsh: true # boolean. Use PowerShell Core. Default: false. #workingDirectory: # string. Working Directory. #runScriptInSeparateScope: false # boolean. Run script in the separate scope. Default: false. + - powershell: | # Required as first property. Inline PowerShell script. + Write-Host "##vso[task.setvariable variable=changedPackageNamesList]${{trim(parameters.overrideChangedPackageNames)}}" + # errorActionPreference: string # Unless otherwise specified, the error action preference defaults to the value stop. See the following section for more information. + # failOnStderr: string # Fail the task if output is sent to Stderr? + # ignoreLASTEXITCODE: string # Check the final exit code of the script to determine whether the step succeeded? + # workingDirectory: string # Start the script with this working directory. + condition: | # Evaluate this condition expression to determine whether to run this task. + and + ( + succeeded(), + gt(length('${{trim(parameters.overrideChangedPackageNames)}}'), 0) + ) + # continueOnError: boolean # Continue running even on failure? + displayName: 'Override changed packages' # Human-readable name for the task. + # target: string | target # Environment in which to run this task. + # enabled: boolean # Run this task when the job runs? + # env: # Variables to map into the process's environment. + # string: string # Name/value pairs + # name: string # ID of the step. + # timeoutInMinutes: string # Time to wait for this task to complete before the server kills it. + # retryCountOnTaskFailure: string # Number of retries if the task fails. + - powershell: | # Required as first property. Inline PowerShell script. + Write-Host "##vso[task.setvariable variable=changedPackageNames;isOutput=true]$(changedPackageNamesList)" + # errorActionPreference: string # Unless otherwise specified, the error action preference defaults to the value stop. See the following section for more information. + # failOnStderr: string # Fail the task if output is sent to Stderr? + # ignoreLASTEXITCODE: string # Check the final exit code of the script to determine whether the step succeeded? + # workingDirectory: string # Start the script with this working directory. + # condition: string # Evaluate this condition expression to determine whether to run this task. + # continueOnError: boolean # Continue running even on failure? + displayName: 'Output changed packages' # Human-readable name for the task. + # target: string | target # Environment in which to run this task. + # enabled: boolean # Run this task when the job runs? + # env: # Variables to map into the process's environment. + # string: string # Name/value pairs + name: ChangedPackages # ID of the step. + # timeoutInMinutes: string # Time to wait for this task to complete before the server kills it. + # retryCountOnTaskFailure: string # Number of retries if the task fails. - task: PowerShell@2 name: TestPackages displayName: 'Find test packages' inputs: #targetType: 'filePath' # 'filePath' | 'inline'. Type. Default: filePath. filePath: 'build/scripts/FindTestPackages.ps1' # string. Required when targetType = filePath. Script Path. - arguments: '-PackageInfos ''${{variables.packageInfos}}'' -TraceLevel ${{parameters.traceLevel}}' # string. Optional. Use when targetType = filePath. Arguments. + arguments: '-TraceLevel ${{parameters.traceLevel}}' # string. Optional. Use when targetType = filePath. Arguments. #script: # string. Required when targetType = inline. Script. # Preference Variables #errorActionPreference: 'stop' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. ErrorActionPreference. Default: stop. @@ -256,7 +296,10 @@ stages: #runScriptInSeparateScope: false # boolean. Run script in the separate scope. Default: false. - job: Version_numbering displayName: 'Calculate version numbers' # Human-readable name for the job. + dependsOn: # Any jobs which must complete before this one. + - Production_packages variables: + changedPackageNames: $[ dependencies.Production_packages.outputs['ChangedPackages.changedPackageNames'] ] versionNumberList: '' pool: vmImage: windows-latest @@ -285,7 +328,7 @@ stages: scriptLocation: 'scriptPath' # 'inlineScript' | 'scriptPath'. Required. Script Location. Default: scriptPath. scriptPath: 'build/scripts/DeclareRequiredVersionNumbers.ps1' # string. Required when scriptLocation = scriptPath. Script Path. # inlineScript: # string. Required when scriptLocation = inlineScript. Inline Script. - arguments: '-PackageName ''${{ packageName }}'' -PackageInfos ''${{variables.packageInfos}}'' -TempPath ''$(Agent.TempDirectory)'' -OutputInformationPreference ''Continue'' -OutputVerbosePreference ${{iif(eq(parameters.enableVerboseOutput, ''true''), ''Continue'', ''SilentlyContinue'')}} -OutputDebugPreference ${{iif(eq(parameters.enableDebug, ''true''), ''Continue'', ''SilentlyContinue'')}} -TraceLevel ${{parameters.traceLevel}}' # string. Alias: scriptArguments. Script Arguments. + arguments: '-PackageName ''${{ packageName }}'' -OutputInformationPreference ''Continue'' -OutputVerbosePreference ${{iif(eq(parameters.enableVerboseOutput, ''true''), ''Continue'', ''SilentlyContinue'')}} -OutputDebugPreference ${{iif(eq(parameters.enableDebug, ''true''), ''Continue'', ''SilentlyContinue'')}} -TraceLevel ${{parameters.traceLevel}}' # string. Alias: scriptArguments. Script Arguments. #powerShellErrorActionPreference: 'stop' # 'stop' | 'continue' | 'silentlyContinue'. Optional. Use when scriptType = ps || scriptType = pscore. ErrorActionPreference. Default: stop. env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) @@ -297,13 +340,13 @@ stages: ( succeeded(), or(eq(variables['isDevelopBranch'], 'true'), and(gt(length(coalesce(variables.publicationRequiredPackageNames, '')), 0), gt(length(split(variables.publicationRequiredPackageNames, ',')), 0))), - or(and(gt(length(coalesce(variables.publicationRequiredPackageNames, '')), 0), containsValue(split(variables.publicationRequiredPackageNames, ','), '${{ packageName }}')), and(gt(length(coalesce(variables['ChangedPackages.changedPackageNames'], '')), 0), containsValue(split(variables['ChangedPackages.changedPackageNames'], ','), '${{ packageName }}'))) + or(and(gt(length(coalesce(variables.publicationRequiredPackageNames, '')), 0), containsValue(split(variables.publicationRequiredPackageNames, ','), '${{ packageName }}')), and(gt(length(coalesce(variables['changedPackageNames'], '')), 0), containsValue(split(variables['changedPackageNames'], ','), '${{ packageName }}'))) ) displayName: '[${{ packageName }}] Calculate optional versions' # Human-readable name for the task. inputs: #targetType: 'filePath' # 'filePath' | 'inline'. Type. Default: filePath. filePath: 'build/scripts/DeclareOptionalVersionNumbers.ps1' # string. Required when targetType = filePath. Script Path. - arguments: '-PackageName ''${{ packageName }}'' -SourceBranch ''$(Build.SourceBranch)'' -TraceLevel ${{parameters.traceLevel}}' # string. Optional. Use when targetType = filePath. Arguments. + arguments: '-PackageName ''${{ packageName }}'' -TraceLevel ${{parameters.traceLevel}}' # string. Optional. Use when targetType = filePath. Arguments. #script: # string. Required when targetType = inline. Script. # Preference Variables #errorActionPreference: 'stop' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. ErrorActionPreference. Default: stop. @@ -378,9 +421,9 @@ stages: azureSubscription: $(SUBSCRIPTION_ID) # string. Alias: connectedServiceNameARM. Required. Azure Resource Manager connection. scriptType: 'pscore' # 'ps' | 'pscore' | 'batch' | 'bash'. Required. Script Type. scriptLocation: 'scriptPath' # 'inlineScript' | 'scriptPath'. Required. Script Location. Default: scriptPath. - scriptPath: 'build/scripts/ReserveProductionVersionNumbers.ps1' # string. Required when scriptLocation = scriptPath. Script Path. + scriptPath: 'build/scripts/UpdatePipelineVersionNumber.ps1' # string. Required when scriptLocation = scriptPath. Script Path. #inlineScript: # string. Required when scriptLocation = inlineScript. Inline Script. - arguments: '-PackageName ''${{ packageName }}'' -PackageInfos ''${{variables.packageInfos}}'' -EncodedPackageVersions ''$(versionNumbers)'' -TraceLevel ${{parameters.traceLevel}}' # string. Alias: scriptArguments. Script Arguments. + arguments: '-PackageName ''${{ packageName }}'' -VersionNumberName PackagePostProductionVersion -VariableNamePrefix next -OutputInformationPreference ''Continue'' -OutputVerbosePreference ${{iif(eq(parameters.enableVerboseOutput, ''true''), ''Continue'', ''SilentlyContinue'')}} -OutputDebugPreference ${{iif(eq(parameters.enableDebug, ''true''), ''Continue'', ''SilentlyContinue'')}} -TraceLevel ${{parameters.traceLevel}}' # string. Alias: scriptArguments. Script Arguments. #powerShellErrorActionPreference: 'stop' # 'stop' | 'continue' | 'silentlyContinue'. Optional. Use when scriptType = ps || scriptType = pscore. ErrorActionPreference. Default: stop. env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) @@ -431,305 +474,22 @@ stages: buildSolution: '${{packageName}}.slnf' isContinuousIntegrationBuild: true steps: - # Use .NET Core v2 - # Acquires a specific version of the .NET Core SDK from the internet or the local cache and adds it to the PATH. Use this task to change the version of .NET Core used in subsequent tasks. Additionally provides proxy support. - - task: UseDotNet@2 - displayName: '[${{packageName}}] Install .NET SDK' - inputs: - #packageType: 'sdk' # 'runtime' | 'sdk'. Package to install. Default: sdk. - useGlobalJson: true # boolean. Optional. Use when packageType = sdk. Use global json. Default: false. - #workingDirectory: # string. Optional. Use when useGlobalJson = true. Working Directory. - #version: # string. Optional. Use when useGlobalJson = false || packageType = runtime. Version. - #includePreviewVersions: false # boolean. Optional. Use when useGlobalJson = false || packageType = runtime. Include Preview Versions. Default: false. - #requestTimeout: '300000' # string. Set timeout for package download request. Default: 300000. - - ${{ each dependencyPackageName in split(variables.allPackageNames, ',') }}: - - ${{ if ne(dependencyPackageName, packageName) }}: - - pwsh: | # Required as first property. Inline PowerShell script. - Import-Module "$(Build.SourcesDirectory)/build/psmodules/CommonHelpers/CommonHelpers.psm1" -Force - - if (${{parameters.traceLevel}} -gt 0) { - Set-PSDebug -Trace ${{parameters.traceLevel}} - } - - $packageInfo = '${{variables.packageInfos}}' - | ConvertFrom-Json - | Where-Object -Property packageName -EQ -Value '${{dependencyPackageName}}' - if ($null -eq $packageInfo) { - Write-Error 'Package information not found for ${{dependencyPackageName}}' - } - $projectSourcePath = '$(Build.SourcesDirectory)' | Join-Path -ChildPath "$($packageInfo.packageSourcePath)" - - $packageVersions = '$(versionNumbers)' - | ConvertFrom-Base64String - | ConvertFrom-Json - | Where-Object -Property PackageName -EQ -Value '${{dependencyPackageName}}' - if ($null -eq $packageVersions) { - Write-Error 'Package versions not found for ${{dependencyPackageName}}' - } - [version]$productionAssemblyVersion = $packageVersions.AssemblyProductionVersion - - Write-Host "##vso[task.setvariable variable=versioningPath]$projectSourcePath" - Write-Host "##vso[task.setvariable variable=versioningNumber]$productionAssemblyVersion" - # errorActionPreference: string # Unless otherwise specified, the error action preference defaults to the value stop. See the following section for more information. - # failOnStderr: string # Fail the task if output is sent to Stderr? - # ignoreLASTEXITCODE: string # Check the final exit code of the script to determine whether the step succeeded? - # workingDirectory: string # Start the script with this working directory. - # condition: string # Evaluate this condition expression to determine whether to run this task. - # continueOnError: boolean # Continue running even on failure? - displayName: '[${{packageName}}] Prepare arguments for Assembly Version' # Human-readable name for the task. - # Version .NET Assemblies (Core/5/6 and later) - # Description - Applies a version to a .NET Assemblies (Core/5/6 and later) via the .csproj files based on the build number. Based on Microsoft sample from https://msdn.microsoft.com/Library/vs/alm/Build/overview - - task: VersionDotNetCoreAssemblies@3 - displayName: '[${{packageName}}] Apply Assembly Version to ${{dependencyPackageName}}' # Human-readable name for the task. - inputs: - # Required arguments - Path: $(versioningPath) - VersionNumber: $(versioningNumber) - Injectversion: True - FilenamePattern: .csproj - AddDefault: true - Field: AssemblyVersion - OutputVersion: AppliedVersion - # PowerShell v2 - # Run a PowerShell script on Linux, macOS, or Windows. - - task: PowerShell@2 - displayName: '[${{packageName}}] Confirm Assembly Version for ${{dependencyPackageName}}' # Human-readable name for the task. - inputs: - targetType: 'inline' # 'filePath' | 'inline'. Type. Default: filePath. - # filePath: # string. Required when targetType = filePath. Script Path. - #arguments: # string. Optional. Use when targetType = filePath. Arguments. - script: | # string. Required when targetType = inline. Script. - if (${{parameters.traceLevel}} -gt 0) { - Set-PSDebug -Trace ${{parameters.traceLevel}} - } - - # Get version numbers. - [version]$productionAssemblyVersion = '$(versioningNumber)' - [version]$appliedVersion = '$(AppliedVersion)' - - # Show version number applied. - if ($appliedVersion -ne $productionAssemblyVersion) { - Write-Error "Failed to apply Assembly version $productionAssemblyVersion; actual version was $appliedVersion." - } - - Write-Information "Applied version $appliedVersion to ${{dependencyPackageName}}." - # Preference Variables - #errorActionPreference: 'stop' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. ErrorActionPreference. Default: stop. - #warningPreference: 'default' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. WarningPreference. Default: default. - informationPreference: 'continue' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. InformationPreference. Default: default. - verbosePreference: ${{ iif(eq(parameters.enableVerboseOutput, 'true'), 'continue', 'default') }} # 'default' | 'stop' | 'continue' | 'silentlyContinue'. VerbosePreference. Default: default. - debugPreference: ${{ iif(eq(parameters.enableDebug, 'true'), 'continue', 'default') }} # 'default' | 'stop' | 'continue' | 'silentlyContinue'. DebugPreference. Default: default. - #progressPreference: 'silentlyContinue' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. ProgressPreference. Default: silentlyContinue. - # Advanced - #failOnStderr: false # boolean. Fail on Standard Error. Default: false. - #showWarnings: false # boolean. Show warnings as Azure DevOps warnings. Default: false. - #ignoreLASTEXITCODE: false # boolean. Ignore $LASTEXITCODE. Default: false. - #pwsh: false # boolean. Use PowerShell Core. Default: false. - #workingDirectory: # string. Working Directory. - #runScriptInSeparateScope: false # boolean. Run script in the separate scope. Default: false. - - task: DotNetCoreCLI@2 - displayName: '[${{packageName}}] Restore solution package dependencies' - inputs: - #azureSubscription: # string. Alias: ConnectedServiceName. Azure Resource Manager connection. - command: 'restore' # 'build' | 'push' | 'pack' | 'publish' | 'restore' | 'run' | 'test' | 'custom'. Required. Command. Default: build. - #publishWebProjects: true # boolean. Optional. Use when command = publish. Publish web projects. Default: true. - projects: '$(buildSolution)' # string. Optional. Use when command = build || command = restore || command = run || command = test || command = custom || publishWebProjects = false. Path to project(s) or solution(s). - #custom: # string. Required when command = custom. Custom command. - #arguments: # string. Optional. Use when command = build || command = publish || command = run || command = test || command = custom. Arguments. - restoreArguments: '-p:DisableWorkloadAutoImportPropsLocator=true' # string. Optional. Use when command = restore. Arguments. - #publishTestResults: true # boolean. Optional. Use when command = test. Publish test results and code coverage. Default: true. - #testRunTitle: # string. Optional. Use when command = test. Test run title. - #zipAfterPublish: true # boolean. Optional. Use when command = publish. Zip published projects. Default: true. - #modifyOutputPath: true # boolean. Optional. Use when command = publish. Add project's folder name to publish path. Default: true. - #packagesToPush: '$(Build.ArtifactStagingDirectory)/*.nupkg' # string. Alias: searchPatternPush. Required when command = push. Path to NuGet package(s) to publish. Default: $(Build.ArtifactStagingDirectory)/*.nupkg. - #nuGetFeedType: 'internal' # 'internal' | 'external'. Required when command = push. Target feed location. Default: internal. - #publishVstsFeed: # string. Alias: feedPublish. Required when command = push && nuGetFeedType = internal. Target feed. - #publishFeedCredentials: # string. Alias: externalEndpoint. Required when command = push && nuGetFeedType = external. NuGet server. - #packagesToPack: '**/*.csproj' # string. Alias: searchPatternPack. Required when command = pack. Path to csproj or nuspec file(s) to pack. Default: **/*.csproj. - #configuration: '$(BuildConfiguration)' # string. Alias: configurationToPack. Optional. Use when command = pack. Configuration to Package. Default: $(BuildConfiguration). - #packDirectory: '$(Build.ArtifactStagingDirectory)' # string. Alias: outputDir. Optional. Use when command = pack. Package Folder. Default: $(Build.ArtifactStagingDirectory). - #nobuild: false # boolean. Optional. Use when command = pack. Do not build. Default: false. - #includesymbols: false # boolean. Optional. Use when command = pack. Include Symbols. Default: false. - #includesource: false # boolean. Optional. Use when command = pack. Include Source. Default: false. - #requestTimeout: '300000' # string. Set timeout for package download request. Default: 300000. - # Feeds and authentication - feedsToUse: 'config' # 'select' | 'config'. Alias: selectOrConfig. Required when command = restore. Feeds to use. Default: select. - #vstsFeed: # string. Alias: feedRestore. Optional. Use when selectOrConfig = select && command = restore. Use packages from this Azure Artifacts feed. Select from the dropdown or enter [project name/]feed name. - #includeNuGetOrg: true # boolean. Optional. Use when selectOrConfig = select && command = restore. Use packages from NuGet.org. Default: true. - nugetConfigPath: '$(Build.SourcesDirectory)/nuget.config' # string. Optional. Use when selectOrConfig = config && command = restore. Path to NuGet.config. - #externalFeedCredentials: # string. Alias: externalEndpoints. Optional. Use when selectOrConfig = config && command = restore. Credentials for feeds outside this organization/collection. - # Advanced - noCache: false # boolean. Optional. Use when command = restore. Disable local cache. Default: false. - #restoreDirectory: # string. Alias: packagesDirectory. Optional. Use when command = restore. Destination directory. - verbosityRestore: 'Detailed' # '-' | 'Quiet' | 'Minimal' | 'Normal' | 'Detailed' | 'Diagnostic'. Optional. Use when command = restore. Verbosity. Default: Normal. - - task: PowerShell@2 - displayName: '[${{packageName}}] Set build arguments' - inputs: - #targetType: 'filePath' # 'filePath' | 'inline'. Type. Default: filePath. - filePath: 'build/scripts/SetBuildTemplateArguments.ps1' # string. Required when targetType = filePath. Script Path. - arguments: '-PackageName ${{packageName}} -PackageInfos ''${{variables.packageInfos}}'' -EncodedPackageVersions ''$(versionNumbers)'' -TraceLevel ${{parameters.traceLevel}}' # string. Optional. Use when targetType = filePath. Arguments. - #script: # string. Required when targetType = inline. Script. - # Preference Variables - #errorActionPreference: 'stop' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. ErrorActionPreference. Default: stop. - #warningPreference: 'default' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. WarningPreference. Default: default. - informationPreference: 'continue' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. InformationPreference. Default: default. - verbosePreference: ${{ iif(eq(parameters.enableVerboseOutput, 'true'), 'continue', 'default') }} # 'default' | 'stop' | 'continue' | 'silentlyContinue'. VerbosePreference. Default: default. - debugPreference: ${{ iif(eq(parameters.enableDebug, 'true'), 'continue', 'default') }} # 'default' | 'stop' | 'continue' | 'silentlyContinue'. DebugPreference. Default: default. - #progressPreference: 'silentlyContinue' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. ProgressPreference. Default: silentlyContinue. - # Advanced - #failOnStderr: false # boolean. Fail on Standard Error. Default: false. - #showWarnings: false # boolean. Show warnings as Azure DevOps warnings. Default: false. - #ignoreLASTEXITCODE: false # boolean. Ignore $LASTEXITCODE. Default: false. - pwsh: true # boolean. Use PowerShell Core. Default: false. - #workingDirectory: # string. Working Directory. - #runScriptInSeparateScope: false # boolean. Run script in the separate scope. Default: false. - # Version .NET Assemblies (Core/5/6 and later) - # Description - Applies a version to a .NET Assemblies (Core/5/6 and later) via the .csproj files based on the build number. Based on Microsoft sample from https://msdn.microsoft.com/Library/vs/alm/Build/overview - - task: VersionDotNetCoreAssemblies@3 - condition: | - and - ( - succeeded(), - containsValue(split(coalesce(variables['hasAssemblyFileVersionNumbers'], ''), ','), '${{packageName}}') - ) - displayName: '[${{packageName}}] Set assembly File Version' - inputs: - # Required arguments - Path: $(Build.SourcesDirectory)/$(sourceFolderPath) - VersionNumber: $(buildFileVersion) - Injectversion: True - Field: FileVersion - AddDefault: True - # Version .NET Assemblies (Core/5/6 and later) - # Description - Applies a version to a .NET Assemblies (Core/5/6 and later) via the .csproj files based on the build number. Based on Microsoft sample from https://msdn.microsoft.com/Library/vs/alm/Build/overview - - task: VersionDotNetCoreAssemblies@3 - condition: | - and - ( - succeeded(), - containsValue(split(coalesce(variables['hasAssemblyInformationalVersionNumbers'], ''), ','), '${{packageName}}') - ) - displayName: '[${{packageName}}] Set assembly Informational Version' - inputs: - # Required arguments - Path: $(Build.SourcesDirectory)/$(sourceFolderPath) - VersionNumber: $(buildInformationalVersion) - Injectversion: True - Field: InformationalVersion - AddDefault: True - # Version .NET Assemblies (Core/5/6 and later) - # Description - Applies a version to a .NET Assemblies (Core/5/6 and later) via the .csproj files based on the build number. Based on Microsoft sample from https://msdn.microsoft.com/Library/vs/alm/Build/overview - - task: VersionDotNetCoreAssemblies@3 - condition: | - and - ( - succeeded(), - containsValue(split(coalesce(variables['hasAssemblyVersionNumbers'], ''), ','), '${{packageName}}') - ) - displayName: '[${{packageName}}] Set assembly Assembly Version' - inputs: - # Required arguments - Path: $(Build.SourcesDirectory)/$(sourceFolderPath) - VersionNumber: $(buildAssemblyVersion) - Injectversion: True - Field: AssemblyVersion - AddDefault: True - # - task: VSBuild@1 - # displayName: 'Build package solution' - # inputs: - # solution: '$(buildSolution)' # string. Required. Solution. Default: **\*.sln. - # #vsVersion: 'latest' # 'latest' | '17.0' | '16.0' | '15.0' | '14.0' | '12.0' | '11.0'. Visual Studio Version. Default: latest. - # msbuildArgs: '/p:ProduceReferenceAssembly=true;ProduceReferenceAssemblyInOutDir=true;ContinuousIntegrationBuild=$(isContinuousIntegrationBuild);FileVersion=$(buildFileVersion);InformationalVersion=$(buildInformationalVersion);AssemblyVersion=$(buildAssemblyVersion)' # string. MSBuild Arguments. - # platform: $(BuildPlatform) # string. Platform. - # configuration: $(BuildConfiguration) # string. Configuration. - # #clean: false # boolean. Clean. Default: false. - # # Advanced - # #maximumCpuCount: false # boolean. Build in Parallel. Default: false. - # #restoreNugetPackages: false # boolean. Restore NuGet Packages. Default: false. - # #msbuildArchitecture: 'x86' # 'x86' | 'x64'. MSBuild Architecture. Default: x86. - # #logProjectEvents: true # boolean. Record Project Details. Default: true. - # #createLogFile: false # boolean. Create Log File. Default: false. - # #logFileVerbosity: 'normal' # 'quiet' | 'minimal' | 'normal' | 'detailed' | 'diagnostic'. Optional. Use when createLogFile = true. Log File Verbosity. Default: normal. - # #enableDefaultLogger: true # boolean. Enable Default Logger. Default: true. - # #customVersion: # string. Custom Version. - # .NET Core v2 - # Build, test, package, or publish a .NET application, or run a custom .NET CLI command. - - task: DotNetCoreCLI@2 - displayName: '[${{packageName}}] Build package solution' - inputs: - #azureSubscription: # string. Alias: ConnectedServiceName. Azure Resource Manager connection. - command: 'build' # 'build' | 'push' | 'pack' | 'publish' | 'restore' | 'run' | 'test' | 'custom'. Required. Command. Default: build. - #publishWebProjects: true # boolean. Optional. Use when command = publish. Publish web projects. Default: true. - projects: '$(buildSolution)' # string. Optional. Use when command = build || command = restore || command = run || command = test || command = custom || publishWebProjects = false. Path to project(s) or solution(s). - #custom: # string. Required when command = custom. Custom command. - arguments: '-c $(BuildConfiguration) -p:Platform="$(BuildPlatform)";ProduceReferenceAssembly=true;ProduceReferenceAssemblyInOutDir=true;ContinuousIntegrationBuild=$(isContinuousIntegrationBuild);DisableWorkloadAutoImportPropsLocator=true;UseSharedCompilation=false' # string. Optional. Use when command = build || command = publish || command = run || command = test || command = custom. Arguments. - #restoreArguments: # string. Optional. Use when command = restore. Arguments. - #publishTestResults: true # boolean. Optional. Use when command = test. Publish test results and code coverage. Default: true. - #testRunTitle: # string. Optional. Use when command = test. Test run title. - #zipAfterPublish: true # boolean. Optional. Use when command = publish. Zip published projects. Default: true. - #modifyOutputPath: true # boolean. Optional. Use when command = publish. Add project's folder name to publish path. Default: true. - #packagesToPush: '$(Build.ArtifactStagingDirectory)/*.nupkg' # string. Alias: searchPatternPush. Required when command = push. Path to NuGet package(s) to publish. Default: $(Build.ArtifactStagingDirectory)/*.nupkg. - #nuGetFeedType: 'internal' # 'internal' | 'external'. Required when command = push. Target feed location. Default: internal. - #publishVstsFeed: # string. Alias: feedPublish. Required when command = push && nuGetFeedType = internal. Target feed. - #publishFeedCredentials: # string. Alias: externalEndpoint. Required when command = push && nuGetFeedType = external. NuGet server. - #packagesToPack: '**/*.csproj' # string. Alias: searchPatternPack. Required when command = pack. Path to csproj or nuspec file(s) to pack. Default: **/*.csproj. - #configuration: '$(BuildConfiguration)' # string. Alias: configurationToPack. Optional. Use when command = pack. Configuration to Package. Default: $(BuildConfiguration). - #packDirectory: '$(Build.ArtifactStagingDirectory)' # string. Alias: outputDir. Optional. Use when command = pack. Package Folder. Default: $(Build.ArtifactStagingDirectory). - #nobuild: false # boolean. Optional. Use when command = pack. Do not build. Default: false. - #includesymbols: false # boolean. Optional. Use when command = pack. Include Symbols. Default: false. - #includesource: false # boolean. Optional. Use when command = pack. Include Source. Default: false. - #requestTimeout: '300000' # string. Set timeout for package download request. Default: 300000. - # Advanced - #workingDirectory: # string. Optional. Use when command != restore && command != push && command != pack. Working directory. - - task: PublishSymbols@2 - displayName: '[${{packageName}}] Publish symbols' - inputs: - #SymbolsFolder: '$(Build.SourcesDirectory)' # string. Path to symbols folder. Default: $(Build.SourcesDirectory). - SearchPattern: 'src/**/bin/**/$(BuildConfiguration)/**/*.pdb' # string. Required. Search pattern. Default: **/bin/**/*.pdb. - #Manifest: # string. Manifest. - IndexSources: false # boolean. Index sources. Default: true. # Disable indexing since GitHub is unsupported - PublishSymbols: true # boolean. Publish symbols. Default: true. - SymbolServerType: 'TeamServices' # Or 'FileShare'. Required when PublishSymbols = true. Symbol server type. - #SymbolsPath: # string. Optional. Use when PublishSymbols = true && SymbolServerType = FileShare. Path to publish symbols. - #CompressSymbols: false # boolean. Optional. Use when SymbolServerType = FileShare. Compress symbols. Default: false. - #SymbolExpirationInDays: '36530' # string. Optional. Use when PublishSymbols = true && SymbolServerType = TeamServices. Symbol Expiration (in days). Default: 36530. - # Advanced - #IndexableFileFormats: 'Default' # 'Default' | 'Pdb' | 'SourceMap' | 'All'. Optional. Use when PublishSymbols = true && SymbolServerType = TeamServices. Symbol file formats to publish. Default: Default. - #DetailedLog: true # boolean. Verbose logging. Default: true. - #TreatNotIndexedAsWarning: false # boolean. Warn if not indexed. Default: false. - #UseNetCoreClientTool: false # boolean. Use NetCore client tool. Default: false. - #SymbolsMaximumWaitTime: # string. Max wait time (min). - #SymbolsProduct: # string. Product. - #SymbolsVersion: # string. Version. - #SymbolsArtifactName: 'Symbols_$(BuildConfiguration)' # string. Artifact name. Default: Symbols_$(BuildConfiguration). - - task: CopyFiles@2 - displayName: '[${{packageName}}] Copy build output to staging area' - inputs: - #SourceFolder: # string. Source Folder. - Contents: | # string. Required. Contents. Default: **. - src\${{packageName}}\**\bin\**\$(BuildConfiguration)\** - tests\${{packageName}}*\**\bin\**\$(BuildConfiguration)\** - TargetFolder: '$(Build.ArtifactStagingDirectory)' # string. Required. Target Folder. - # Advanced - #CleanTargetFolder: false # boolean. Clean Target Folder. Default: false. - #OverWrite: false # boolean. Overwrite. Default: false. - #flattenFolders: false # boolean. Flatten Folders. Default: false. - #preserveTimestamp: false # boolean. Preserve Target Timestamp. Default: false. - #retryCount: '0' # string. Retry count to copy the file. Default: 0. - #delayBetweenRetries: '1000' # string. Delay between two retries. Default: 1000. - #ignoreMakeDirErrors: false # boolean. Ignore errors during creation of target folder. Default: false. - - task: PublishBuildArtifacts@1 - displayName: '[${{packageName}}] Publish build artifacts to pipeline' - inputs: - PathtoPublish: '$(Build.ArtifactStagingDirectory)' # string. Required. Path to publish. Default: $(Build.ArtifactStagingDirectory). - ArtifactName: 'drop' # string. Required. Artifact name. Default: drop. - publishLocation: 'Container' # 'Container' | 'FilePath'. Alias: ArtifactType. Required. Artifact publish location. Default: Container. - #MaxArtifactSize: '0' # string. Max Artifact Size. Default: 0. - #TargetPath: # string. Required when ArtifactType = FilePath. File share path. - #Parallel: false # boolean. Optional. Use when ArtifactType = FilePath. Parallel copy. Default: false. - #ParallelCount: '8' # string. Optional. Use when ArtifactType = FilePath && Parallel = true. Parallel count. Default: 8. - # Advanced - #StoreAsTar: false # boolean. Tar the artifact before uploading. Default: false. + - template: /build/build-steps.yml # reference to template + parameters: # provided parameters + packageName: ${{packageName}} + buildSolution: ${{variables.buildSolution}} + assemblyVersionNumberCondition: and(succeeded(), containsValue(split(variables['hasAssemblyVersionNumbers'], ','), '${{packageName}}')) + assemblyFileVersionNumberCondition: and(succeeded(), containsValue(split(variables['hasAssemblyFileVersionNumbers'], ','), '${{packageName}}')) + assemblyInformationalVersionNumberCondition: and(succeeded(), containsValue(split(variables['hasAssemblyInformationalVersionNumbers'], ','), '${{packageName}}')) + packageNames: ${{variables.allPackageNames}} + packageInfos: ${{variables.packageInfos}} + encodedPackageVersions: $(versionNumbers) + buildConfiguration: $(BuildConfiguration) + buildPlatform: $(BuildPlatform) + isContinuousIntegration: ${{variables.isContinuousIntegrationBuild}} + enableVerboseOutput: ${{parameters.enableVerboseOutput}} + enableDebug: ${{parameters.enableDebug}} + traceLevel: ${{parameters.traceLevel}} - stage: QA dependsOn: - Configure @@ -793,94 +553,27 @@ stages: pool: vmImage: windows-latest # Pool where this job will run. steps: # A list of steps to run. - - task: DownloadBuildArtifacts@1 - displayName: '[${{packageName}}] Download build artifacts' - inputs: - buildType: 'current' # 'current' | 'specific'. Required. Download artifacts produced by. Default: current. - #project: # string. Required when buildType == specific. Project. - #pipeline: # string. Alias: definition. Required when buildType == specific. Build pipeline. - #specificBuildWithTriggering: false # boolean. Optional. Use when buildType == specific. When appropriate, download artifacts from the triggering build. Default: false. - buildVersionToDownload: 'latest' # 'latest' | 'latestFromBranch' | 'specific'. Required when buildType == specific. Build version to download. Default: latest. - #allowPartiallySucceededBuilds: false # boolean. Optional. Use when buildType == specific && buildVersionToDownload != specific. Download artifacts even from partially succeeded builds. Default: false. - branchName: $(Build.SourceBranch) # string. Required when buildType == specific && buildVersionToDownload == latestFromBranch. Branch name. Default: refs/heads/master. - #buildId: # string. Required when buildType == specific && buildVersionToDownload == specific. Build. - #tags: # string. Optional. Use when buildType == specific && buildVersionToDownload != specific. Build Tags. - downloadType: 'single' # 'single' | 'specific'. Required. Download type. Default: single. - artifactName: drop # string. Required when downloadType == single. Artifact name. - #itemPattern: '**' # string. Matching pattern. Default: **. - downloadPath: '$(Pipeline.Workspace)' # string. Required. Destination directory. Default: $(System.ArtifactsDirectory). - #cleanDestinationFolder: false # boolean. Clean destination folder. Default: false. - # Advanced - #parallelizationLimit: '8' # string. Parallelization limit. Default: 8. - #checkDownloadedFiles: false # boolean. Check downloaded files. Default: false. - #retryDownloadCount: '4' # string. Retry count. Default: 4. - #extractTars: # boolean. Extract all files that are stored inside tar archives. - - task: CopyFiles@2 - displayName: '[${{packageName}}] Copy files to working area' - inputs: - SourceFolder: $(Pipeline.Workspace)\drop # string. Source Folder. - Contents: '**' # string. Required. Contents. Default: **. - TargetFolder: $(System.DefaultWorkingDirectory) # string. Required. Target Folder. - # Advanced - #CleanTargetFolder: false # boolean. Clean Target Folder. Default: false. - #OverWrite: false # boolean. Overwrite. Default: false. - #flattenFolders: false # boolean. Flatten Folders. Default: false. - #preserveTimestamp: false # boolean. Preserve Target Timestamp. Default: false. - #retryCount: '0' # string. Retry count to copy the file. Default: 0. - #delayBetweenRetries: '1000' # string. Delay between two retries. Default: 1000. - #ignoreMakeDirErrors: false # boolean. Ignore errors during creation of target folder. Default: false. - - task: VSTest@3 - displayName: '[${{packageName}}] Run automated tests' - inputs: - #azureSubscription: # string. Alias: ConnectedServiceName. Azure Resource Manager connection. - # Test selection - testSelector: 'testAssemblies' # 'testAssemblies' | 'testPlan' | 'testRun'. Required. Select tests using. Default: testAssemblies. - testAssemblyVer2: ${{ variables.testAssemblies }} # string. Required when testSelector = testAssemblies. Test files. - #testPlan: # string. Required when testSelector = testPlan. Test plan. - #testSuite: # string. Required when testSelector = testPlan. Test suite. - #testConfiguration: # string. Required when testSelector = testPlan. Test configuration. - #tcmTestRun: '$(test.RunId)' # string. Optional. Use when testSelector = testRun. Test Run. Default: $(test.RunId). - searchFolder: '$(System.DefaultWorkingDirectory)' # string. Required. Search folder. Default: $(System.DefaultWorkingDirectory). - #resultsFolder: '$(Agent.TempDirectory)\TestResults' # string. Test results folder. Default: $(Agent.TempDirectory)\TestResults. - #testFiltercriteria: # string. Optional. Use when testSelector = testAssemblies. Test filter criteria. - #runOnlyImpactedTests: False # boolean. Optional. Use when testSelector = testAssemblies. Run only impacted tests. Default: False. - #runAllTestsAfterXBuilds: '50' # string. Optional. Use when testSelector = testAssemblies && runOnlyImpactedTests = true. Number of builds after which all tests should be run. Default: 50. - #uiTests: false # boolean. Test mix contains UI tests. Default: false. - # Execution options - #vstestLocationMethod: 'version' # 'version' | 'location'. Select test platform using. Default: version. - #vsTestVersion: 'latest' # 'latest' | '17.0' | '16.0' | '15.0' | '14.0' | 'toolsInstaller'. Optional. Use when vstestLocationMethod = version. Test platform version. Default: latest. - #vstestLocation: # string. Optional. Use when vstestLocationMethod = location. Path to vstest.console.exe. - #runSettingsFile: # string. Settings file. - #overrideTestrunParameters: # string. Override test run parameters. - #pathtoCustomTestAdapters: # string. Path to custom test adapters. - #runInParallel: False # boolean. Run tests in parallel on multi-core machines. Default: False. - #runTestsInIsolation: False # boolean. Run tests in isolation. Default: False. - #codeCoverageEnabled: False # boolean. Code coverage enabled. Default: False. - #otherConsoleOptions: # string. Other console options. - #diagnosticsEnabled: false # boolean. Collect advanced diagnostics in case of catastrophic failures. Default: false. - #collectDumpOn: 'onAbortOnly' # 'onAbortOnly' | 'always' | 'never'. Optional. Use when diagnosticsEnabled = true. Collect process dump and attach to test run report. Default: onAbortOnly. - #rerunFailedTests: False # boolean. Rerun failed tests. Default: False. - #rerunType: 'basedOnTestFailurePercentage' # 'basedOnTestFailurePercentage' | 'basedOnTestFailureCount'. Optional. Use when rerunFailedTests = true. Do not rerun if test failures exceed specified threshold. Default: basedOnTestFailurePercentage. - #rerunFailedThreshold: '30' # string. Optional. Use when rerunFailedTests = true && rerunType = basedOnTestFailurePercentage. % failure. Default: 30. - #rerunFailedTestCasesMaxLimit: '5' # string. Optional. Use when rerunFailedTests = true && rerunType = basedOnTestFailureCount. # of failed tests. Default: 5. - #rerunMaxAttempts: '3' # string. Optional. Use when rerunFailedTests = true. Maximum # of attempts. Default: 3. - # Reporting options - #testRunTitle: # string. Test run title. - platform: $(BuildPlatform) # string. Build platform. - configuration: $(BuildConfiguration) # string. Build configuration. - #publishRunAttachments: true # boolean. Upload test attachments. Default: true. - #donotPublishTestResults: false # boolean. Optional. Use when runInParallel = false. Disable publishing test results. Default: false. - failOnMinTestsNotRun: true # boolean. Fail the task if a minimum number of tests are not run. Default: False. - #minimumExpectedTests: '1' # string. Optional. Use when failOnMinTestsNotRun = true. Minimum # of tests. Default: 1. + - template: /build/qa-steps.yml # reference to template + parameters: # provided parameters + packageName: ${{packageName}} + testAssemblySearchPattern: ${{ variables.testAssemblies }} + buildPlatform: $(BuildPlatform) + buildConfiguration: $(BuildConfiguration) - stage: Publication condition: | - and - ( - succeeded(), - notIn(stageDependencies.Configure.Version_numbering.PromoteVersionList.result, 'Skipped'), - in(dependencies.Build.result, 'Succeeded'), - or(eq(variables['isDevelopBranch'], 'true'), and(gt(length(coalesce(variables.publicationRequiredPackageNames, '')), 0), gt(length(split(variables.publicationRequiredPackageNames, ',')), 0))), - or(and(gt(length(coalesce(variables.publicationRequiredPackageNames, '')), 0), gt(length(split(variables.publicationRequiredPackageNames, ',')), 0)), and(gt(length(coalesce(stageDependencies.Configure.outputs['Production_packages.ChangedPackages.changedPackageNames'], '')), 0), gt(length(split(stageDependencies.Configure.outputs['Production_packages.ChangedPackages.changedPackageNames'], ',')), 0))) + and( + succeeded(), + or( + and( + gt(length(coalesce(variables.publicationRequiredPackageNames, '')), 0), + gt(length(split(variables.publicationRequiredPackageNames, ',')), 0) + ), + and( + eq(variables['isDevelopBranch'], 'true'), + gt(length(coalesce(stageDependencies.Configure.outputs['Production_packages.ChangedPackages.changedPackageNames'], '')), 0), + gt(length(split(stageDependencies.Configure.outputs['Production_packages.ChangedPackages.changedPackageNames'], ',')), 0) + ) + ) ) dependsOn: - Configure @@ -901,60 +594,10 @@ stages: Release: BuildConfiguration: release steps: - - task: MSBuild@1 - displayName: "Restore package dependencies" - inputs: - solution: ${{ variables.solution }} # Required # Relative path from repo root of the project(s) or solution(s) to run. Wildcards can be used. For example, `**/*.csproj` for all csproj files in all sub folders. - #msbuildLocationMethod: # Options: 'version', 'location' # Optional - #msbuildVersion: # Options: 'latest', '17.0', '16.0', '15.0', '14.0', '12.0', '4.0' # Optional # If the preferred version cannot be found, the latest version found will be used instead. On an macOS agent, xbuild (Mono) will be used if version is lower than 15.0. - #msbuildArchitecture: # Options: 'x86', 'x64' # Optional # Optionally supply the architecture (x86, x64) of MSBuild to run. - #msbuildLocation: # Optional # Optionally supply the path to MSBuild. - #platform: # Optional - configuration: $(BuildConfiguration) # Optional - msbuildArguments: -t:restore # Optional # Additional arguments passed to MSBuild (on Windows) and xbuild (on macOS). - #clean: # Optional # Run a clean build (/t:clean) prior to the build. - #maximumCpuCount: # Optional # If your MSBuild target configuration is compatible with building in parallel, you can optionally check this input to pass the /m switch to MSBuild (Windows only). If your target configuration is not compatible with building in parallel, checking this option may cause your build to result in file-in-use errors, or intermittent or inconsistent build failures. - #restoreNugetPackages: # Optional # This option is deprecated. To restore NuGet packages, add a [NuGet](https://docs.microsoft.com/azure/devops/pipelines/tasks/package/nuget) task before the build. - #logProjectEvents: # Optional # Optionally record timeline details for each project (Windows only). - #createLogFile: # Optional # Optionally create a log file (Windows only). - #logFileVerbosity: # Options: 'quiet', 'minimal', 'normal', 'detailed', 'diagnostic' # Optional # Optional log file verbosity. - - task: DownloadBuildArtifacts@1 - inputs: - buildType: current # Options: 'current', 'specific' # Required # Download artifacts produced by the current build, or from a specific build. - # project: # Required when buildType == specific # The project from which to download the build artifacts - # definition: # Required when buildType == specific # Select the build pipeline name - #specificBuildWithTriggering: # Optional # If checked, this build task will try to download artifacts from the triggering build. If there is no triggering build from the specified pipeline, it will download artifacts from the build specified in the options below. - # buildVersionToDownload: latest # Options: 'latest', 'latestFromBranch', 'specific' # Required - #allowPartiallySucceededBuilds: # Optional # If checked, this build task will try to download artifacts whether the build is succeeded or partially succeeded. - # branchName: refs/heads/master # Required # Specify to filter on branch/ref name, for example: ```refs/heads/develop```. - # buildId: # Required when buildType == specific && buildVersionToDownload == specific # The build from which to download the artifacts - #tags: # Optional # A comma-delimited list of tags. Only builds with these tags will be returned. - downloadType: single # Options: 'single', 'specific' # Required # Download a specific artifact or specific files from the build. - artifactName: drop # Required when downloadType == single # The name of the artifact to download - #itemPattern: # Optional # Specify files to be downloaded as multi line minimatch pattern. [More Information](https://aka.ms/minimatchexamples)

The default pattern (//*//*) will download all files across all artifacts in the build if "Specific files" option is selected. To download all files within artifact drop use drop/**.

- downloadPath: $(System.ArtifactsDirectory) # Required # Path on the agent machine where the artifacts will be downloaded - #cleanDestinationFolder: # Optional # Delete all existing files in destination folder before artifact download - #parallelizationLimit: # Optional # Number of files to download simultaneously - #checkDownloadedFiles: # Optional # If checked, this build task will check that all files are fully downloaded. - #retryDownloadCount: # Optional # Optional number of times to retry downloading a build artifact if the download fails. - #extractTars: # Optional # Enable this option to extract all downloaded files that have .tar extension. This is helpful because you need to pack your artifact files into tar if you want to preserve Unix file permissions. Enabling `StoreAsTar` option in PublishBuildArtifacts task will store artifacts as .tar files automatically. - - task: CopyFiles@2 - inputs: - SourceFolder: $(System.ArtifactsDirectory)/drop # Optional # The source folder that the copy pattern(s) will be run from. Empty is the root of the repo. Use [variables](https://go.microsoft.com/fwlink/?LinkID=550988) if files are not in the repo. Example: $(agent.builddirectory) - Contents: "src/**/bin/**/$(BuildConfiguration)/**" # Required # File paths to include as part of the copy. Supports multiple lines of match patterns. [More Information](https://go.microsoft.com/fwlink/?LinkID=708389) - TargetFolder: $(Build.SourcesDirectory) # Required # Target folder or UNC path files will copy to. You can use [variables](http://go.microsoft.com/fwlink/?LinkID=550988). Example: $(build.artifactstagingdirectory) - #CleanTargetFolder: # Optional # Delete all existing files in target folder before copy - OverWrite: true # Optional # Replace existing file in target folder - #flattenFolders: # Optional # Flatten the folder structure and copy all files into the specified target folder. - #preserveTimestamp: # Optional # Using the original source file, preserve the target file timestamp. - #retryCount: # Optional # Specify the retry count to copy the file. It might help to resolve intermittent issues e.g. with UNC target paths on a remote host. - #delayBetweenRetries: # Optional # Specify the delay between two retries. It might help to be more resilient to intermittent issues e.g. with UNC target paths on a remote host. - #ignoreMakeDirErrors: # Optional # Ignore errors which happen during creation of target folder. This could be useful to avoid issues with parallel execution of task by several agents with one target folder. - - task: NuGetToolInstaller@1 - displayName: "Install NuGet CLI" - inputs: - #versionSpec: # Optional # A version or version range that specifies the NuGet version to make available on the path. Use x as a wildcard. See the [list of available NuGet versions](http://dist.nuget.org/tools.json).If you want to match a pre-release version, the specification must contain a major, minor, patch, and pre-release version from the list above.Examples: 4.x, 3.3.x, 2.8.6, >=4.0.0-0If unspecified, a version will be chosen automatically. - checkLatest: false # Optional # Always check for and download the latest available version of NuGet.exe which satisfies the version spec.Enabling this option could cause unexpected build breaks when a new version of NuGet is released. + - template: /build/publication-create-packages-prepare.yml # reference to template + parameters: # provided parameters + buildConfiguration: $(BuildConfiguration) + buildSolution: ${{variables.solution}} # Create NuGet packages - ${{ each packageName in split(variables.allPackageNames, ',') }}: - task: PowerShell@2 @@ -968,7 +611,7 @@ stages: inputs: #targetType: 'filePath' # 'filePath' | 'inline'. Type. Default: filePath. filePath: 'build/scripts/SetReleaseNotesArgument.ps1' # string. Required when targetType = filePath. Script Path. - arguments: '-PackageName ${{packageName}} -SourceCommitHash $(Build.SourceVersion) -PackageInfos ''${{variables.packageInfos}}'' -SourceRootFolderPath $(Build.SourcesDirectory) -IsBuildMasterBranch ${{ iif(eq(variables[''Build.SourceBranch''], ''refs/heads/master''), ''$True'', ''$False'') }} -TraceLevel ${{parameters.traceLevel}}' # string. Optional. Use when targetType = filePath. Arguments. + arguments: '-PackageName ${{packageName}} -TraceLevel ${{parameters.traceLevel}}' # string. Optional. Use when targetType = filePath. Arguments. #script: # string. Required when targetType = inline. Script. # Preference Variables #errorActionPreference: 'stop' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. ErrorActionPreference. Default: stop. @@ -1005,7 +648,7 @@ stages: or(containsValue(split(coalesce(variables.publicationRequiredPackageNames, ''), ','), '${{ packageName }}'), and(containsValue(split(coalesce(variables['changedPackageNames'], ''), ','), '${{ packageName }}'), eq(variables['isDevelopBranch'], 'true'))) ) - pwsh: | - Import-Module "$(Build.SourcesDirectory)/build/psmodules/CommonHelpers/CommonHelpers.psm1" -Force + Import-Module "$(Build.SourcesDirectory)/build/psmodules/CommonHelpers/CommonHelpers.psm1" -Force -Scope Local if (${{parameters.traceLevel}} -gt 0) { Set-PSDebug -Trace ${{parameters.traceLevel}} @@ -1063,7 +706,7 @@ stages: inputs: #targetType: 'filePath' # 'filePath' | 'inline'. Type. Default: filePath. filePath: 'build/scripts/UpdatePackageMetadata.ps1' # string. Required when targetType = filePath. Script Path. - arguments: "-PackageName '${{packageName}}' -EncodedPackageVersions '$(versionNumbers)' -EncodedReleaseNotes '$(releaseNotesArg)' -PackageSearchRootPath '$(Build.ArtifactStagingDirectory)' -BuildConfiguration $(BuildConfiguration) -TempPath '$(Agent.TempDirectory)' -TraceLevel ${{parameters.traceLevel}}" # string. Optional. Use when targetType = filePath. Arguments. + arguments: "-PackageName '${{packageName}}' -EncodedPackageVersions '$(versionNumbers)' -EncodedReleaseNotes '$(releaseNotesArg)' -BuildConfiguration $(BuildConfiguration) -TraceLevel ${{parameters.traceLevel}}" # string. Optional. Use when targetType = filePath. Arguments. #script: # string. Required when targetType = inline. Script. # Preference Variables #errorActionPreference: 'stop' # 'default' | 'stop' | 'continue' | 'silentlyContinue'. ErrorActionPreference. Default: stop. @@ -1081,12 +724,6 @@ stages: #runScriptInSeparateScope: false # boolean. Run script in the separate scope. Default: false. # Publish NuGet packages to pipeline - task: PublishBuildArtifacts@1 - condition: | - and - ( - succeeded(), - or(and(gt(length(coalesce(variables.publicationRequiredPackageNames, '')), 0), gt(length(split(variables.publicationRequiredPackageNames, ',')), 0)), and(gt(length(coalesce(variables['changedPackageNames'], '')), 0), gt(length(split(variables['changedPackageNames'], ',')), 0))) - ) inputs: PathtoPublish: $(Build.ArtifactStagingDirectory)/packages # Required # The folder or file path to publish. This can be a fully-qualified path or a path relative to the root of the repository. Wildcards are not supported. [Variables](https://go.microsoft.com/fwlink/?LinkID=550988) are supported. Example: $(Build.ArtifactStagingDirectory) ArtifactName: packages # Required # The name of the artifact to create in the publish location. @@ -1096,69 +733,9 @@ stages: #ParallelCount: # Optional # Enter the degree of parallelism, or number of threads used, to perform the copy. The value must be at least 1 and not greater than 128. #FileCopyOptions: # Optional # Pass additional options to the Robocopy command. #StoreAsTar: # Optional # Add all files from the publish path to a tar archive before uploading. This allows you to preserve the UNIX file permissions. Use `extractTars` option of DownloadBuildArtifacts task to extract the downloaded items automatically. - - job: Publish_Packages - displayName: "Publish NuGet packages to private feed" - dependsOn: Create_Packages - condition: | - and - ( - succeeded(), - or(and(gt(length(coalesce(variables.publicationRequiredPackageNames, '')), 0), gt(length(split(variables.publicationRequiredPackageNames, ',')), 0)), and(gt(length(coalesce(variables['changedPackageNames'], '')), 0), gt(length(split(variables['changedPackageNames'], ',')), 0))) - ) - variables: - BuildConfiguration: release - steps: - - checkout: none - - task: NuGetToolInstaller@1 - displayName: "Install NuGet CLI" - # inputs: - #versionSpec: # Optional # A version or version range that specifies the NuGet version to make available on the path. Use x as a wildcard. See the [list of available NuGet versions](http://dist.nuget.org/tools.json).If you want to match a pre-release version, the specification must contain a major, minor, patch, and pre-release version from the list above.Examples: 4.x, 3.3.x, 2.8.6, >=4.0.0-0If unspecified, a version will be chosen automatically. - # checkLatest: true # Optional # Always check for and download the latest available version of NuGet.exe which satisfies the version spec.Enabling this option could cause unexpected build breaks when a new version of NuGet is released. - # Configure NuGet tools to authenticate with Azure Artifacts and other NuGet repositories. Requires NuGet >= 4.8.5385, dotnet >= 6, or MSBuild >= 15.8.166.59604. - - task: NuGetAuthenticate@1 - # inputs: - # forceReinstallCredentialProvider: false # boolean. Reinstall the credential provider even if already installed. Default: false. - #nuGetServiceConnections: # string. Service connection credentials for feeds outside this organization. - - task: DownloadPipelineArtifact@2 - inputs: - buildType: "current" - artifactName: "packages" - itemPattern: "**/$(BuildConfiguration)/**/*" - targetPath: "$(System.ArtifactsDirectory)" - # Build, test, package, or publish a .NET application, or run a custom .NET CLI command. - - task: DotNetCoreCLI@2 - displayName: "Upload packages to package server" - inputs: - #azureSubscription: # string. Alias: ConnectedServiceName. Azure Resource Manager connection. - command: 'push' # 'build' | 'push' | 'pack' | 'publish' | 'restore' | 'run' | 'test' | 'custom'. Required. Command. Default: build. - #publishWebProjects: true # boolean. Optional. Use when command = publish. Publish web projects. Default: true. - #projects: # string. Optional. Use when command = build || command = restore || command = run || command = test || command = custom || publishWebProjects = false. Path to project(s) or solution(s). - #custom: # string. Required when command = custom. Custom command. - #arguments: # string. Optional. Use when command = build || command = publish || command = run || command = test || command = custom. Arguments. - #restoreArguments: # string. Optional. Use when command = restore. Arguments. - #publishTestResults: true # boolean. Optional. Use when command = test. Publish test results and code coverage. Default: true. - #testRunTitle: # string. Optional. Use when command = test. Test run title. - #zipAfterPublish: true # boolean. Optional. Use when command = publish. Zip published projects. Default: true. - #modifyOutputPath: true # boolean. Optional. Use when command = publish. Add project's folder name to publish path. Default: true. - packagesToPush: '$(System.ArtifactsDirectory)/**/*.nupkg' # string. Alias: searchPatternPush. Required when command = push. Path to NuGet package(s) to publish. Default: $(Build.ArtifactStagingDirectory)/*.nupkg. - nuGetFeedType: 'internal' # 'internal' | 'external'. Required when command = push. Target feed location. Default: internal. - publishVstsFeed: $(PACKAGE_FEED_ID) # string. Alias: feedPublish. Required when command = push && nuGetFeedType = internal. Target feed. - #publishFeedCredentials: # string. Alias: externalEndpoint. Required when command = push && nuGetFeedType = external. NuGet server. - #packagesToPack: '**/*.csproj' # string. Alias: searchPatternPack. Required when command = pack. Path to csproj or nuspec file(s) to pack. Default: **/*.csproj. - #configuration: '$(BuildConfiguration)' # string. Alias: configurationToPack. Optional. Use when command = pack. Configuration to Package. Default: $(BuildConfiguration). - #packDirectory: '$(Build.ArtifactStagingDirectory)' # string. Alias: outputDir. Optional. Use when command = pack. Package Folder. Default: $(Build.ArtifactStagingDirectory). - #nobuild: false # boolean. Optional. Use when command = pack. Do not build. Default: false. - #includesymbols: false # boolean. Optional. Use when command = pack. Include Symbols. Default: false. - #includesource: false # boolean. Optional. Use when command = pack. Include Source. Default: false. - #requestTimeout: '300000' # string. Set timeout for package download request. Default: 300000. - # Feeds and authentication - #feedsToUse: 'select' # 'select' | 'config'. Alias: selectOrConfig. Required when command = restore. Feeds to use. Default: select. - #vstsFeed: # string. Alias: feedRestore. Optional. Use when selectOrConfig = select && command = restore. Use packages from this Azure Artifacts feed. Select from the dropdown or enter [project name/]feed name. - #includeNuGetOrg: true # boolean. Optional. Use when selectOrConfig = select && command = restore. Use packages from NuGet.org. Default: true. - #nugetConfigPath: # string. Optional. Use when selectOrConfig = config && command = restore. Path to NuGet.config. - #externalFeedCredentials: # string. Alias: externalEndpoints. Optional. Use when selectOrConfig = config && command = restore. Credentials for feeds outside this organization/collection. - # Advanced - #publishPackageMetadata: true # boolean. Optional. Use when command = push && nuGetFeedType = internal. Publish pipeline metadata. Default: true. + - template: /build/publication-publish-packages-job.yml # reference to template + parameters: # provided parameters + buildConfiguration: $(BuildConfiguration) - stage: Cleanup displayName: "End" dependsOn: @@ -1185,8 +762,7 @@ stages: # continueOnError: string # Continue running even on failure? # timeoutInMinutes: string # Time to wait for this job to complete before the server kills it. # cancelTimeoutInMinutes: string # Time to wait for the job to cancel before forcibly terminating it. - variables: # Job-specific variables. - rolledBackPackageList: '' + # variables: # Job-specific variables. steps: # A list of steps to run. - ${{ each packageName in split(variables.allPackageNames, ',') }}: # Azure CLI v2 @@ -1197,7 +773,7 @@ stages: ( succeeded(), or(eq(variables['isDevelopBranch'], 'true'), and(gt(length(coalesce(variables.publicationRequiredPackageNames, '')), 0), gt(length(split(variables.publicationRequiredPackageNames, ',')), 0))), - or(and(gt(length(coalesce(variables.publicationRequiredPackageNames, '')), 0), containsValue(split(variables.publicationRequiredPackageNames, ','), '${{ packageName }}')), and(gt(length(coalesce(variables['ChangedPackages.changedPackageNames'], '')), 0), containsValue(split(variables['ChangedPackages.changedPackageNames'], ','), '${{ packageName }}'))) + or(and(gt(length(coalesce(variables.publicationRequiredPackageNames, '')), 0), containsValue(split(variables.publicationRequiredPackageNames, ','), '${{ packageName }}')), and(gt(length(coalesce(variables['changedPackageNames'], '')), 0), containsValue(split(variables['changedPackageNames'], ','), '${{ packageName }}'))) ) displayName: '[${{packageName}}] Prepare arguments for rollback' # Human-readable name for the task. inputs: @@ -1206,7 +782,7 @@ stages: scriptLocation: 'inlineScript' # 'inlineScript' | 'scriptPath'. Required. Script Location. Default: scriptPath. # scriptPath: # string. Required when scriptLocation = scriptPath. Script Path. inlineScript: | # string. Required when scriptLocation = inlineScript. Inline Script. - Import-Module "$(Build.SourcesDirectory)/build/psmodules/CommonHelpers/CommonHelpers.psm1" -Force + Import-Module "$(Build.SourcesDirectory)/build/psmodules/CommonHelpers/CommonHelpers.psm1" -Force -Scope Local if (${{parameters.traceLevel}} -gt 0) { Set-PSDebug -Trace ${{parameters.traceLevel}} @@ -1214,7 +790,7 @@ stages: # set environment variable for current process $env:AZURE_DEVOPS_EXT_PAT = $env:SYSTEM_ACCESSTOKEN - + az devops configure -d organization=${env:ORGANIZATION_URL} project=${env:PROJECT_NAME} az account set -s ${env:SUBSCRIPTION_ID} @@ -1222,7 +798,7 @@ stages: if ($null -eq $packageVersions) { Write-Error 'Package versions not found for ${{ packageName }}' } - + [version]$originalNextPackageVersion = $packageVersions.PackagePostProductionVersion Write-Host "##vso[task.setvariable variable=originalNextMajor]$($originalNextPackageVersion.Major)" Write-Host "##vso[task.setvariable variable=originalNextMinor]$($originalNextPackageVersion.Minor)" @@ -1235,12 +811,12 @@ stages: } $variableListOutput = & az pipelines variable-group variable list --group-id $packageInfo.variableGroupId - $variableGroupVersionNumbers = ($variableListOutput | ConvertFrom-Json).PSObject.Properties - | Where-Object { $_.Name.StartsWith('next') } - | Out-String -InputObject { $_.Name + ':' + $_.Value.value } -Stream - | Sort-Object - | ConvertFrom-Csv -Delimiter ':' -Header 'Name', 'Value' - | Out-String -InputObject { $_.Value } -Stream + $variableGroupVersionNumbers = ($variableListOutput | ConvertFrom-Json).PSObject.Properties | + Where-Object { $_.Name.StartsWith('next') -and $_.Name.EndsWith('number') } | + Out-String -InputObject { $_.Name + ':' + $_.Value.value } -Stream | + Sort-Object | + ConvertFrom-Csv -Delimiter ':' -Header 'Name', 'Value' | + Out-String -InputObject { $_.Value } -Stream [version] $currentNextPackageVersion = ($variableGroupVersionNumbers[0], $variableGroupVersionNumbers[1], $variableGroupVersionNumbers[2], $variableGroupVersionNumbers[3] -join '.') Write-Host "##vso[task.setvariable variable=currentNextMajor]$($currentNextPackageVersion.Major)" Write-Host "##vso[task.setvariable variable=currentNextMinor]$($currentNextPackageVersion.Minor)" @@ -1258,49 +834,17 @@ stages: ( succeeded(), or(eq(variables['isDevelopBranch'], 'true'), and(gt(length(coalesce(variables.publicationRequiredPackageNames, '')), 0), gt(length(split(variables.publicationRequiredPackageNames, ',')), 0))), - or(and(gt(length(coalesce(variables.publicationRequiredPackageNames, '')), 0), containsValue(split(variables.publicationRequiredPackageNames, ','), '${{ packageName }}')), and(gt(length(coalesce(variables['ChangedPackages.changedPackageNames'], '')), 0), containsValue(split(variables['ChangedPackages.changedPackageNames'], ','), '${{ packageName }}'))), + or(and(gt(length(coalesce(variables.publicationRequiredPackageNames, '')), 0), containsValue(split(variables.publicationRequiredPackageNames, ','), '${{ packageName }}')), and(gt(length(coalesce(variables['changedPackageNames'], '')), 0), containsValue(split(variables['changedPackageNames'], ','), '${{ packageName }}'))), and(eq(variables['currentNextMajor'], variables['originalNextMajor']), eq(variables['currentNextMinor'], variables['originalNextMinor']), eq(variables['currentNextPatch'], variables['originalNextPatch']), eq(variables['currentNextPreview'], variables['originalNextPreview'])) ) displayName: '[${{packageName}}] Rollback version numbers' # Human-readable name for the task. inputs: azureSubscription: $(SUBSCRIPTION_ID) # string. Alias: connectedServiceNameARM. Required. Azure Resource Manager connection. scriptType: 'pscore' # 'ps' | 'pscore' | 'batch' | 'bash'. Required. Script Type. - scriptLocation: 'inlineScript' # 'inlineScript' | 'scriptPath'. Required. Script Location. Default: scriptPath. - # scriptPath: # string. Required when scriptLocation = scriptPath. Script Path. - inlineScript: | # string. Required when scriptLocation = inlineScript. Inline Script. - Import-Module "$(Build.SourcesDirectory)/build/psmodules/CommonHelpers/CommonHelpers.psm1" -Force - - if (${{parameters.traceLevel}} -gt 0) { - Set-PSDebug -Trace ${{parameters.traceLevel}} - } - - # set environment variable for current process - $env:AZURE_DEVOPS_EXT_PAT = $env:SYSTEM_ACCESSTOKEN - - # Get information on current package - $packageInfo = '${{variables.packageInfos}}' | ConvertFrom-Json | Where-Object -Property packageName -EQ '${{packageName}}' - if ($null -eq $packageInfo) { - Write-Error 'Package information not found for ${{packageName}}' - } - - $packageVersions = '$(versionNumbers)' | ConvertFrom-Base64String | ConvertFrom-Json | Where-Object -Property PackageName -EQ -Value '${{packageName}}' - if ($null -eq $packageVersions) { - Write-Error 'Package versions not found for ${{packageName}}' - } - - # Restore original version numbers - [version]$nextPackageVersion = $packageVersions.PackageNextVersion - az devops configure -d organization=${env:ORGANIZATION_URL} - az pipelines variable-group variable update --group-id $packageInfo.variableGroupId --name next-major-number --project ${env:PROJECT_NAME} --value "$($nextPackageVersion.Major)" --verbose - az pipelines variable-group variable update --group-id $packageInfo.variableGroupId --name next-minor-number --project ${env:PROJECT_NAME} --value "$($nextPackageVersion.Minor)" --verbose - az pipelines variable-group variable update --group-id $packageInfo.variableGroupId --name next-patch-number --project ${env:PROJECT_NAME} --value "$($nextPackageVersion.Build)" --verbose - az pipelines variable-group variable update --group-id $packageInfo.variableGroupId --name next-preview-number --project ${env:PROJECT_NAME} --value "$($nextPackageVersion.Revision)" --verbose - - # Track packages that have been rolled back - $rolledBackPackages = "$(rolledBackPackageList)" -split ',' - $rolledBackPackages += $packageInfo.packageName - Write-Host "##vso[task.setvariable variable=rolledBackPackageList]$($rolledBackPackages -join ',')" - #arguments: # string. Alias: scriptArguments. Script Arguments. + # scriptLocation: 'scriptPath' # 'inlineScript' | 'scriptPath'. Required. Script Location. Default: scriptPath. + scriptPath: 'build/scripts/UpdatePipelineVersionNumber.ps1' # string. Required when scriptLocation = scriptPath. Script Path. + # inlineScript: string # string. Required when scriptLocation = inlineScript. Inline Script. + arguments: '-PackageName ''${{packageName}}'' -VersionNumberName PackageNextVersion -VariableNamePrefix next -OutputInformationPreference ''Continue'' -OutputVerbosePreference ${{iif(eq(parameters.enableVerboseOutput, ''true''), ''Continue'', ''SilentlyContinue'')}} -OutputDebugPreference ${{iif(eq(parameters.enableDebug, ''true''), ''Continue'', ''SilentlyContinue'')}} -TraceLevel ${{parameters.traceLevel}}' # string. Alias: scriptArguments. Script Arguments. #powerShellErrorActionPreference: 'stop' # 'stop' | 'continue' | 'silentlyContinue'. Optional. Use when scriptType = ps || scriptType = pscore. ErrorActionPreference. Default: stop. env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) @@ -1310,57 +854,17 @@ stages: and ( succeeded(), - gt(length(coalesce(variables['rolledBackPackageList'], '')), 0), - containsValue(split(variables['rolledBackPackageList'], ','), '${{packageName}}') + or(eq(variables['isDevelopBranch'], 'true'), and(gt(length(coalesce(variables.publicationRequiredPackageNames, '')), 0), gt(length(split(variables.publicationRequiredPackageNames, ',')), 0))), + or(and(gt(length(coalesce(variables.publicationRequiredPackageNames, '')), 0), containsValue(split(variables.publicationRequiredPackageNames, ','), '${{ packageName }}')), and(gt(length(coalesce(variables['changedPackageNames'], '')), 0), containsValue(split(variables['changedPackageNames'], ','), '${{ packageName }}'))), + and(eq(variables['currentNextMajor'], variables['originalNextMajor']), eq(variables['currentNextMinor'], variables['originalNextMinor']), eq(variables['currentNextPatch'], variables['originalNextPatch']), eq(variables['currentNextPreview'], variables['originalNextPreview'])) ) inputs: azureSubscription: $(SUBSCRIPTION_ID) # string. Alias: connectedServiceNameARM. Required. Azure Resource Manager connection. scriptType: 'pscore' # 'ps' | 'pscore' | 'batch' | 'bash'. Required. Script Type. - scriptLocation: 'inlineScript' # 'inlineScript' | 'scriptPath'. Required. Script Location. Default: scriptPath. - # scriptPath: # string. Required when scriptLocation = scriptPath. Script Path. - inlineScript: | # string. Required when scriptLocation = inlineScript. Inline Script. - Import-Module "$(Build.SourcesDirectory)/build/psmodules/CommonHelpers/CommonHelpers.psm1" -Force - - if (${{parameters.traceLevel}} -gt 0) { - Set-PSDebug -Trace ${{parameters.traceLevel}} - } - - # set environment variable for current process - $env:AZURE_DEVOPS_EXT_PAT = $env:SYSTEM_ACCESSTOKEN - - az devops configure -d organization=${env:ORGANIZATION_URL} project=${env:PROJECT_NAME} - az account set -s ${env:SUBSCRIPTION_ID} - - # Get package information. - $packageInfo = '${{variables.packageInfos}}' | ConvertFrom-Json | Where-Object -Property packageName -EQ -Value '${{packageName}}' - if ($null -eq $packageInfo) { - Write-Error 'Package information not found for ${{packageName}}' - } - - $packageVersions = '$(versionNumbers)' | ConvertFrom-Base64String | ConvertFrom-Json | Where-Object -Property PackageName -EQ -Value '${{packageName}}' - if ($null -eq $packageVersions) { - Write-Error 'Package versions not found for ${{packageName}}' - } - [version]$nextPackageVersion = $packageVersions.PackageNextVersion - - # Fetch next package version from pipeline. - $variableListOutput = & az pipelines variable-group variable list --group-id $packageInfo.variableGroupId - $variableGroupVersionNumbers = ($variableListOutput | ConvertFrom-Json).PSObject.Properties - | Where-Object { $_.Name.StartsWith('next') } - | Out-String -InputObject { $_.Name + ':' + $_.Value.value } -Stream - | Sort-Object - | ConvertFrom-Csv -Delimiter ':' -Header 'Name', 'Value' - | Out-String -InputObject { $_.Value } -Stream - [version] $currentPackageVersion = ($variableGroupVersionNumbers[0], $variableGroupVersionNumbers[1], $variableGroupVersionNumbers[2], $variableGroupVersionNumbers[3] -join '.') - - # Verify rollback was successful. - if ($currentPackageVersion -ne $nextPackageVersion) { - Write-Error "Failed to rollback package version for ${{packageName}} to $nextPackageVersion; actual version is $currentPackageVersion." - } - - [version]$oldPackageVersion = '$(currentNextMajor).$(currentNextMinor).$(currentNextPatch).$(currentNextPreview)' - Write-Information "Rolled back package $($packageInfo.packageName) next version from v$oldPackageVersion to v$currentPackageVersion." -InformationAction Continue - #arguments: # string. Alias: scriptArguments. Script Arguments. + # scriptLocation: 'scriptPath' # 'inlineScript' | 'scriptPath'. Required. Script Location. Default: scriptPath. + scriptPath: 'build/scripts/ConfirmVersionNumberRollback.ps1' # string. Required when scriptLocation = scriptPath. Script Path. + # inlineScript: string # string. Required when scriptLocation = inlineScript. Inline Script. + arguments: '-PackageName ''${{packageName}}'' -EncodedPackageVersions ''$(versionNumbers)'' -TraceLevel ${{parameters.traceLevel}}' # string. Alias: scriptArguments. Script Arguments. #powerShellErrorActionPreference: 'stop' # 'stop' | 'continue' | 'silentlyContinue'. Optional. Use when scriptType = ps || scriptType = pscore. ErrorActionPreference. Default: stop. env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) @@ -1379,7 +883,7 @@ stages: - template: /build/configure-git-user.yml - ${{ each packageName in split(variables.allPackageNames, ',') }}: - pwsh: | - Import-Module "$(Build.SourcesDirectory)/build/psmodules/CommonHelpers/CommonHelpers.psm1" -Force + Import-Module "$(Build.SourcesDirectory)/build/psmodules/CommonHelpers/CommonHelpers.psm1" -Force -Scope Local if (${{parameters.traceLevel}} -gt 0) { Set-PSDebug -Trace ${{parameters.traceLevel}} @@ -1424,41 +928,14 @@ stages: ( succeeded(), or(containsValue(split(variables.publicationRequiredPackageNames, ','), '${{packageName}}'), containsValue(split(variables['changedPackageNames'], ','), '${{packageName}}')) - ) + ) inputs: azureSubscription: $(SUBSCRIPTION_ID) # string. Alias: connectedServiceNameARM. Required. Azure Resource Manager connection. - scriptType: "pscore" # 'ps' | 'pscore' | 'batch' | 'bash'. Required. Script Type. - scriptLocation: "inlineScript" # 'inlineScript' | 'scriptPath'. Required. Script Location. Default: scriptPath. - # scriptPath: # string. Required when scriptLocation = scriptPath. Script Path. - inlineScript: | # string. Required when scriptLocation = inlineScript. Inline Script. - Import-Module "$(Build.SourcesDirectory)/build/psmodules/CommonHelpers/CommonHelpers.psm1" -Force - - if (${{parameters.traceLevel}} -gt 0) { - Set-PSDebug -Trace ${{parameters.traceLevel}} - } - - # set environment variable for current process - $env:AZURE_DEVOPS_EXT_PAT = $env:SYSTEM_ACCESSTOKEN - - # Extract updated version numbers - $packageInfo = '${{variables.packageInfos}}' | ConvertFrom-Json | Where-Object -Property packageName -EQ -Value '${{packageName}}' - if ($null -eq $packageInfo) { - Write-Error 'Package information not found for ${{packageName}}' - } - - $packageVersions = '$(versionNumbers)' | ConvertFrom-Base64String | ConvertFrom-Json | Where-Object -Property PackageName -EQ -Value '${{packageName}}' - if ($null -eq $packageVersions) { - Write-Error 'Package versions not found for ${{packageName}}' - } - - # Update version numbers in pipeline. - [version]$productionPackageVersion = $packageVersions.PackageProductionVersion - az devops configure -d organization=${env:ORGANIZATION_URL} - az pipelines variable-group variable update --group-id $packageInfo.variableGroupId --name current-major-number --project ${env:PROJECT_NAME} --value $productionPackageVersion.Major --verbose - az pipelines variable-group variable update --group-id $packageInfo.variableGroupId --name current-minor-number --project ${env:PROJECT_NAME} --value $productionPackageVersion.Minor --verbose - az pipelines variable-group variable update --group-id $packageInfo.variableGroupId --name current-patch-number --project ${env:PROJECT_NAME} --value $productionPackageVersion.Build --verbose - az pipelines variable-group variable update --group-id $packageInfo.variableGroupId --name current-preview-number --project ${env:PROJECT_NAME} --value $productionPackageVersion.Revision --verbose - #arguments: # string. Alias: scriptArguments. Script Arguments. + scriptType: 'pscore' # 'ps' | 'pscore' | 'batch' | 'bash'. Required. Script Type. + # scriptLocation: "scriptPath" # 'inlineScript' | 'scriptPath'. Required. Script Location. Default: scriptPath. + scriptPath: 'build/scripts/UpdatePipelineVersionNumber.ps1' # string. Required when scriptLocation = scriptPath. Script Path. + # inlineScript: string # string. Required when scriptLocation = inlineScript. Inline Script. + arguments: '-PackageName ''${{packageName}}'' -VersionNumberName PackageProductionVersion -VariableNamePrefix current -VersionPrereleaseLabelName PackageProductionPrereleaseLabel -OutputInformationPreference ''Continue'' -OutputVerbosePreference ${{iif(eq(parameters.enableVerboseOutput, ''true''), ''Continue'', ''SilentlyContinue'')}} -OutputDebugPreference ${{iif(eq(parameters.enableDebug, ''true''), ''Continue'', ''SilentlyContinue'')}} -TraceLevel ${{parameters.traceLevel}}' # string. Alias: scriptArguments. Script Arguments. #powerShellErrorActionPreference: 'stop' # 'stop' | 'continue' | 'silentlyContinue'. Optional. Use when scriptType = ps || scriptType = pscore. ErrorActionPreference. Default: stop. env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) @@ -1469,38 +946,75 @@ stages: ( succeeded(), or(containsValue(split(coalesce(variables.publicationRequiredPackageNames, ''), ','), '${{packageName}}'), containsValue(split(coalesce(variables['changedPackageNames'], ''), ','), '${{packageName}}')) - ) + ) inputs: azureSubscription: $(SUBSCRIPTION_ID) # string. Alias: connectedServiceNameARM. Required. Azure Resource Manager connection. scriptType: 'pscore' # 'ps' | 'pscore' | 'batch' | 'bash'. Required. Script Type. - scriptLocation: 'inlineScript' # 'inlineScript' | 'scriptPath'. Required. Script Location. Default: scriptPath. - # scriptPath: # string. Required when scriptLocation = scriptPath. Script Path. - inlineScript: | # string. Required when scriptLocation = inlineScript. Inline Script. - if (${{parameters.traceLevel}} -gt 0) { - Set-PSDebug -Trace ${{parameters.traceLevel}} - } + # scriptLocation: 'scriptPath' # 'inlineScript' | 'scriptPath'. Required. Script Location. Default: scriptPath. + scriptPath: 'build/scripts/ConfirmCurrentVersionNumber.ps1' # string. Required when scriptLocation = scriptPath. Script Path. + # inlineScript: string # string. Required when scriptLocation = inlineScript. Inline Script. + arguments: '-PackageName ''${{packageName}}'' -TraceLevel ${{parameters.traceLevel}}' # string. Alias: scriptArguments. Script Arguments. + #powerShellErrorActionPreference: 'stop' # 'stop' | 'continue' | 'silentlyContinue'. Optional. Use when scriptType = ps || scriptType = pscore. ErrorActionPreference. Default: stop. + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + - powershell: | # Required as first property. Inline PowerShell script. + Import-Module "$(Build.SourcesDirectory)/build/psmodules/CommonHelpers/CommonHelpers.psm1" -Force -Scope Local - # set environment variable for current process - $env:AZURE_DEVOPS_EXT_PAT = $env:SYSTEM_ACCESSTOKEN - - az devops configure -d organization=${env:ORGANIZATION_URL} project=${env:PROJECT_NAME} - az account set -s ${env:SUBSCRIPTION_ID} + if (${{parameters.traceLevel}} -gt 0) { + Set-PSDebug -Trace ${{parameters.traceLevel}} + } - $packageInfo = '${{variables.packageInfos}}' | ConvertFrom-Json | Where-Object -Property packageName -EQ '${{packageName}}' - if ($null -eq $packageInfo) { - Write-Error 'Package information not found for ${{packageName}}' - } + $packageVersions = ("$(versionNumbers)" | ConvertFrom-Base64String | ConvertFrom-Json) | Where-Object -Property PackageName -EQ -Value ${{packageName}} + if ($null -eq $packageVersions) { + Write-Error 'Package versions not found for ${{packageName}}' + } - $variableListOutput = & az pipelines variable-group variable list --group-id $packageInfo.variableGroupId - $variableGroupVersionNumbers = ($variableListOutput | ConvertFrom-Json).PSObject.Properties - | Where-Object { $_.Name.StartsWith('current') } - | Out-String -InputObject { $_.Name + ':' + $_.Value.value } -Stream - | Sort-Object - | ConvertFrom-Csv -Delimiter ':' -Header 'Name', 'Value' - | Out-String -InputObject { $_.Value } -Stream - [version] $packageVersionNumbers = ($variableGroupVersionNumbers[0], $variableGroupVersionNumbers[1], $variableGroupVersionNumbers[2], $variableGroupVersionNumbers[3] -join '.') - Write-Information "Updated package $($packageInfo.packageName) current version to v$($packageVersionNumbers.Major).$($packageVersionNumbers.Minor).$($packageVersionNumbers.Build).$($packageVersionNumbers.Revision)." -InformationAction Continue - #arguments: # string. Alias: scriptArguments. Script Arguments. + [version]$productionPackageVersion = $packageVersions.PackageProductionVersion + Write-Host "##vso[task.setvariable variable=productionPrereleaseNumberArg]$($productionPackageVersion.Revision)" + # errorActionPreference: string # Unless otherwise specified, the error action preference defaults to the value stop. See the following section for more information. + # failOnStderr: string # Fail the task if output is sent to Stderr? + # ignoreLASTEXITCODE: string # Check the final exit code of the script to determine whether the step succeeded? + # workingDirectory: string # Start the script with this working directory. + condition: | # Evaluate this condition expression to determine whether to run this task. + and + ( + succeeded(), + or(containsValue(split(coalesce(variables.publicationRequiredPackageNames, ''), ','), '${{packageName}}'), containsValue(split(coalesce(variables['changedPackageNames'], ''), ','), '${{packageName}}')) + ) + # continueOnError: boolean # Continue running even on failure? + displayName: '[${{packageName}}] Set production prerelease argument' # Human-readable name for the task. + # target: string | target # Environment in which to run this task. + # enabled: boolean # Run this task when the job runs? + # env: # Variables to map into the process's environment. + # string: string # Name/value pairs + # name: string # ID of the step. + # timeoutInMinutes: string # Time to wait for this task to complete before the server kills it. + # retryCountOnTaskFailure: string # Number of retries if the task fails. + # Azure CLI v2 + # Run Azure CLI commands against an Azure subscription in a PowerShell Core/Shell script when running on Linux agent or PowerShell/PowerShell Core/Batch script when running on Windows agent. + - task: AzureCLI@2 + condition: | # Evaluate this condition expression to determine whether to run this task. + and + ( + succeeded(), + or(containsValue(split(coalesce(variables.publicationRequiredPackageNames, ''), ','), '${{packageName}}'), containsValue(split(coalesce(variables['changedPackageNames'], ''), ','), '${{packageName}}')), + eq(0, variables['productionPrereleaseNumberArg']) + ) + displayName: '[${{packageName}}] Update stable version numbers' # Human-readable name for the task. + inputs: + azureSubscription: $(SUBSCRIPTION_ID) # string. Alias: connectedServiceNameARM. Required. Azure Resource Manager connection. + scriptType: 'pscore' # 'ps' | 'pscore' | 'batch' | 'bash'. Required. Script Type. + scriptLocation: 'scriptPath' # 'inlineScript' | 'scriptPath'. Required. Script Location. Default: scriptPath. + scriptPath: 'build/scripts/UpdatePipelineVersionNumber.ps1' # string. Required when scriptLocation = scriptPath. Script Path. + #inlineScript: # string. Required when scriptLocation = inlineScript. Inline Script. + arguments: '-PackageName ''${{packageName}}'' -VersionNumberName PackageProductionVersion -VariableNamePrefix stable -OutputInformationPreference ''Continue'' -OutputVerbosePreference ${{iif(eq(parameters.enableVerboseOutput, ''true''), ''Continue'', ''SilentlyContinue'')}} -OutputDebugPreference ${{iif(eq(parameters.enableDebug, ''true''), ''Continue'', ''SilentlyContinue'')}} -TraceLevel ${{parameters.traceLevel}}' # string. Alias: scriptArguments. Script Arguments. #powerShellErrorActionPreference: 'stop' # 'stop' | 'continue' | 'silentlyContinue'. Optional. Use when scriptType = ps || scriptType = pscore. ErrorActionPreference. Default: stop. + # Advanced + #addSpnToEnvironment: false # boolean. Access service principal details in script. Default: false. + #useGlobalConfig: false # boolean. Use global Azure CLI configuration. Default: false. + #workingDirectory: # string. Alias: cwd. Working Directory. + #failOnStandardError: false # boolean. Fail on Standard Error. Default: false. + #powerShellIgnoreLASTEXITCODE: false # boolean. Optional. Use when scriptType = ps || scriptType = pscore. Ignore $LASTEXITCODE. Default: false. + #visibleAzLogin: true # boolean. az login output visibility. Default: true. env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) \ No newline at end of file diff --git a/build/publication-create-packages-prepare.yml b/build/publication-create-packages-prepare.yml new file mode 100644 index 0000000..d3e4d38 --- /dev/null +++ b/build/publication-create-packages-prepare.yml @@ -0,0 +1,61 @@ +parameters: # expected parameters +- name: buildConfiguration + type: string +- name: buildSolution + type: string + +steps: +- task: MSBuild@1 + displayName: "Restore package dependencies" + inputs: + solution: ${{ parameters.buildSolution }} # Required # Relative path from repo root of the project(s) or solution(s) to run. Wildcards can be used. For example, `**/*.csproj` for all csproj files in all sub folders. + #msbuildLocationMethod: # Options: 'version', 'location' # Optional + #msbuildVersion: # Options: 'latest', '17.0', '16.0', '15.0', '14.0', '12.0', '4.0' # Optional # If the preferred version cannot be found, the latest version found will be used instead. On an macOS agent, xbuild (Mono) will be used if version is lower than 15.0. + #msbuildArchitecture: # Options: 'x86', 'x64' # Optional # Optionally supply the architecture (x86, x64) of MSBuild to run. + #msbuildLocation: # Optional # Optionally supply the path to MSBuild. + #platform: # Optional + configuration: ${{parameters.buildConfiguration}} # Optional + msbuildArguments: -t:restore # Optional # Additional arguments passed to MSBuild (on Windows) and xbuild (on macOS). + #clean: # Optional # Run a clean build (/t:clean) prior to the build. + #maximumCpuCount: # Optional # If your MSBuild target configuration is compatible with building in parallel, you can optionally check this input to pass the /m switch to MSBuild (Windows only). If your target configuration is not compatible with building in parallel, checking this option may cause your build to result in file-in-use errors, or intermittent or inconsistent build failures. + #restoreNugetPackages: # Optional # This option is deprecated. To restore NuGet packages, add a [NuGet](https://docs.microsoft.com/azure/devops/pipelines/tasks/package/nuget) task before the build. + #logProjectEvents: # Optional # Optionally record timeline details for each project (Windows only). + #createLogFile: # Optional # Optionally create a log file (Windows only). + #logFileVerbosity: # Options: 'quiet', 'minimal', 'normal', 'detailed', 'diagnostic' # Optional # Optional log file verbosity. +- task: DownloadBuildArtifacts@1 + inputs: + buildType: current # Options: 'current', 'specific' # Required # Download artifacts produced by the current build, or from a specific build. + # project: # Required when buildType == specific # The project from which to download the build artifacts + # definition: # Required when buildType == specific # Select the build pipeline name + #specificBuildWithTriggering: # Optional # If checked, this build task will try to download artifacts from the triggering build. If there is no triggering build from the specified pipeline, it will download artifacts from the build specified in the options below. + # buildVersionToDownload: latest # Options: 'latest', 'latestFromBranch', 'specific' # Required + #allowPartiallySucceededBuilds: # Optional # If checked, this build task will try to download artifacts whether the build is succeeded or partially succeeded. + # branchName: refs/heads/master # Required # Specify to filter on branch/ref name, for example: ```refs/heads/develop```. + # buildId: # Required when buildType == specific && buildVersionToDownload == specific # The build from which to download the artifacts + #tags: # Optional # A comma-delimited list of tags. Only builds with these tags will be returned. + downloadType: single # Options: 'single', 'specific' # Required # Download a specific artifact or specific files from the build. + artifactName: drop # Required when downloadType == single # The name of the artifact to download + #itemPattern: # Optional # Specify files to be downloaded as multi line minimatch pattern. [More Information](https://aka.ms/minimatchexamples)

The default pattern (//*//*) will download all files across all artifacts in the build if "Specific files" option is selected. To download all files within artifact drop use drop/**.

+ downloadPath: $(System.ArtifactsDirectory) # Required # Path on the agent machine where the artifacts will be downloaded + #cleanDestinationFolder: # Optional # Delete all existing files in destination folder before artifact download + #parallelizationLimit: # Optional # Number of files to download simultaneously + #checkDownloadedFiles: # Optional # If checked, this build task will check that all files are fully downloaded. + #retryDownloadCount: # Optional # Optional number of times to retry downloading a build artifact if the download fails. + #extractTars: # Optional # Enable this option to extract all downloaded files that have .tar extension. This is helpful because you need to pack your artifact files into tar if you want to preserve Unix file permissions. Enabling `StoreAsTar` option in PublishBuildArtifacts task will store artifacts as .tar files automatically. +- task: CopyFiles@2 + inputs: + SourceFolder: $(System.ArtifactsDirectory)/drop # Optional # The source folder that the copy pattern(s) will be run from. Empty is the root of the repo. Use [variables](https://go.microsoft.com/fwlink/?LinkID=550988) if files are not in the repo. Example: $(agent.builddirectory) + Contents: "src/**/bin/**/${{parameters.buildConfiguration}}/**" # Required # File paths to include as part of the copy. Supports multiple lines of match patterns. [More Information](https://go.microsoft.com/fwlink/?LinkID=708389) + TargetFolder: $(Build.SourcesDirectory) # Required # Target folder or UNC path files will copy to. You can use [variables](http://go.microsoft.com/fwlink/?LinkID=550988). Example: $(build.artifactstagingdirectory) + #CleanTargetFolder: # Optional # Delete all existing files in target folder before copy + OverWrite: true # Optional # Replace existing file in target folder + #flattenFolders: # Optional # Flatten the folder structure and copy all files into the specified target folder. + #preserveTimestamp: # Optional # Using the original source file, preserve the target file timestamp. + #retryCount: # Optional # Specify the retry count to copy the file. It might help to resolve intermittent issues e.g. with UNC target paths on a remote host. + #delayBetweenRetries: # Optional # Specify the delay between two retries. It might help to be more resilient to intermittent issues e.g. with UNC target paths on a remote host. + #ignoreMakeDirErrors: # Optional # Ignore errors which happen during creation of target folder. This could be useful to avoid issues with parallel execution of task by several agents with one target folder. +- task: NuGetToolInstaller@1 + displayName: "Install NuGet CLI" + # inputs: + #versionSpec: # Optional # A version or version range that specifies the NuGet version to make available on the path. Use x as a wildcard. See the [list of available NuGet versions](http://dist.nuget.org/tools.json).If you want to match a pre-release version, the specification must contain a major, minor, patch, and pre-release version from the list above.Examples: 4.x, 3.3.x, 2.8.6, >=4.0.0-0If unspecified, a version will be chosen automatically. + # checkLatest: false # Optional # Always check for and download the latest available version of NuGet.exe which satisfies the version spec.Enabling this option could cause unexpected build breaks when a new version of NuGet is released. \ No newline at end of file diff --git a/build/publication-publish-packages-job.yml b/build/publication-publish-packages-job.yml new file mode 100644 index 0000000..25158b4 --- /dev/null +++ b/build/publication-publish-packages-job.yml @@ -0,0 +1,63 @@ +parameters: # expected parameters +- name: buildConfiguration + type: string + +# File: templates/insert-jobs.yml +jobs: +- job: Publish_Packages + displayName: "Publish NuGet packages to private feed" + dependsOn: Create_Packages + variables: + BuildConfiguration: release + steps: + - checkout: none + - task: NuGetToolInstaller@1 + displayName: "Install NuGet CLI" + # inputs: + #versionSpec: # Optional # A version or version range that specifies the NuGet version to make available on the path. Use x as a wildcard. See the [list of available NuGet versions](http://dist.nuget.org/tools.json).If you want to match a pre-release version, the specification must contain a major, minor, patch, and pre-release version from the list above.Examples: 4.x, 3.3.x, 2.8.6, >=4.0.0-0If unspecified, a version will be chosen automatically. + # checkLatest: true # Optional # Always check for and download the latest available version of NuGet.exe which satisfies the version spec.Enabling this option could cause unexpected build breaks when a new version of NuGet is released. + # Configure NuGet tools to authenticate with Azure Artifacts and other NuGet repositories. Requires NuGet >= 4.8.5385, dotnet >= 6, or MSBuild >= 15.8.166.59604. + - task: NuGetAuthenticate@1 + # inputs: + # forceReinstallCredentialProvider: false # boolean. Reinstall the credential provider even if already installed. Default: false. + #nuGetServiceConnections: # string. Service connection credentials for feeds outside this organization. + - task: DownloadPipelineArtifact@2 + inputs: + buildType: "current" + artifactName: "packages" + itemPattern: "**/${{parameters.buildConfiguration}}/**/*" + targetPath: "$(System.ArtifactsDirectory)" + # Build, test, package, or publish a .NET application, or run a custom .NET CLI command. + - task: DotNetCoreCLI@2 + displayName: "Upload packages to package server" + inputs: + #azureSubscription: # string. Alias: ConnectedServiceName. Azure Resource Manager connection. + command: 'push' # 'build' | 'push' | 'pack' | 'publish' | 'restore' | 'run' | 'test' | 'custom'. Required. Command. Default: build. + #publishWebProjects: true # boolean. Optional. Use when command = publish. Publish web projects. Default: true. + #projects: # string. Optional. Use when command = build || command = restore || command = run || command = test || command = custom || publishWebProjects = false. Path to project(s) or solution(s). + #custom: # string. Required when command = custom. Custom command. + #arguments: # string. Optional. Use when command = build || command = publish || command = run || command = test || command = custom. Arguments. + #restoreArguments: # string. Optional. Use when command = restore. Arguments. + #publishTestResults: true # boolean. Optional. Use when command = test. Publish test results and code coverage. Default: true. + #testRunTitle: # string. Optional. Use when command = test. Test run title. + #zipAfterPublish: true # boolean. Optional. Use when command = publish. Zip published projects. Default: true. + #modifyOutputPath: true # boolean. Optional. Use when command = publish. Add project's folder name to publish path. Default: true. + packagesToPush: '$(System.ArtifactsDirectory)/**/*.nupkg' # string. Alias: searchPatternPush. Required when command = push. Path to NuGet package(s) to publish. Default: $(Build.ArtifactStagingDirectory)/*.nupkg. + nuGetFeedType: 'internal' # 'internal' | 'external'. Required when command = push. Target feed location. Default: internal. + publishVstsFeed: $(PACKAGE_FEED_ID) # string. Alias: feedPublish. Required when command = push && nuGetFeedType = internal. Target feed. + #publishFeedCredentials: # string. Alias: externalEndpoint. Required when command = push && nuGetFeedType = external. NuGet server. + #packagesToPack: '**/*.csproj' # string. Alias: searchPatternPack. Required when command = pack. Path to csproj or nuspec file(s) to pack. Default: **/*.csproj. + #configuration: '$(BuildConfiguration)' # string. Alias: configurationToPack. Optional. Use when command = pack. Configuration to Package. Default: $(BuildConfiguration). + #packDirectory: '$(Build.ArtifactStagingDirectory)' # string. Alias: outputDir. Optional. Use when command = pack. Package Folder. Default: $(Build.ArtifactStagingDirectory). + #nobuild: false # boolean. Optional. Use when command = pack. Do not build. Default: false. + #includesymbols: false # boolean. Optional. Use when command = pack. Include Symbols. Default: false. + #includesource: false # boolean. Optional. Use when command = pack. Include Source. Default: false. + #requestTimeout: '300000' # string. Set timeout for package download request. Default: 300000. + # Feeds and authentication + #feedsToUse: 'select' # 'select' | 'config'. Alias: selectOrConfig. Required when command = restore. Feeds to use. Default: select. + #vstsFeed: # string. Alias: feedRestore. Optional. Use when selectOrConfig = select && command = restore. Use packages from this Azure Artifacts feed. Select from the dropdown or enter [project name/]feed name. + #includeNuGetOrg: true # boolean. Optional. Use when selectOrConfig = select && command = restore. Use packages from NuGet.org. Default: true. + #nugetConfigPath: # string. Optional. Use when selectOrConfig = config && command = restore. Path to NuGet.config. + #externalFeedCredentials: # string. Alias: externalEndpoints. Optional. Use when selectOrConfig = config && command = restore. Credentials for feeds outside this organization/collection. + # Advanced + #publishPackageMetadata: true # boolean. Optional. Use when command = push && nuGetFeedType = internal. Publish pipeline metadata. Default: true. \ No newline at end of file diff --git a/build/qa-steps.yml b/build/qa-steps.yml new file mode 100644 index 0000000..e10e951 --- /dev/null +++ b/build/qa-steps.yml @@ -0,0 +1,90 @@ +parameters: # expected parameters +- name: packageName + type: string +- name: testAssemblySearchPattern + type: string +- name: buildPlatform + type: string +- name: buildConfiguration + type: string + +steps: +- task: DownloadBuildArtifacts@1 + displayName: '[${{parameters.packageName}}] Download build artifacts' + inputs: + buildType: 'current' # 'current' | 'specific'. Required. Download artifacts produced by. Default: current. + #project: # string. Required when buildType == specific. Project. + #pipeline: # string. Alias: definition. Required when buildType == specific. Build pipeline. + #specificBuildWithTriggering: false # boolean. Optional. Use when buildType == specific. When appropriate, download artifacts from the triggering build. Default: false. + buildVersionToDownload: 'latest' # 'latest' | 'latestFromBranch' | 'specific'. Required when buildType == specific. Build version to download. Default: latest. + #allowPartiallySucceededBuilds: false # boolean. Optional. Use when buildType == specific && buildVersionToDownload != specific. Download artifacts even from partially succeeded builds. Default: false. + branchName: $(Build.SourceBranch) # string. Required when buildType == specific && buildVersionToDownload == latestFromBranch. Branch name. Default: refs/heads/master. + #buildId: # string. Required when buildType == specific && buildVersionToDownload == specific. Build. + #tags: # string. Optional. Use when buildType == specific && buildVersionToDownload != specific. Build Tags. + downloadType: 'single' # 'single' | 'specific'. Required. Download type. Default: single. + artifactName: drop # string. Required when downloadType == single. Artifact name. + #itemPattern: '**' # string. Matching pattern. Default: **. + downloadPath: '$(Pipeline.Workspace)' # string. Required. Destination directory. Default: $(System.ArtifactsDirectory). + #cleanDestinationFolder: false # boolean. Clean destination folder. Default: false. + # Advanced + #parallelizationLimit: '8' # string. Parallelization limit. Default: 8. + #checkDownloadedFiles: false # boolean. Check downloaded files. Default: false. + #retryDownloadCount: '4' # string. Retry count. Default: 4. + #extractTars: # boolean. Extract all files that are stored inside tar archives. +- task: CopyFiles@2 + displayName: '[${{parameters.packageName}}] Copy files to working area' + inputs: + SourceFolder: $(Pipeline.Workspace)\drop # string. Source Folder. + Contents: '**' # string. Required. Contents. Default: **. + TargetFolder: $(System.DefaultWorkingDirectory) # string. Required. Target Folder. + # Advanced + #CleanTargetFolder: false # boolean. Clean Target Folder. Default: false. + #OverWrite: false # boolean. Overwrite. Default: false. + #flattenFolders: false # boolean. Flatten Folders. Default: false. + #preserveTimestamp: false # boolean. Preserve Target Timestamp. Default: false. + #retryCount: '0' # string. Retry count to copy the file. Default: 0. + #delayBetweenRetries: '1000' # string. Delay between two retries. Default: 1000. + #ignoreMakeDirErrors: false # boolean. Ignore errors during creation of target folder. Default: false. +- task: VSTest@3 + displayName: '[${{parameters.packageName}}] Run automated tests' + inputs: + #azureSubscription: # string. Alias: ConnectedServiceName. Azure Resource Manager connection. + # Test selection + testSelector: 'testAssemblies' # 'testAssemblies' | 'testPlan' | 'testRun'. Required. Select tests using. Default: testAssemblies. + testAssemblyVer2: ${{ parameters.testAssemblySearchPattern }} # string. Required when testSelector = testAssemblies. Test files. + #testPlan: # string. Required when testSelector = testPlan. Test plan. + #testSuite: # string. Required when testSelector = testPlan. Test suite. + #testConfiguration: # string. Required when testSelector = testPlan. Test configuration. + #tcmTestRun: '$(test.RunId)' # string. Optional. Use when testSelector = testRun. Test Run. Default: $(test.RunId). + searchFolder: '$(System.DefaultWorkingDirectory)' # string. Required. Search folder. Default: $(System.DefaultWorkingDirectory). + #resultsFolder: '$(Agent.TempDirectory)\TestResults' # string. Test results folder. Default: $(Agent.TempDirectory)\TestResults. + #testFiltercriteria: # string. Optional. Use when testSelector = testAssemblies. Test filter criteria. + #runOnlyImpactedTests: False # boolean. Optional. Use when testSelector = testAssemblies. Run only impacted tests. Default: False. + #runAllTestsAfterXBuilds: '50' # string. Optional. Use when testSelector = testAssemblies && runOnlyImpactedTests = true. Number of builds after which all tests should be run. Default: 50. + #uiTests: false # boolean. Test mix contains UI tests. Default: false. + # Execution options + #vstestLocationMethod: 'version' # 'version' | 'location'. Select test platform using. Default: version. + #vsTestVersion: 'latest' # 'latest' | '17.0' | '16.0' | '15.0' | '14.0' | 'toolsInstaller'. Optional. Use when vstestLocationMethod = version. Test platform version. Default: latest. + #vstestLocation: # string. Optional. Use when vstestLocationMethod = location. Path to vstest.console.exe. + #runSettingsFile: # string. Settings file. + #overrideTestrunParameters: # string. Override test run parameters. + #pathtoCustomTestAdapters: # string. Path to custom test adapters. + #runInParallel: False # boolean. Run tests in parallel on multi-core machines. Default: False. + #runTestsInIsolation: False # boolean. Run tests in isolation. Default: False. + #codeCoverageEnabled: False # boolean. Code coverage enabled. Default: False. + #otherConsoleOptions: # string. Other console options. + #diagnosticsEnabled: false # boolean. Collect advanced diagnostics in case of catastrophic failures. Default: false. + #collectDumpOn: 'onAbortOnly' # 'onAbortOnly' | 'always' | 'never'. Optional. Use when diagnosticsEnabled = true. Collect process dump and attach to test run report. Default: onAbortOnly. + #rerunFailedTests: False # boolean. Rerun failed tests. Default: False. + #rerunType: 'basedOnTestFailurePercentage' # 'basedOnTestFailurePercentage' | 'basedOnTestFailureCount'. Optional. Use when rerunFailedTests = true. Do not rerun if test failures exceed specified threshold. Default: basedOnTestFailurePercentage. + #rerunFailedThreshold: '30' # string. Optional. Use when rerunFailedTests = true && rerunType = basedOnTestFailurePercentage. % failure. Default: 30. + #rerunFailedTestCasesMaxLimit: '5' # string. Optional. Use when rerunFailedTests = true && rerunType = basedOnTestFailureCount. # of failed tests. Default: 5. + #rerunMaxAttempts: '3' # string. Optional. Use when rerunFailedTests = true. Maximum # of attempts. Default: 3. + # Reporting options + #testRunTitle: # string. Test run title. + platform: ${{parameters.buildPlatform}} # string. Build platform. + configuration: ${{parameters.buildConfiguration}} # string. Build configuration. + #publishRunAttachments: true # boolean. Upload test attachments. Default: true. + #donotPublishTestResults: false # boolean. Optional. Use when runInParallel = false. Disable publishing test results. Default: false. + failOnMinTestsNotRun: true # boolean. Fail the task if a minimum number of tests are not run. Default: False. + #minimumExpectedTests: '1' # string. Optional. Use when failOnMinTestsNotRun = true. Minimum # of tests. Default: 1. \ No newline at end of file diff --git a/build/scripts/ConfirmCurrentVersionNumber.ps1 b/build/scripts/ConfirmCurrentVersionNumber.ps1 new file mode 100644 index 0000000..8140bea --- /dev/null +++ b/build/scripts/ConfirmCurrentVersionNumber.ps1 @@ -0,0 +1,34 @@ +param ( + [Parameter(Mandatory)] + [ValidateNotNullOrEmpty()] + [string] $PackageName, + + [Parameter()] + [int] $TraceLevel = 0 +) + +if (0 -lt $TraceLevel) { + Set-PSDebug -Trace $TraceLevel +} + +# set environment variable for current process +$env:AZURE_DEVOPS_EXT_PAT = $env:SYSTEM_ACCESSTOKEN + +az devops configure -d organization=${env:ORGANIZATION_URL} project=${env:PROJECT_NAME} +az account set -s ${env:SUBSCRIPTION_ID} + +$packageInfo = $env:PACKAGEINFOS | ConvertFrom-Json | Where-Object -Property packageName -EQ -Value $PackageName +if ($null -eq $packageInfo) { + Write-Error "Package information not found for $PackageName." +} + +$variableListOutput = & az pipelines variable-group variable list --group-id $packageInfo.variableGroupId +$variableGroupVersionNumbers = ($variableListOutput | ConvertFrom-Json).PSObject.Properties | +Where-Object { $_.Name.StartsWith('current') -and $_.Name.EndsWith('number') } | +Out-String -InputObject { $_.Name + ':' + $_.Value.value } -Stream | +Sort-Object | +ConvertFrom-Csv -Delimiter ':' -Header 'Name', 'Value' | +Out-String -InputObject { $_.Value } -Stream +[version] $packageVersionNumbers = ($variableGroupVersionNumbers[0], $variableGroupVersionNumbers[1], $variableGroupVersionNumbers[2], $variableGroupVersionNumbers[3] -join '.') + +Write-Information "Updated package $($packageInfo.packageName) current version to v$packageVersionNumbers." -InformationAction Continue \ No newline at end of file diff --git a/build/scripts/ConfirmVersionNumberRollback.ps1 b/build/scripts/ConfirmVersionNumberRollback.ps1 new file mode 100644 index 0000000..20afa2f --- /dev/null +++ b/build/scripts/ConfirmVersionNumberRollback.ps1 @@ -0,0 +1,57 @@ +#Requires -Version 3.0 + +param ( + [Parameter(Mandatory)] + [ValidateNotNullOrEmpty()] + [string] $PackageName, + + [Parameter(Mandatory)] + [ValidateNotNullOrEmpty()] + [string] $EncodedPackageVersions, + + [Parameter()] + [int] $TraceLevel = 0 +) + +$modulePath = Join-Path $PSScriptRoot "../psmodules/CommonHelpers/CommonHelpers.psm1" +Import-Module $modulePath -Force -Scope Local + +if (0 -lt $TraceLevel) { + Set-PSDebug -Trace $TraceLevel +} + +# set environment variable for current process +$env:AZURE_DEVOPS_EXT_PAT = $env:SYSTEM_ACCESSTOKEN + +az devops configure -d organization=${env:ORGANIZATION_URL} project=${env:PROJECT_NAME} +az account set -s ${env:SUBSCRIPTION_ID} + +# Get package information. +$packageInfo = $env:PACKAGEINFOS | ConvertFrom-Json | Where-Object -Property packageName -EQ -Value $PackageName +if ($null -eq $packageInfo) { + Write-Error "Package information not found for $PackageName." +} + +$packageVersions = $EncodedPackageVersions | ConvertFrom-Base64String | ConvertFrom-Json | Where-Object -Property PackageName -EQ -Value '${{packageName}}' +if ($null -eq $packageVersions) { + Write-Error "Package versions not found for $PackageName." +} +[version]$nextPackageVersion = $packageVersions.PackageNextVersion + +# Fetch next package version from pipeline. +$variableListOutput = & az pipelines variable-group variable list --group-id $packageInfo.variableGroupId +$variableGroupVersionNumbers = ($variableListOutput | ConvertFrom-Json).PSObject.Properties | +Where-Object { $_.Name.StartsWith('next') -and $_.Name.EndsWith('number') } | +Out-String -InputObject { $_.Name + ':' + $_.Value.value } -Stream | +Sort-Object | +ConvertFrom-Csv -Delimiter ':' -Header 'Name', 'Value' | +Out-String -InputObject { $_.Value } -Stream +[version] $currentPackageVersion = ($variableGroupVersionNumbers[0], $variableGroupVersionNumbers[1], $variableGroupVersionNumbers[2], $variableGroupVersionNumbers[3] -join '.') + +# Verify rollback was successful. +if ($currentPackageVersion -ne $nextPackageVersion) { + Write-Error "Failed to rollback package version for $PackageName to $nextPackageVersion; actual version is $currentPackageVersion." +} + +[version]$oldPackageVersion = '$(currentNextMajor).$(currentNextMinor).$(currentNextPatch).$(currentNextPreview)' +Write-Information "Rolled back package $($packageInfo.packageName) next version from v$oldPackageVersion to v$currentPackageVersion." -InformationAction Continue \ No newline at end of file diff --git a/build/scripts/DeclareOptionalVersionNumbers.ps1 b/build/scripts/DeclareOptionalVersionNumbers.ps1 index 539404c..da1711f 100644 --- a/build/scripts/DeclareOptionalVersionNumbers.ps1 +++ b/build/scripts/DeclareOptionalVersionNumbers.ps1 @@ -1,18 +1,16 @@ +#Requires -Version 3.0 + param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $PackageName, - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $SourceBranch, - [Parameter()] [int] $TraceLevel = 0 ) $modulePath = Join-Path $PSScriptRoot "../psmodules/CommonHelpers/CommonHelpers.psm1" -Import-Module $modulePath -Force +Import-Module $modulePath -Force -Scope Local if (0 -lt $TraceLevel) { Set-PSDebug -Trace $TraceLevel @@ -38,7 +36,7 @@ $productionMajorNumber = $nextPackageVersion.Major $productionMinorNumber = $nextPackageVersion.Minor $productionBuildNumber = $nextPackageVersion.Build $productionRevisionNumber = [System.Math]::Max($nextPackageVersion.Revision, 1) -if ($SourceBranch -eq 'refs/heads/master') { +if ($env:BUILD_SOURCEBRANCH -eq 'refs/heads/master') { $productionRevisionNumber = 0 } [version]$productionPackageVersion = ($productionMajorNumber, $productionMinorNumber, $productionBuildNumber, $productionRevisionNumber -join '.') @@ -48,16 +46,17 @@ Write-Information "Production package version number will be $productionPackageV $productionPackageVersionString = $productionPackageVersion.Major, $productionPackageVersion.Minor, $productionPackageVersion.Build -join '.' if ($productionPackageVersion.Revision -gt 0) { - $productionPackageVersionString += "-preview.$($productionPackageVersion.Revision)" + $productionPackageVersionString += "-$($packageVersions.PackageNextPrereleaseLabel).$($productionPackageVersion.Revision)" } $packageVersions.PackageProductionVersionString = $productionPackageVersionString +$packageVersions.PackageProductionPrereleaseLabel = $packageVersions.PackageNextPrereleaseLabel Write-Information "Production package version will be $productionPackageVersionString." # Calculate post-production package version number. $postProductionNumbers = $productionPackageVersion.Major, $productionPackageVersion.Minor, $productionPackageVersion.Build, $productionPackageVersion.Revision $incrementFromIndex = $postProductionNumbers.Count - 1 # default to incrementing the preview number -if ($SourceBranch -eq 'refs/heads/master') { +if ($env:BUILD_SOURCEBRANCH -eq 'refs/heads/master') { $incrementFromIndex = 1 # increment minor number } for ($versionPartIndex = $incrementFromIndex; $versionPartIndex -lt $postProductionNumbers.Count; $versionPartIndex++) { diff --git a/build/scripts/DeclareRequiredVersionNumbers.ps1 b/build/scripts/DeclareRequiredVersionNumbers.ps1 index e358456..13b1dd3 100644 --- a/build/scripts/DeclareRequiredVersionNumbers.ps1 +++ b/build/scripts/DeclareRequiredVersionNumbers.ps1 @@ -5,29 +5,31 @@ param ( [ValidateNotNullOrEmpty()] [string] $PackageName, - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $PackageInfos, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $TempPath, - [Parameter()] + [ValidateNotNullOrEmpty()] [string] $OutputInformationPreference = 'SilentlyContinue', [Parameter()] + [ValidateNotNullOrEmpty()] [string] $OutputVerbosePreference = 'SilentlyContinue', [Parameter()] + [ValidateNotNullOrEmpty()] [string] $OutputDebugPreference = 'SilentlyContinue', [Parameter()] [int] $TraceLevel = 0 ) +# Install from PowerShell Gallery +Set-PSRepository -Name PSGallery -InstallationPolicy Trusted +Install-Module -Name ConvertFrom-StringTable -Scope CurrentUser + +# Import the module into your session +Import-Module ConvertFrom-StringTable -Scope Local + $modulePath = Join-Path $PSScriptRoot "../psmodules/CommonHelpers/CommonHelpers.psm1" -Import-Module $modulePath -Force +Import-Module $modulePath -Force -Scope Local if (0 -lt $TraceLevel) { Set-PSDebug -Trace $TraceLevel @@ -44,45 +46,52 @@ az devops configure -d organization=${env:ORGANIZATION_URL} project=${env:PROJEC az account set -s ${env:SUBSCRIPTION_ID} # Extract package metadata. -$packageInfo = $PackageInfos | ConvertFrom-Json | Where-Object -Property packageName -EQ "$PackageName" +$packageInfo = $env:PACKAGEINFOS | ConvertFrom-Json | Where-Object -Property packageName -EQ "$PackageName" if ($null -eq $packageInfo) { Write-Error "Package information not found for $PackageName." } Write-Information "Found information for package $PackageName." +# Download variables from pipeline. +$variableListOutput = & az pipelines variable-group variable list --group-id $packageInfo.variableGroupId --output table +$packageVersions = $variableListOutput | ConvertFrom-StringTable + +# Fetch stable package version number. +$variableGroupVersionNumbers = $packageVersions | +Where-Object { $_.Name.StartsWith('stable') -and $_.Name.EndsWith('number') } | +Sort-Object -Property Name | +Select-Object -ExpandProperty Value +[version]$stablePackageVersion = ($variableGroupVersionNumbers[0], $variableGroupVersionNumbers[1], $variableGroupVersionNumbers[2] -join '.') + # Fetch current package version number. -$variableListOutput = & az pipelines variable-group variable list --group-id $packageInfo.variableGroupId -$variableGroupVersionNumbers = ($variableListOutput | ConvertFrom-Json).PSObject.Properties | -Where-Object { $_.Name.StartsWith('current') } | -Out-String -InputObject { $_.Name + ':' + $_.Value.value } -Stream | -Sort-Object | -ConvertFrom-Csv -Delimiter ':' -Header 'Name', 'Value' | -Out-String -InputObject { $_.Value } -Stream +$variableGroupVersionNumbers = $packageVersions | +Where-Object { $_.Name.StartsWith('current') -and $_.Name.EndsWith('number') } | +Sort-Object -Property Name | +Select-Object -ExpandProperty Value [version] $currentPackageVersion = ($variableGroupVersionNumbers[0], $variableGroupVersionNumbers[1], $variableGroupVersionNumbers[2], $variableGroupVersionNumbers[3] -join '.') +$currentPackagePrereleaseLabel = $packageVersions | Where-Object -Property Name -EQ -Value 'current-prerelease-label' | Select-Object -ExpandProperty Value $currentPackageVersionString = $currentPackageVersion.Major, $currentPackageVersion.Minor, $currentPackageVersion.Build -join '.' if ($currentPackageVersion.Revision -gt 0) { - $currentPackageVersionString += "-preview.$($currentPackageVersion.Revision)" + $currentPackageVersionString += "-$currentPackagePrereleaseLabel.$($currentPackageVersion.Revision)" } # Fetch next package version number. -$variableListOutput = & az pipelines variable-group variable list --group-id $packageInfo.variableGroupId -$variableGroupVersionNumbers = ($variableListOutput | ConvertFrom-Json).PSObject.Properties | -Where-Object { $_.Name.StartsWith('next') } | -Out-String -InputObject { $_.Name + ':' + $_.Value.value } -Stream | -Sort-Object | -ConvertFrom-Csv -Delimiter ':' -Header 'Name', 'Value' | -Out-String -InputObject { $_.Value } -Stream +$variableGroupVersionNumbers = $packageVersions | +Where-Object { $_.Name.StartsWith('next') -and $_.Name.EndsWith('number') } | +Sort-Object -Property Name | +Select-Object -ExpandProperty Value [version] $nextPackageVersion = ($variableGroupVersionNumbers[0], $variableGroupVersionNumbers[1], $variableGroupVersionNumbers[2], $variableGroupVersionNumbers[3] -join '.') +$nextPackagePrereleaseLabel = $packageVersions | Where-Object -Property Name -EQ -Value 'next-prerelease-label' | Select-Object -ExpandProperty Value # Fetch current version numbers from assembly. [version]$currentAssemblyVersion = $null; [version]$currentFileVersion = $null; [version]$currentInformationalVersion = $null -nuget install $PackageName -DependencyVersion Ignore -DirectDownload -ExcludeVersion -NoHttpCache -NonInteractive -OutputDirectory $TempPath -PackageSaveMode nupkg -PreRelease -Source 'https://pkgs.dev.azure.com/solobyte/DataStandardizer/_packaging/DataStandardizer/nuget/v3/index.json' -Source 'https://api.nuget.org/v3/index.json' -Verbosity detailed -Version $currentPackageVersionString 2>&1 | Write-Host +nuget install $PackageName -DependencyVersion Ignore -DirectDownload -ExcludeVersion -NoHttpCache -NonInteractive -OutputDirectory $env:AGENT_TEMPDIRECTORY -PackageSaveMode nupkg -PreRelease -Source 'https://pkgs.dev.azure.com/solobyte/DataStandardizer/_packaging/DataStandardizer/nuget/v3/index.json' -Source 'https://api.nuget.org/v3/index.json' -Verbosity detailed -Version $currentPackageVersionString 2>&1 | Write-Host [string]$currentPackageFolderPath -$currentPackageArchivePath = Get-ChildItem -Path $TempPath -Filter "$PackageName.nupkg" -Recurse | Select-Object -ExpandProperty FullName +$currentPackageArchivePath = Get-ChildItem -Path $env:AGENT_TEMPDIRECTORY -Filter "$PackageName.nupkg" -Recurse | Select-Object -ExpandProperty FullName if ((-not [string]::IsNullOrEmpty($currentPackageArchivePath)) -and (Test-Path $currentPackageArchivePath -PathType Leaf)) { Write-Verbose "Found $PackageName package file at $currentPackageArchivePath." @@ -126,18 +135,25 @@ if ($null -ne $currentAssemblyVersion -and ($currentAssemblyVersion.Major -ne $c # Add package version numbers to list. $packageVersions = [PSCustomObject]@{ PackageName = $PackageName + PackageStableVersion = $stablePackageVersion.ToString() PackageCurrentVersion = $currentPackageVersion.ToString() + PackageCurrentPrereleaseLabel = $currentPackagePrereleaseLabel PackageNextVersion = $nextPackageVersion.ToString() + PackageNextPrereleaseLabel = $nextPackagePrereleaseLabel PackageProductionVersion = $currentPackageVersion.ToString() PackageProductionVersionString = $currentPackageVersionString + PackageProductionPrereleaseLabel = $currentPackagePrereleaseLabel AssemblyProductionVersion = ${currentAssemblyVersion}?.ToString() AssemblyProductionFileVersion = ${currentFileVersion}?.ToString() AssemblyProductionInformationalVersion = ${currentInformationalVersion}?.ToString() } +Write-Information "Stable package version number is $stablePackageVersion." Write-Information "Current package version number is $currentPackageVersion." Write-Information "Current package version is $currentPackageVersionString." +Write-Information "Current package pre-release label is $currentPackagePrereleaseLabel." Write-Information "Next package version number will be $nextPackageVersion." +Write-Information "Next package pre-release label is $nextPackagePrereleaseLabel." Write-Information "Current assembly version number is $($currentAssemblyVersion ?? 'unknown')." Write-Information "Current assembly file version number is $($currentFileVersion ?? 'unknown')." Write-Information "Current assembly informational version is $($currentInformationalVersion ?? 'unknown')." diff --git a/build/scripts/FindChangedPackages.ps1 b/build/scripts/FindChangedPackages.ps1 index 88d6b27..c10a297 100644 --- a/build/scripts/FindChangedPackages.ps1 +++ b/build/scripts/FindChangedPackages.ps1 @@ -1,14 +1,6 @@ #Requires -Version 7.0 param ( - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $PackageList, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $SourceCommitHash, - [Parameter()] [int] $TraceLevel = 0 ) @@ -44,14 +36,14 @@ if (0 -lt $TraceLevel) { # Get list of changed files since most recent build on current branch. $changedPackages = @() -$PackageList | +$env:PACKAGEINFOS | ConvertFrom-Json | ForEach-Object { Write-Verbose "Checking for changes made to package $($_.packageName)" [string] $diffFilesOutput $packageMatchPattern = "v*$($_.packageName)" - $tagsOutput = & git tag --list $packageMatchPattern --sort=-version:refname --merged $SourceCommitHash + $tagsOutput = & git tag --list $packageMatchPattern --sort=-version:refname --merged $env:BUILD_SOURCEVERSION # $latestTagName = & git for-each-ref refs/tags --sort=-taggerdate --format='%(refname:short)' --count=1 --points-at=HEAD # $latestTagName = & git describe --tags --abbrev=0 --match $packageMatchPattern $SourceCommitHash $latestReleaseTagName = $tagsOutput -split '\r?\n' | Select-String -Pattern "^v\d+\.\d+\.\d+-$($_.packageName)$" | Select-Object -First 1 -ExpandProperty Matches | Select-Object -First 1 -ExpandProperty Value @@ -61,15 +53,15 @@ $PackageList | Write-Debug "Found most recent project tag $latestTagName." $tagRefName = "tags/$latestTagName" - Write-Debug "Getting file differences between $tagRefName and $SourceCommitHash." - $diffFilesOutput = & git diff --name-only $tagRefName $SourceCommitHash + Write-Debug "Getting file differences between $tagRefName and $env:BUILD_SOURCEVERSION." + $diffFilesOutput = & git diff --name-only $tagRefName $env:BUILD_SOURCEVERSION } else { Write-Debug 'Failed to find standard differences; using all differences instead.' $firstCommitHash = & git log --format="%H" --no-abbrev-commit | tail -1 - Write-Debug "Getting file differences between $firstCommitHash and $SourceCommitHash." - $diffFilesOutput = & git diff --name-only $firstCommitHash $SourceCommitHash + Write-Debug "Getting file differences between $firstCommitHash and $env:BUILD_SOURCEVERSION." + $diffFilesOutput = & git diff --name-only $firstCommitHash $env:BUILD_SOURCEVERSION } $changedFiles = (-not [string]::IsNullOrEmpty($diffFilesOutput))? $diffFilesOutput.Trim() -split '\r?\n':@() @@ -88,7 +80,7 @@ $PackageList | } } -Write-Host "##vso[task.setvariable variable=changedPackageNames;isOutput=true]$($changedPackages -join ',')" +Write-Host "##vso[task.setvariable variable=changedPackageNamesList]$($changedPackages -join ',')" if ($changedPackages.Count -gt 0) { Write-Information "Detected $($changedPackages.Count) changed package$(($changedPackages.Count -eq 1) ? '' : 's')." @@ -97,13 +89,6 @@ else { Write-Information "No package changes were detected." } -$changedPackagesMessage = [string]::Empty $changedPackages | ForEach-Object { - if (-not [string]::IsNullOrEmpty($_)) { - $changedPackagesMessage += [System.Environment]::NewLine - } - $changedPackagesMessage += "-`t$($_)" -} -if (-not [string]::IsNullOrEmpty($changedPackagesMessage)) { - Write-Verbose $changedPackagesMessage + Write-Verbose "-`t$($_)" } \ No newline at end of file diff --git a/build/scripts/FindTestPackages.ps1 b/build/scripts/FindTestPackages.ps1 index 57266cd..f36a86c 100644 --- a/build/scripts/FindTestPackages.ps1 +++ b/build/scripts/FindTestPackages.ps1 @@ -1,10 +1,6 @@ #Requires -Version 7.4 param ( - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $PackageInfos, - [Parameter()] [int] $TraceLevel = 0 ) @@ -13,7 +9,7 @@ if (0 -lt $TraceLevel) { Set-PSDebug -Trace $TraceLevel } -$testPackageNames = $PackageInfos | +$testPackageNames = $env:PACKAGEINFOS | ConvertFrom-Json | Where-Object -Property enableTests -NE -Value 0 | Select-Object -ExpandProperty packageName @@ -27,13 +23,6 @@ else { Write-Information 'No test packages were detected.' } -$testPackageNamesMessage = [string]::Empty $testPackageNames | ForEach-Object { - if (-not [string]::IsNullOrEmpty($_)) { - $testPackageNames += [System.Environment]::NewLine - } - $testPackageNames += "-`t$($_)" -} -if (-not [string]::IsNullOrEmpty($testPackageNamesMessage)) { - Write-Verbose $testPackageNamesMessage + Write-Verbose "-`t$($_)" } \ No newline at end of file diff --git a/build/scripts/OutputVersionVars.ps1 b/build/scripts/OutputVersionVars.ps1 index ea1767f..7f7783f 100644 --- a/build/scripts/OutputVersionVars.ps1 +++ b/build/scripts/OutputVersionVars.ps1 @@ -1,10 +1,12 @@ +#Requires -Version 3.0 + param ( [Parameter()] [int] $TraceLevel = 0 ) $modulePath = Join-Path $PSScriptRoot "../psmodules/CommonHelpers/CommonHelpers.psm1" -Import-Module $modulePath -Force +Import-Module $modulePath -Force -Scope Local if (0 -lt $TraceLevel) { Set-PSDebug -Trace $TraceLevel diff --git a/build/scripts/ReserveProductionVersionNumbers.ps1 b/build/scripts/ReserveProductionVersionNumbers.ps1 deleted file mode 100644 index c08f9c0..0000000 --- a/build/scripts/ReserveProductionVersionNumbers.ps1 +++ /dev/null @@ -1,44 +0,0 @@ -param ( - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $PackageName, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $PackageInfos, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $EncodedPackageVersions, - - [Parameter()] - [int] $TraceLevel = 0 -) - -$modulePath = Join-Path $PSScriptRoot "../psmodules/CommonHelpers/CommonHelpers.psm1" -Import-Module $modulePath -Force - -if (0 -lt $TraceLevel) { - Set-PSDebug -Trace $TraceLevel -} - -# Set environment variable for current process. -$env:AZURE_DEVOPS_EXT_PAT = $env:SYSTEM_ACCESSTOKEN - -# Get information about the current package. -$packageInfo = $PackageInfos | ConvertFrom-Json | Where-Object -Property packageName -EQ -Value $PackageName -if ($null -eq $packageInfo) { - Write-Error "Package information for $PackageName not found." -} - -# Update version numbers in pipeline. -$packageVersions = $EncodedPackageVersions | ConvertFrom-Base64String | ConvertFrom-Json | Where-Object -Property PackageName -EQ -Value $PackageName -[version]$postProductionPackageVersion = $packageVersions.PackagePostProductionVersion - -az devops configure -d organization=${env:ORGANIZATION_URL} -az pipelines variable-group variable update --group-id $packageInfo.variableGroupId --name next-major-number --project ${env:PROJECT_NAME} --value $postProductionPackageVersion.Major --verbose -az pipelines variable-group variable update --group-id $packageInfo.variableGroupId --name next-minor-number --project ${env:PROJECT_NAME} --value $postProductionPackageVersion.Minor --verbose -az pipelines variable-group variable update --group-id $packageInfo.variableGroupId --name next-patch-number --project ${env:PROJECT_NAME} --value $postProductionPackageVersion.Build --verbose -az pipelines variable-group variable update --group-id $packageInfo.variableGroupId --name next-preview-number --project ${env:PROJECT_NAME} --value $postProductionPackageVersion.Revision --verbose - -Write-Information "Reserved package version $postProductionPackageVersion." -InformationAction Continue \ No newline at end of file diff --git a/build/scripts/SetBuildTemplateArguments.ps1 b/build/scripts/SetBuildTemplateArguments.ps1 index c2672fc..48afc25 100644 --- a/build/scripts/SetBuildTemplateArguments.ps1 +++ b/build/scripts/SetBuildTemplateArguments.ps1 @@ -1,12 +1,10 @@ +#Requires -Version 3.0 + param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $PackageName, - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $PackageInfos, - [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$EncodedPackageVersions, @@ -16,14 +14,14 @@ param ( ) $modulePath = Join-Path $PSScriptRoot "../psmodules/CommonHelpers/CommonHelpers.psm1" -Import-Module $modulePath -Force +Import-Module $modulePath -Force -Scope Local if (0 -lt $TraceLevel) { Set-PSDebug -Trace $TraceLevel } # Set package Source Folder Path argument. -$packageInfo = $PackageInfos | ConvertFrom-Json | Where-Object -Property packageName -EQ $PackageName +$packageInfo = $env:PACKAGEINFOS | ConvertFrom-Json | Where-Object -Property packageName -EQ $PackageName if ($null -eq $packageInfo) { Write-Error "No package information found for $PackageName." exit diff --git a/build/scripts/SetReleaseNotesArgument.ps1 b/build/scripts/SetReleaseNotesArgument.ps1 index 1bfc36c..cdffd54 100644 --- a/build/scripts/SetReleaseNotesArgument.ps1 +++ b/build/scripts/SetReleaseNotesArgument.ps1 @@ -1,28 +1,11 @@ +#Requires -Version 3.0 + param ( # Package name. [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $PackageName, - # Source commit hash. - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $SourceCommitHash, - - # Metadata for packages - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $PackageInfos, - - # Path to source code root folder - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $SourceRootFolderPath, - - # Is build happening on the master branch? - [Parameter()] - [bool] $IsBuildMasterBranch, - # Release Note separation. [Parameter()] [bool] $IsReleaseNoteSeparationRequired = $false, @@ -32,7 +15,7 @@ param ( ) $modulePath = Join-Path $PSScriptRoot "../psmodules/CommonHelpers/CommonHelpers.psm1" -Import-Module $modulePath -Force +Import-Module $modulePath -Force -Scope Local if (0 -lt $TraceLevel) { Set-PSDebug -Trace $TraceLevel @@ -40,9 +23,9 @@ if (0 -lt $TraceLevel) { # Find the most recent tag for the package. $packageMatchPattern = "v*$PackageName" -$tagsOutput = & git tag --list $packageMatchPattern --sort=-version:refname --no-contains $SourceCommitHash +$tagsOutput = & git tag --list $packageMatchPattern --sort=-version:refname --no-contains $env:BUILD_SOURCEVERSION # $isMasterBranch = "$(Build.SourceBranch)" -eq 'refs/heads/master' -$tagMatchPattern = $IsBuildMasterBranch ? "^v\d+\.\d+\.\d+-$PackageName$" : "^v\d+\.\d+\.\d+\.\d+-$PackageName$" +$tagMatchPattern = ($env:BUILD_SOURCEBRANCH -eq 'refs/heads/master') ? "^v\d+\.\d+\.\d+-$PackageName$" : "^v\d+\.\d+\.\d+\.\d+-$PackageName$" [string]$latestTagName = $tagsOutput -split '\r?\n' | Select-String -Pattern $tagMatchPattern -Raw | Select-Object -First 1 | Out-String -Stream # Find the repository object preceding the source commit. @@ -53,9 +36,9 @@ if (-not [string]::IsNullOrWhiteSpace($latestTagName)) { else { $previousCommitObject = & git log --format="%H" --no-abbrev-commit | tail -1 } -$revisionListOutput = Invoke-Expression "git rev-list $previousCommitObject..$SourceCommitHash --no-commit-header --format=%s" +$revisionListOutput = Invoke-Expression "git rev-list $previousCommitObject..$env:BUILD_SOURCEVERSION --no-commit-header --format=%s" -Write-Information "Using commit messages between $previousCommitObject and $SourceCommitHash." +Write-Information "Using commit messages between $previousCommitObject and $env:BUILD_SOURCEVERSION." # Compose the release notes. [string[]]$sanitiseTags = @('[skip ci]', '[ci skip]', 'skip-checks: true', 'skip-checks:true', '[skip azurepipelines]', '[azurepipelines skip]', '[skip azpipelines]', '[azpipelines skip]', '[skip azp]', '[azp skip]', '***NO_CI***') diff --git a/build/scripts/UpdatePackageMetadata.ps1 b/build/scripts/UpdatePackageMetadata.ps1 index 68920ac..14a7124 100644 --- a/build/scripts/UpdatePackageMetadata.ps1 +++ b/build/scripts/UpdatePackageMetadata.ps1 @@ -9,18 +9,10 @@ param ( [ValidateNotNullOrEmpty()] [string] $EncodedPackageVersions, - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $PackageSearchRootPath, - [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $BuildConfiguration, - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $TempPath, - [Parameter()] [ValidateNotNull()] [string] $EncodedReleaseNotes, @@ -30,7 +22,7 @@ param ( ) $modulePath = Join-Path $PSScriptRoot "../psmodules/CommonHelpers/CommonHelpers.psm1" -Import-Module $modulePath -Force +Import-Module $modulePath -Force -Scope Local if (0 -lt $TraceLevel) { Set-PSDebug -Trace $TraceLevel @@ -40,11 +32,11 @@ if (0 -lt $TraceLevel) { $packageVersionsList = $EncodedPackageVersions | ConvertFrom-Base64String | ConvertFrom-Json # Extract the package file to temporary location. -$packageSearchPath = $PackageSearchRootPath | Join-Path -ChildPath 'packages' | Join-Path -ChildPath $BuildConfiguration +$packageSearchPath = $env:BUILD_ARTIFACTSTAGINGDIRECTORY | Join-Path -ChildPath 'packages' | Join-Path -ChildPath $BuildConfiguration $packageFilePath = Get-ChildItem $packageSearchPath -Recurse -Filter "$PackageName*.nupkg" | Select-Object -First 1 -ExpandProperty FullName Write-Information "Found package file at $packageFilePath." -$tempPackagePath = $TempPath | Join-Path -ChildPath $PackageName +$tempPackagePath = $env:AGENT_TEMPDIRECTORY | Join-Path -ChildPath $PackageName if (-not (Test-Path $tempPackagePath -PathType Container)) { New-Item $tempPackagePath -ItemType Directory } @@ -187,17 +179,24 @@ if ($dependencyNodes.Count -eq 0) { Write-Warning "Found $($dependencyNodes.Count) dependencies to process." } +$updatingPackageVersions = $packageVersionsList | Where-Object -Property PackageName -EQ -Value $PackageName +[version]$emptyVersion = '0.0.0.0' + $dependenciesUpdatedCount = 0 foreach ($dependencyNode in $dependencyNodes) { $dependencyName = $dependencyNode.Attributes['id'].Value - $packageVersions = $packageVersionsList | Where-Object -Property PackageName -EQ -Value $dependencyName - if ($null -eq $packageVersions) { + $dependencyPackageVersions = $packageVersionsList | Where-Object -Property PackageName -EQ -Value $dependencyName + if ($null -eq $dependencyPackageVersions) { Write-Verbose "Found no versions for $dependencyName; skipped." continue } - $dependencyNode.Attributes['version'].Value = $packageVersions.PackageProductionVersion - Write-Verbose "Updated dependency $dependencyName to v$($packageVersions.PackageProductionVersion)." + $dependencyPackageVersion = $dependencyPackageVersions.PackageProductionVersionString + if (([version]$updatingPackageVersions.PackageProductionVersion).Revision -eq 0 -and ([version]$dependencyPackageVersions.PackageProductionVersion).Revision -gt 0 -and ([version]$dependencyPackageVersions.PackageStableVersion) -gt $emptyVersion) { + $dependencyPackageVersion = $dependencyPackageVersions.PackageStableVersion + } + $dependencyNode.Attributes['version'].Value = $dependencyPackageVersion + Write-Verbose "Updated dependency $dependencyName to v$dependencyPackageVersion." $dependenciesUpdatedCount++ $isChangedPackageNuspecDocument = $true diff --git a/build/scripts/UpdatePipelineVersionNumber.ps1 b/build/scripts/UpdatePipelineVersionNumber.ps1 new file mode 100644 index 0000000..aef3b69 --- /dev/null +++ b/build/scripts/UpdatePipelineVersionNumber.ps1 @@ -0,0 +1,114 @@ +#Requires -Version 3.0 + +param ( + [Parameter(Mandatory)] + [ValidateNotNullOrEmpty()] + [string] $PackageName, + + [Parameter(Mandatory)] + [ValidateNotNullOrEmpty()] + [string] $VersionNumberName, + + [Parameter()] + [string] $VersionPrereleaseLabelName, + + [Parameter(Mandatory)] + [ValidateNotNullOrEmpty()] + [string] $VariableNamePrefix, + + [Parameter()] + [ValidateNotNullOrEmpty()] + [string] $OutputInformationPreference = 'SilentlyContinue', + + [Parameter()] + [ValidateNotNullOrEmpty()] + [string] $OutputVerbosePreference = 'SilentlyContinue', + + [Parameter()] + [ValidateNotNullOrEmpty()] + [string] $OutputDebugPreference = 'SilentlyContinue', + + [Parameter()] + [int] $TraceLevel = 0 +) + +$InformationPreference = $OutputInformationPreference +$VerbosePreference = $OutputVerbosePreference +$DebugPreference = $OutputDebugPreference + +$modulePath = Join-Path $PSScriptRoot "../psmodules/CommonHelpers/CommonHelpers.psm1" +Import-Module $modulePath -Force -Scope Local + +if (0 -lt $TraceLevel) { + Set-PSDebug -Trace $TraceLevel +} + +# set environment variable for current process +$env:AZURE_DEVOPS_EXT_PAT = $env:SYSTEM_ACCESSTOKEN + +az devops configure -d organization=${env:ORGANIZATION_URL} project=${env:PROJECT_NAME} +az account set -s ${env:SUBSCRIPTION_ID} + +# Extract package metadata. +$packageInfo = $env:PACKAGEINFOS | ConvertFrom-Json | Where-Object -Property packageName -EQ -Value $PackageName +if ($null -eq $packageInfo) { + Write-Error "Package information not found for $PackageName." +} + +$packageVersions = $env:VERSIONNUMBERS | ConvertFrom-Base64String | ConvertFrom-Json | Where-Object -Property PackageName -EQ -Value $PackageName +if ($null -eq $packageVersions) { + Write-Error "Package versions not found for $PackageName." +} + +# Get version numbers for updating. +$variableListOutput = & az pipelines variable-group variable list --group-id $packageInfo.variableGroupId +$pipelinePackageVersions = $variableListOutput | ConvertFrom-Json + +[version]$updateVersionNumber = $packageVersions.PSObject.Properties[$VersionNumberName].Value + +# Update version Major component. +$variableName = "$VariableNamePrefix-major-number" +if ($null -ne $pipelinePackageVersions.PSObject.Properties[$variableName]) { + $updateMajorNumber = $updateVersionNumber.Major + az pipelines variable-group variable update --group-id $packageInfo.variableGroupId --name $variableName --value $updateMajorNumber --verbose + + Write-Verbose "Set pipeline $variableName variable to $updateMajorNumber." +} + +# Update version Minor component. +$variableName = "$VariableNamePrefix-minor-number" +if ($null -ne $pipelinePackageVersions.PSObject.Properties[$variableName]) { + $updateMinorNumber = $updateVersionNumber.Minor + az pipelines variable-group variable update --group-id $packageInfo.variableGroupId --name $variableName --value $updateMinorNumber --verbose + + Write-Verbose "Set pipeline $variableName variable to $updateMinorNumber." +} + +# Update version Patch component. +$variableName = "$VariableNamePrefix-patch-number" +if ($null -ne $pipelinePackageVersions.PSObject.Properties[$variableName]) { + $updateBuildNumber = [System.Math]::Max($updateVersionNumber.Build, 0) + az pipelines variable-group variable update --group-id $packageInfo.variableGroupId --name $variableName --value $updateBuildNumber --verbose + + Write-Verbose "Set pipeline $variableName variable to $updateBuildNumber." +} + +# Update version Prerelease component. +$variableName = "$VariableNamePrefix-prerelease-number" +if ($null -ne $pipelinePackageVersions.PSObject.Properties[$variableName]) { + $updateRevisionNumber = [System.Math]::Max($updateVersionNumber.Revision, 0) + az pipelines variable-group variable update --group-id $packageInfo.variableGroupId --name $variableName --value $updateRevisionNumber --verbose + + Write-Verbose "Set pipeline $variableName variable to $updateRevisionNumber." +} + +# Update prerelease label. +$variableName = "$VariableNamePrefix-prerelease-label" +if ((-not [string]::IsNullOrEmpty($VersionPrereleaseLabelName)) -and ($null -ne $pipelinePackageVersions.PSObject.Properties[$variableName])) { + $prereleaseLabel = $packageVersions.PSObject.Properties[$VersionPrereleaseLabelName].Value + az pipelines variable-group variable update --group-id $packageInfo.variableGroupId --name $variableName --value $prereleaseLabel --verbose + + Write-Verbose "Set pipeline $variableName variable to $prereleaseLabel." +} + +Write-Information "Updated $PackageName $VariableNamePrefix version number to $updateVersionNumber." \ No newline at end of file diff --git a/src/DataStandardizer.BCP47/DataStandardizer.BCP47.csproj b/src/DataStandardizer.BCP47/DataStandardizer.BCP47.csproj index 3c57487..b0da91c 100644 --- a/src/DataStandardizer.BCP47/DataStandardizer.BCP47.csproj +++ b/src/DataStandardizer.BCP47/DataStandardizer.BCP47.csproj @@ -18,7 +18,7 @@ Supports use of IETF BCP 47 language tags as defined by RFC 5646. matthew25187 Initial release. Data Standardizer - Copyright © 2024-2025, Matthew25187. All rights reserved. + Copyright © 2024-2026, Matthew25187. All rights reserved. false false false diff --git a/src/DataStandardizer.Chronology/DataStandardizer.Chronology.csproj b/src/DataStandardizer.Chronology/DataStandardizer.Chronology.csproj index 5df145e..02b9585 100644 --- a/src/DataStandardizer.Chronology/DataStandardizer.Chronology.csproj +++ b/src/DataStandardizer.Chronology/DataStandardizer.Chronology.csproj @@ -13,7 +13,7 @@ Provides types supporting the measurement and comparison of date and time period - TZ Database - Unix time - DOS date/time - Copyright © 2024-2025, Matthew25187. All rights reserved. + Copyright © 2024-2026, Matthew25187. All rights reserved. https://github.com/matthew25187/DataStandardizer 054-doc_web.png README.md diff --git a/src/DataStandardizer.Communication/DataStandardizer.Communication.csproj b/src/DataStandardizer.Communication/DataStandardizer.Communication.csproj index 839e31f..62dcd7e 100644 --- a/src/DataStandardizer.Communication/DataStandardizer.Communication.csproj +++ b/src/DataStandardizer.Communication/DataStandardizer.Communication.csproj @@ -11,7 +11,7 @@ Provides types supporting communication-related standards, including: - ITU-T E.164 telephony numbers - Copyright © 2024-2025, Matthew25187. All rights reserved. + Copyright © 2024-2026, Matthew25187. All rights reserved. https://github.com/matthew25187/DataStandardizer 054-doc_web.png README.md diff --git a/src/DataStandardizer.Core/DataStandardizer.Core.csproj b/src/DataStandardizer.Core/DataStandardizer.Core.csproj index 8042ce8..db37f59 100644 --- a/src/DataStandardizer.Core/DataStandardizer.Core.csproj +++ b/src/DataStandardizer.Core/DataStandardizer.Core.csproj @@ -6,7 +6,7 @@ Data Standardizer provides implementations of various internationally recognised standards in data processing, covering topics ranging from languages to currencies and geographical entities. With strongly-typed enumerations for each standard (where applicable) or other targeted data types, you can represent these elements in your code such that errors with invalid values are minimised. Common types used to implement standards in the other packages. - Copyright © 2024-2025, Matthew25187. All rights reserved. + Copyright © 2024-2026, Matthew25187. All rights reserved. https://github.com/matthew25187/DataStandardizer 054-doc_web.png https://github.com/matthew25187/DataStandardizer.git diff --git a/src/DataStandardizer.File.CSV/DataStandardizer.File.CSV.csproj b/src/DataStandardizer.File.CSV/DataStandardizer.File.CSV.csproj index 5cbef49..0c29d36 100644 --- a/src/DataStandardizer.File.CSV/DataStandardizer.File.CSV.csproj +++ b/src/DataStandardizer.File.CSV/DataStandardizer.File.CSV.csproj @@ -15,7 +15,7 @@ Provides types supporting the reading and writing of files in standard formats. Includes: - Comma Separated Value (CSV). Supports reading and writing CSV files with customizable delimiters. Ideal for CSV data normalization and transformation workflows. - Copyright © 2025, Matthew25187. All rights reserved. + Copyright © 2025-2026, Matthew25187. All rights reserved. https://github.com/matthew25187/DataStandardizer 054-doc_web.png README.md diff --git a/src/DataStandardizer.File/DataStandardizer.File.csproj b/src/DataStandardizer.File/DataStandardizer.File.csproj index 9483bfa..bc7d511 100644 --- a/src/DataStandardizer.File/DataStandardizer.File.csproj +++ b/src/DataStandardizer.File/DataStandardizer.File.csproj @@ -11,7 +11,7 @@ Provides types supporting the reading and writing of files in standard formats. Includes: - Comma Separated Value (CSV). Supports reading and writing CSV files with customizable delimiters. Ideal for CSV data normalization and transformation workflows. - Copyright © 2025, Matthew25187. All rights reserved. + Copyright © 2025-2026, Matthew25187. All rights reserved. https://github.com/matthew25187/DataStandardizer 054-doc_web.png README.md diff --git a/src/DataStandardizer.Geography/DataStandardizer.Geography.csproj b/src/DataStandardizer.Geography/DataStandardizer.Geography.csproj index c476e1b..0f89180 100644 --- a/src/DataStandardizer.Geography/DataStandardizer.Geography.csproj +++ b/src/DataStandardizer.Geography/DataStandardizer.Geography.csproj @@ -17,7 +17,7 @@ Includes: - Supports use of ISO 3166, "Codes for the representation of names of countries and their subdivisions" parts 1 & 2. - Supports use of UN M49 or the "Standard Country or Area Codes for Statistical Use (Series M, No. 49)". - Copyright © 2025, Matthew25187. All rights reserved. + Copyright © 2025-2026, Matthew25187. All rights reserved. https://github.com/matthew25187/DataStandardizer 054-doc_web.png README.md diff --git a/src/DataStandardizer.ISO15924/DataStandardizer.ISO15924.csproj b/src/DataStandardizer.ISO15924/DataStandardizer.ISO15924.csproj index 066b4fe..47208a1 100644 --- a/src/DataStandardizer.ISO15924/DataStandardizer.ISO15924.csproj +++ b/src/DataStandardizer.ISO15924/DataStandardizer.ISO15924.csproj @@ -17,7 +17,7 @@ Supports use of ISO 15924, "Codes for the representation of names of scripts".BSD-3-Clause True Data Standardizer - Copyright © 2024-2025, Matthew25187. All rights reserved. + Copyright © 2024-2026, Matthew25187. All rights reserved. false false false diff --git a/src/DataStandardizer.ISO3166/DataStandardizer.ISO3166.csproj b/src/DataStandardizer.ISO3166/DataStandardizer.ISO3166.csproj index 2d677d4..781b112 100644 --- a/src/DataStandardizer.ISO3166/DataStandardizer.ISO3166.csproj +++ b/src/DataStandardizer.ISO3166/DataStandardizer.ISO3166.csproj @@ -16,7 +16,7 @@ Supports use of ISO 3166, "Codes for the representation of names of countries an BSD-3-Clause True Data Standardizer - Copyright © 2024-2025, Matthew25187. All rights reserved. + Copyright © 2024-2026, Matthew25187. All rights reserved. false false false diff --git a/src/DataStandardizer.ISO4217/DataStandardizer.ISO4217.csproj b/src/DataStandardizer.ISO4217/DataStandardizer.ISO4217.csproj index a58a887..6e3bfe0 100644 --- a/src/DataStandardizer.ISO4217/DataStandardizer.ISO4217.csproj +++ b/src/DataStandardizer.ISO4217/DataStandardizer.ISO4217.csproj @@ -7,7 +7,7 @@ Data Standardizer provides implementations of various internationally recognised standards in data processing, covering topics ranging from languages to currencies and geographical entities. With strongly-typed enumerations for each standard (where applicable) or other targeted data types, you can represent these elements in your code such that errors with invalid values are minimised. Supports use of ISO 4217, "Codes for the representation of currencies and funds". - Copyright © 2024-2025, Matthew25187. All rights reserved. + Copyright © 2024-2026, Matthew25187. All rights reserved. https://github.com/matthew25187/DataStandardizer 054-doc_web.png https://github.com/matthew25187/DataStandardizer.git diff --git a/src/DataStandardizer.ISO639/DataStandardizer.ISO639.csproj b/src/DataStandardizer.ISO639/DataStandardizer.ISO639.csproj index bb65942..c7e9015 100644 --- a/src/DataStandardizer.ISO639/DataStandardizer.ISO639.csproj +++ b/src/DataStandardizer.ISO639/DataStandardizer.ISO639.csproj @@ -7,7 +7,7 @@ Data Standardizer provides implementations of various internationally recognised standards in data processing, covering topics ranging from languages to currencies and geographical entities. With strongly-typed enumerations for each standard (where applicable) or other targeted data types, you can represent these elements in your code such that errors with invalid values are minimised. Supports use of ISO 639, "Codes for the representation of names of languages" parts 1, 2, 3 & 5. - Copyright © 2024-2025, Matthew25187. All rights reserved. + Copyright © 2024-2026, Matthew25187. All rights reserved. https://github.com/matthew25187/DataStandardizer 054-doc_web.png https://github.com/matthew25187/DataStandardizer.git diff --git a/src/DataStandardizer.Language/DataStandardizer.Language.csproj b/src/DataStandardizer.Language/DataStandardizer.Language.csproj index b19dd2a..eeafd24 100644 --- a/src/DataStandardizer.Language/DataStandardizer.Language.csproj +++ b/src/DataStandardizer.Language/DataStandardizer.Language.csproj @@ -16,7 +16,7 @@ Includes: - Supports use of ISO 639, "Codes for the representation of names of languages" parts 1, 2, 3 & 5. - Supports use of ISO 15924, "Codes for the representation of names of scripts". - Copyright © 2025, Matthew25187. All rights reserved. + Copyright © 2025-2026, Matthew25187. All rights reserved. https://github.com/matthew25187/DataStandardizer 054-doc_web.png README.md diff --git a/src/DataStandardizer.LanguageTag/DataStandardizer.LanguageTag.csproj b/src/DataStandardizer.LanguageTag/DataStandardizer.LanguageTag.csproj index 0c20204..64dc476 100644 --- a/src/DataStandardizer.LanguageTag/DataStandardizer.LanguageTag.csproj +++ b/src/DataStandardizer.LanguageTag/DataStandardizer.LanguageTag.csproj @@ -15,7 +15,7 @@ Includes: - Supports use of IETF BCP 47 language tags as defined by RFC 5646. - Copyright © 2025, Matthew25187. All rights reserved. + Copyright © 2025-2026, Matthew25187. All rights reserved. https://github.com/matthew25187/DataStandardizer 054-doc_web.png README.md diff --git a/src/DataStandardizer.Money/DataStandardizer.Money.csproj b/src/DataStandardizer.Money/DataStandardizer.Money.csproj index 8e9c472..c271a9d 100644 --- a/src/DataStandardizer.Money/DataStandardizer.Money.csproj +++ b/src/DataStandardizer.Money/DataStandardizer.Money.csproj @@ -12,7 +12,7 @@ Includes: - Table A.1 – Current currency & funds code list - Table A.3 – List of codes for historic denominations of currencies & funds - Money data type as described in "Patterns of Enterprise Application Architecture" by Martin Fowler. Combines an amount with an ISO 4217 currency code to manage a monetary value. - Copyright © 2024-2025, Matthew25187. All rights reserved. + Copyright © 2024-2026, Matthew25187. All rights reserved. https://github.com/matthew25187/DataStandardizer 054-doc_web.png README.md diff --git a/src/DataStandardizer.Money/Iso4217CurrencyCurrent.cs b/src/DataStandardizer.Money/Iso4217CurrencyCurrent.cs index 1a19a89..55e564e 100644 --- a/src/DataStandardizer.Money/Iso4217CurrencyCurrent.cs +++ b/src/DataStandardizer.Money/Iso4217CurrencyCurrent.cs @@ -1,4 +1,3 @@ - //------------------------------------------------------------------------------ // // This code was generated by a tool. @@ -16,7 +15,7 @@ namespace DataStandardizer.Money /// ISO 4217, "Codes for the representation of currencies and funds" Table A.1 – Current currency & funds code list /// /// - /// Based on official ISO 4217 currency codes as at 2025-05-12. + /// Based on official ISO 4217 currency codes as at 2026-01-01. /// public enum Iso4217CurrencyCurrent : ushort { @@ -211,20 +210,6 @@ public enum Iso4217CurrencyCurrent : ushort [DataStandardizer.Money.Iso4217CurrencyCodeAttribute("Taka", 2)] BDT = 50, - /// - /// Bulgarian Lev - /// - /// - /// Used by: - /// - /// - /// BULGARIA - /// - /// - /// - [DataStandardizer.Money.Iso4217CurrencyCodeAttribute("Bulgarian Lev", 2)] - BGN = 975, - /// /// Bahraini Dinar /// @@ -715,6 +700,9 @@ public enum Iso4217CurrencyCurrent : ushort /// BELGIUM /// /// + /// BULGARIA + /// + /// /// CROATIA /// /// diff --git a/src/DataStandardizer.Money/Iso4217CurrencyHistoric.cs b/src/DataStandardizer.Money/Iso4217CurrencyHistoric.cs index e00b60f..44a9981 100644 --- a/src/DataStandardizer.Money/Iso4217CurrencyHistoric.cs +++ b/src/DataStandardizer.Money/Iso4217CurrencyHistoric.cs @@ -15,7 +15,7 @@ namespace DataStandardizer.Money /// ISO 4217, "Codes for the representation of currencies and funds" Table A.3 – List of codes for historic denominations of currencies & funds /// /// - /// Based on official ISO 4217 currency codes as at 2025-03-31. + /// Based on official ISO 4217 currency codes as at 2026-01-01. /// public enum Iso4217CurrencyHistoric : short { @@ -407,6 +407,25 @@ public enum Iso4217CurrencyHistoric : short [DataStandardizer.Money.Iso4217CurrencyCodeAttribute("Lev")] BGL = 100, + /// + /// Bulgarian Lev + /// + /// + /// + /// Used by: + /// + /// + /// BULGARIA + /// + /// + /// + /// + /// Withdrawn: 2026-01 + /// + /// + [DataStandardizer.Money.Iso4217CurrencyCodeAttribute("Bulgarian Lev")] + BGN = 975, + /// /// Peso boliviano /// diff --git a/src/DataStandardizer.UNM49/DataStandardizer.UNM49.csproj b/src/DataStandardizer.UNM49/DataStandardizer.UNM49.csproj index bae9ebe..b9c1ea4 100644 --- a/src/DataStandardizer.UNM49/DataStandardizer.UNM49.csproj +++ b/src/DataStandardizer.UNM49/DataStandardizer.UNM49.csproj @@ -17,7 +17,7 @@ Supports use of UN M49 or the "Standard Country or Area Codes for Statistical Us BSD-3-Clause True Data Standardizer - Copyright © 2024-2025, Matthew25187. All rights reserved. + Copyright © 2024-2026, Matthew25187. All rights reserved. false false false diff --git a/src/GlobalAssemblyInfo.cs b/src/GlobalAssemblyInfo.cs index c9df05e..30e34e0 100644 --- a/src/GlobalAssemblyInfo.cs +++ b/src/GlobalAssemblyInfo.cs @@ -1,3 +1,3 @@ [assembly: System.Reflection.AssemblyCompany("Matthew25187")] [assembly: System.Reflection.AssemblyProduct("Data Standardizer")] -[assembly: System.Reflection.AssemblyCopyright("Copyright © 2024-2025, Matthew25187. All rights reserved.")] \ No newline at end of file +[assembly: System.Reflection.AssemblyCopyright("Copyright © 2024-2026, Matthew25187. All rights reserved.")] \ No newline at end of file diff --git a/tests/DataStandardizer.Money.Tests/Iso4217ExtensionsTests.cs b/tests/DataStandardizer.Money.Tests/Iso4217ExtensionsTests.cs index c751de1..5bca8cd 100644 --- a/tests/DataStandardizer.Money.Tests/Iso4217ExtensionsTests.cs +++ b/tests/DataStandardizer.Money.Tests/Iso4217ExtensionsTests.cs @@ -25,7 +25,7 @@ public void GetCurrencyName_OnIso4217CurrentCurrencyCode_ReturnsCurrencyName(Iso [Theory] [InlineData(Iso4217CurrencyHistoric.BEF, "Belgian Franc")] - [InlineData(Iso4217CurrencyHistoric.ZWC, "Rhodesian Dollar")] + [InlineData(Iso4217CurrencyHistoric.DDM, "Mark der DDR")] public void GetCurrencyName_OnIso4217HistoricCurrencyCode_ReturnsCurrencyName(Iso4217CurrencyHistoric testCode, string? expectedResult) { // act