diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7a6b4d2..8c8d392 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -27,10 +27,14 @@ variables: value: $(build.version.major).$(build.version.minor).$(build.version.revision) - name: build.date value: $[format('{0:yyyy}-{0:MM}-{0:dd}T{0:HH}:{0:mm}:{0:ss}', pipeline.startTime)] - - group: Azure KeyVault Code Signing + - name: azure.subscription + value: 'ProductionServices' name: $(build.version.major).$(build.version.minor).$(build.version.revision)$(build.version.suffix) + +# This pipeline is manual only. Repository pushes and pull requests must not start builds. trigger: none +pr: none stages: - stage: test_provider @@ -167,6 +171,8 @@ stages: jobs: - job: "build_provider_job" steps: + - template: templates/checkout.yaml@release_tools + - task: DotNetCoreCLI@2 displayName: dotnet build inputs: @@ -174,41 +180,13 @@ stages: arguments: '-c $(buildConfiguration) -p:Version=$(build.version) -p:GeneratePackageOnBuild=false' projects: 'src/Lithnet.CredentialProvider/Lithnet.CredentialProvider.csproj' - - task: DotNetCoreCLI@2 - inputs: - command: 'custom' - custom: 'tool' - arguments: 'update --global azuresigntool' - displayName: Install AzureSignTool - - - task: PowerShell@2 - displayName: 'Sign files with AzureSignTool' - inputs: - targetType: 'inline' - script: | - $files = @() - $files += (Get-ChildItem -Recurse -Path "$(Build.SourcesDirectory)\Lithnet*.dll").FullName - - write-host "Signing $($files.Length) files:" - write-output $files - - $cmdargs = @( - "sign", - "-d", "Lithnet Windows Credential Provider", - "-kvu", "$(akv.url)", - "-kvi", "$(akv.applicationID)", - "-kvs", "$(akv.secret)", - "-kvt", "$(akv.tenantId)", - "-kvc", "$(akv.certificateName)", - "-tr", "http://timestamp.digicert.com", - "-td", "sha256" - ) - - $cmdargs += $files - - & AzureSignTool $cmdargs - failOnStderr: true - showWarnings: true + - template: templates/codesign.yaml@release_tools + parameters: + path: + - '$(Build.SourcesDirectory)/**/Lithnet.CredentialProvider.dll' + environment: 'prod' + azureSubscription: '$(azure.subscription)' + description: 'Lithnet Windows Credential Provider' - task: DotNetCoreCLI@2 displayName: dotnet pack @@ -221,70 +199,14 @@ stages: versioningScheme: 'byEnvVar' versionEnvVar: 'build.version' - - task: DotNetCoreCLI@2 - inputs: - command: 'custom' - custom: 'tool' - arguments: 'update --global NuGetKeyVaultSignTool' - displayName: Install NugetKeyVaultSignTool - - - task: PowerShell@2 - displayName: 'Sign Nuget package' - inputs: - targetType: 'inline' - script: | - $cmdargs = @( - "sign", "$(Build.ArtifactStagingDirectory)\cp\Lithnet.CredentialProvider.$(build.version).nupkg" - "-fd", "sha256", - "-kvu", "$(akv.url)", - "-kvi", "$(akv.applicationID)", - "-kvs", "$(akv.secret)", - "-kvt", "$(akv.tenantId)", - "-kvc", "$(akv.certificateName)", - "-tr", "http://timestamp.digicert.com", - "-td", "sha256" - ) - - & NuGetKeyVaultSignTool $cmdargs - failOnStderr: true - showWarnings: true - - - task: PowerShell@2 - displayName: 'Sign Nuget symbols package' - inputs: - targetType: 'inline' - script: | - $cmdargs = @( - "sign", "$(Build.ArtifactStagingDirectory)\cp\Lithnet.CredentialProvider.$(build.version).snupkg" - "-fd", "sha256", - "-kvu", "$(akv.url)", - "-kvi", "$(akv.applicationID)", - "-kvs", "$(akv.secret)", - "-kvt", "$(akv.tenantId)", - "-kvc", "$(akv.certificateName)", - "-tr", "http://timestamp.digicert.com", - "-td", "sha256" - ) - - & NuGetKeyVaultSignTool $cmdargs - failOnStderr: true - showWarnings: true - - - task: DotNetCoreCLI@2 - displayName: Publish package to internal feed - inputs: - command: 'push' - packagesToPush: '$(Build.ArtifactStagingDirectory)/cp/*.nupkg' - nuGetFeedType: 'internal' - publishVstsFeed: '91a552bc-359d-4f28-bdbd-f36f71cfdf81' - - - task: DotNetCoreCLI@2 - displayName: Publish symbols to internal feed - inputs: - command: 'push' - packagesToPush: '$(Build.ArtifactStagingDirectory)/cp/*.snupkg' - nuGetFeedType: 'internal' - publishVstsFeed: '91a552bc-359d-4f28-bdbd-f36f71cfdf81' + - template: templates/codesign.yaml@release_tools + parameters: + path: + - '$(Build.ArtifactStagingDirectory)/cp/*.nupkg' + - '$(Build.ArtifactStagingDirectory)/cp/*.snupkg' + environment: 'prod' + azureSubscription: '$(azure.subscription)' + description: 'Lithnet Windows Credential Provider' - task: PublishPipelineArtifact@1 displayName: Publish nuget artifact @@ -293,65 +215,78 @@ stages: publishLocation: 'pipeline' artifact: cp - - task: GitHubRelease@1 - inputs: - gitHubConnection: github.com_lithnet # string. Required. GitHub connection (OAuth or PAT). - repositoryName: '$(Build.Repository.Name)' # string. Required. Repository. Default: $(Build.Repository.Name). - action: 'create' # 'create' | 'edit' | 'delete'. Required. Action. Default: create. - #target: '$(Build.SourceVersion)' # string. Required when action = create || action = edit. Target. Default: $(Build.SourceVersion). - tagSource: 'userSpecifiedTag' # 'gitTag' | 'userSpecifiedTag'. Required when action = create. Tag source. Default: gitTag. - #tagPattern: # string. Optional. Use when tagSource = gitTag. Tag Pattern. - tag: v$(build.version) # string. Required when action = edit || action = delete || tagSource = userSpecifiedTag. Tag. - title: v$(build.version) # string. Optional. Use when action = create || action = edit. Release title. - #releaseNotesSource: 'filePath' # 'filePath' | 'inline'. Optional. Use when action = create || action = edit. Release notes source. Default: filePath. - #releaseNotesFilePath: # string. Optional. Use when releaseNotesSource = filePath. Release notes file path. - #releaseNotesInline: # string. Optional. Use when releaseNotesSource = inline. Release notes. - assets: | # string. Optional. Use when action = create || action = edit. Assets. Default: $(Build.ArtifactStagingDirectory)/*. - $(Build.ArtifactStagingDirectory)/cp/*.nupkg - #assetUploadMode: 'delete' # 'delete' | 'replace'. Optional. Use when action = edit. Asset upload mode. Default: delete. - #isDraft: false # boolean. Optional. Use when action = create || action = edit. Draft release. Default: false. - isPreRelease: true # boolean. Optional. Use when action = create || action = edit. Pre-release. Default: false. - addChangeLog: true # boolean. Optional. Use when action = create || action = edit. Add changelog. Default: true. - # Changelog configuration - changeLogCompareToRelease: 'lastFullRelease' # 'lastFullRelease' | 'lastNonDraftRelease' | 'lastNonDraftReleaseByTag'. Required when addChangeLog = true. Compare to. Default: lastFullRelease. - #changeLogCompareToReleaseTag: # string. Required when changeLogCompareToRelease = lastNonDraftReleaseByTag && addChangeLog = true. Release Tag. - changeLogType: 'commitBased' # 'commitBased' | 'issueBased'. Required when addChangeLog = true. Changelog type. Default: commitBased. - #changeLogLabels: '[{ "label" : "bug", "displayName" : "Bugs", "state" : "closed" }]' # string. Optional. Use when changeLogType = issueBased && addChangeLog = true. Categories. Default: [{ "label" : "bug", "displayName" : "Bugs", "state" : "closed" }]. - -- stage: publish_nuget - displayName: Publish CredProvider to nuget.org - dependsOn: "build_provider" +# Publish signed packages to Azure Artifacts only after the test and build stages succeed. +- stage: publish_internal + displayName: Publish to internal feed + dependsOn: build_provider jobs: - - deployment: 'PublishPackages' - environment: 'Public nuget feed' - displayName: Publish packages to public nuget feed - pool: - vmImage: windows-2022 - strategy: - runOnce: - deploy: - steps: + - job: publish_internal_job + displayName: Publish packages to internal feed + steps: + - checkout: none + + - download: current + artifact: cp + + - template: templates/publish-nuget.yaml@release_tools + parameters: + nugetPackagePath: '$(Pipeline.Workspace)/cp/*.nupkg' + symbolPackagePath: '$(Pipeline.Workspace)/cp/*.snupkg' + publishInternal: true + publishExternal: false + +# Public release is limited to main and waits for approval on the Public nuget feed environment. +- stage: publish_prod + displayName: Publish to nuget.org and GitHub + dependsOn: publish_internal + condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')) + jobs: + - deployment: publish_nuget + displayName: Publish package to public nuget feed + environment: 'Public nuget feed' + pool: + vmImage: windows-2022 + strategy: + runOnce: + deploy: + steps: - checkout: none + - download: current artifact: cp - - task: NuGetToolInstaller@1 - inputs: - versionSpec: '>=4.9.0-0' - - task: NuGetCommand@2 - displayName: 'Publish nuget package to public feed' - inputs: - command: 'push' - packagesToPush: '$(Pipeline.Workspace)/cp/*.nupkg' - nuGetFeedType: 'external' - publishFeedCredentials: 'WindowsCredentialProviderNuget' - - task: GitHubRelease@1 - inputs: - gitHubConnection: github.com_lithnet # string. Required. GitHub connection (OAuth or PAT). - repositoryName: '$(Build.Repository.Name)' # string. Required. Repository. Default: $(Build.Repository.Name). - action: 'edit' # 'create' | 'edit' | 'delete'. Required. Action. Default: create. - target: '$(Build.SourceVersion)' # string. Required when action = create || action = edit. Target. Default: $(Build.SourceVersion). - tagSource: 'userSpecifiedTag' # 'gitTag' | 'userSpecifiedTag'. Required when action = create. Tag source. Default: gitTag. - #tagPattern: # string. Optional. Use when tagSource = gitTag. Tag Pattern. - tag: v$(build.version) # string. Required when action = edit || action = delete || tagSource = userSpecifiedTag. Tag. - isPreRelease: false # boolean. Optional. Use when action = create || action = edit. Pre-release. Default: false. - addChangeLog: false # boolean. Optional. Use when action = create || action = edit. Add changelog. Default: true. + + - template: templates/publish-nuget.yaml@release_tools + parameters: + nugetPackagePath: '$(Pipeline.Workspace)/cp/*.nupkg' + publishInternal: false + publishExternal: true + externalFeedCredentials: 'WindowsCredentialProviderNuget' + + # Create the GitHub release only after nuget.org accepts the package. + - job: publish_github + displayName: Publish package to GitHub releases + dependsOn: publish_nuget + condition: succeeded() + pool: + vmImage: windows-2022 + steps: + - checkout: none + + - download: current + artifact: cp + + - task: GitHubRelease@1 + displayName: Create GitHub release (v$(build.version)) + inputs: + gitHubConnection: github.com_lithnet + repositoryName: '$(Build.Repository.Name)' + action: create + target: '$(Build.SourceVersion)' + tagSource: userSpecifiedTag + tag: v$(build.version) + title: v$(build.version) + assets: '$(Pipeline.Workspace)/cp/*.nupkg' + isPreRelease: false + addChangeLog: true + changeLogCompareToRelease: lastFullRelease + changeLogType: commitBased