@@ -14,13 +14,16 @@ parameters:
1414- name : DevFeedName
1515 type : string
1616 default : ' public/azure-sdk-for-rust'
17+ - name : Environment
18+ type : string
19+ default : ' cratesio'
1720
1821stages :
1922- ${{ if eq(variables['System.TeamProject'], 'internal') }} :
2023 - ${{ if in(variables['Build.Reason'], 'Manual', '') }} :
21- - ${{ if gt(length( parameters.Artifacts), 0) }} :
22- - stage : Release_Batch
23- displayName : " Releasing : ${{length(parameters.Artifacts)}} crates "
24+ - ${{ each artifact in parameters.Artifacts }} :
25+ - stage : Release_${{artifact.safeName}}
26+ displayName : " Release : ${{artifact.name}} "
2427 dependsOn : ${{parameters.DependsOn}}
2528 condition : and(succeeded(), ne(variables['SetDevVersion'], 'true'), ne(variables['Skip.Release'], 'true'), ne(variables['Build.Repository.Name'], 'Azure/azure-sdk-for-rust-pr'))
2629 variables :
@@ -47,17 +50,16 @@ stages:
4750
4851 - template : /eng/common/pipelines/templates/steps/retain-run.yml
4952
50- - ${{ each artifact in parameters.Artifacts }} :
51- - script : |
52- echo "##vso[build.addbuildtag]${{artifact.name}}"
53- displayName: Add build tag '${{artifact.name}}'
53+ - script : |
54+ echo "##vso[build.addbuildtag]${{artifact.name}}"
55+ displayName: Add build tag '${{artifact.name}}'
5456
55- - template : /eng/common/pipelines/templates/steps/create-tags-and-git-release.yml
56- parameters :
57- ArtifactLocation : $(Pipeline.Workspace)/${{parameters.PipelineArtifactName}}/${{artifact.name}}
58- PackageRepository : Crates.io
59- ReleaseSha : $(Build.SourceVersion)
60- WorkingDirectory : $(Pipeline.Workspace)/_work
57+ - template : /eng/common/pipelines/templates/steps/create-tags-and-git-release.yml
58+ parameters :
59+ ArtifactLocation : $(Pipeline.Workspace)/${{parameters.PipelineArtifactName}}/${{artifact.name}}
60+ PackageRepository : Crates.io
61+ ReleaseSha : $(Build.SourceVersion)
62+ WorkingDirectory : $(Pipeline.Workspace)/_work
6163
6264 - deployment : PublishPackage
6365 displayName : " Publish to Crates.io"
@@ -69,10 +71,7 @@ stages:
6971 - input : pipelineArtifact # Required, type of the input artifact
7072 artifactName : ${{parameters.PipelineArtifactName}} # Required, name of the pipeline artifact
7173 targetPath : $(Pipeline.Workspace)/drop # Optional, specifies where the artifact is downloaded to
72- ${{if parameters.TestPipeline}} :
73- environment : none
74- ${{else}} :
75- environment : cratesio
74+ environment : ${{parameters.Environment}}
7675 # This timeout shouldn't be necessary once we're able to parallelize better. Right now,
7776 # this is here to ensure larger areas (30+) libraries don't time out.
7877 timeoutInMinutes : 120
@@ -85,77 +84,33 @@ stages:
8584 runOnce :
8685 deploy :
8786 steps :
88- - pwsh : |
89- Write-Host "##vso[task.setvariable variable=ArtifactIndex]0"
90- displayName: Set ArtifactIndex to 0
91-
92- - ${{ each artifact in parameters.Artifacts }} :
93- - pwsh : |
94- # Read artifact release order from release-order.json
95- # and use ArtifactIndex to select the right one
96- $index = [int]'$(ArtifactIndex)'
97- $artifacts = Get-Content '$(Pipeline.Workspace)/drop/release-order.json' | ConvertFrom-Json
98- if ($index -ge $artifacts.Count) {
99- Write-Error "ArtifactIndex $index is out of range (0..$($artifacts.Count - 1))"
100- exit 1
101- }
102-
103- $artifactName = $artifacts[$index]
104- Write-Host "Releasing artifact $artifactName (index $index)"
105-
106- $artifactRootPath = '$(Pipeline.Workspace)/drop'
107- $outDir = '$(Pipeline.Workspace)/esrp-release'
108-
109- if (Test-Path $outDir) {
110- Write-Host "Cleaning output directory: $outDir"
111- Remove-Item -Path $outDir -Recurse -Force
112- }
113- New-Item -ItemType Directory -Path $outDir -Force | Out-Null
114-
115- Write-Host "Artifact name: $artifactName"
116-
117- $packageMetadataPath = "$artifactRootPath/PackageInfo/$artifactName.json"
118- if (!(Test-Path $packageMetadataPath)) {
119- Write-Error "Package metadata file not found: $packageMetadataPath"
120- exit 1
121- }
122-
123- $packageMetadata = Get-Content -Raw $packageMetadataPath | ConvertFrom-Json
124- $packageVersion = $packageMetadata.version
125- Write-Host "Package version: $packageVersion"
126-
127- $cratePath = "$artifactRootPath/$artifactName/$artifactName-$packageVersion.crate"
128- Copy-Item `
129- -Path $cratePath `
130- -Destination $outDir
131- Write-Host "Contents of $outDir"
132- Get-ChildItem -Path $outDir | ForEach-Object { Write-Host $_.FullName }
133- displayName: 'Copy crate for ESRP'
134-
135- - task : EsrpRelease@10
136- displayName : ' ESRP Release'
137- inputs :
138- connectedservicename : ' Azure SDK PME Managed Identity'
139- ClientId : ' 5f81938c-2544-4f1f-9251-dd9de5b8a81b'
140- DomainTenantId : ' 975f013f-7f24-47e8-a7d3-abc4752bf346'
141- Usemanagedidentity : true
142- KeyVaultName : ' kv-azuresdk-codesign'
143- SignCertName : ' azure-sdk-esrp-release-certificate'
144- intent : ' packagedistribution'
145- contenttype : ' Rust'
146- contentsource : ' Folder'
147- folderlocation : ' $(Pipeline.Workspace)/esrp-release'
148- waitforreleasecompletion : true
149- owners :
${{ coalesce(variables['Build.RequestedForEmail'], '[email protected] ') }} 150- approvers :
${{ coalesce(variables['Build.RequestedForEmail'], '[email protected] ') }} 151- serviceendpointurl : ' https://api.esrp.microsoft.com/'
152- mainpublisher : ' ESRPRELPACMANTEST'
153-
154- - pwsh : |
155- $index = [int]'$(ArtifactIndex)' + 1
156- Write-Host "Setting ArtifactIndex to $index"
157- Write-Host "##vso[task.setvariable variable=ArtifactIndex]$index"
158- displayName: Increment ArtifactIndex
87+ - template : /eng/pipelines/templates/steps/use-rust.yml@self
88+ parameters :
89+ Toolchain : stable
90+
91+ - pwsh : |
92+ $additionalOwners = @('heaths', 'hallipr')
93+ $token = $env:CARGO_REGISTRY_TOKEN
94+ $crateName = '${{artifact.name}}'
95+
96+ $manifestPath = "$(Pipeline.Workspace)/drop/$crateName/contents/Cargo.toml"
97+ Write-Host "> cargo publish --manifest-path `"$manifestPath`""
98+ cargo publish --manifest-path $manifestPath
99+ if (!$?) {
100+ Write-Error "Failed to publish package: '$crateName'"
101+ exit 1
102+ }
103+
104+ $existingOwners = (cargo owner --list $crateName) -replace " \(.*", ""
105+ $missingOwners = $additionalOwners | Where-Object { $existingOwners -notcontains $_ }
106+
107+ foreach ($owner in $missingOwners) {
108+ Write-Host "> cargo owner --add $owner $crateName"
109+ cargo owner --add $owner $crateName
110+ }
111+ displayName: Publish Crate
112+ env:
113+ CARGO_REGISTRY_TOKEN: $(azure-sdk-cratesio-token)
159114
160115 - job : UpdatePackageVersion
161116 displayName : " API Review and Package Version Update"
@@ -175,32 +130,69 @@ stages:
175130 displayName : Download ${{parameters.PipelineArtifactName}} artifact
176131 artifact : ${{parameters.PipelineArtifactName}}
177132
178- - ${{each artifact in parameters.Artifacts }} :
179- - template : /eng/common/pipelines/templates/steps/create-apireview.yml
180- parameters :
181- ArtifactPath : $(Pipeline.Workspace)/${{parameters.PipelineArtifactName}}
182- Artifacts : ${{parameters.Artifacts}}
183- ConfigFileDir : $(Pipeline.Workspace)/${{parameters.PipelineArtifactName}}/PackageInfo
184- MarkPackageAsShipped : true
185- ArtifactName : ${{parameters.PipelineArtifactName}}
186- SourceRootPath : $(System.DefaultWorkingDirectory)
187- PackageName : ${{artifact.name}}
188-
189- # Apply the version increment to each library, which updates the Cargo.toml and changelog files.
190- - task : PowerShell@2
191- displayName : Increment ${{artifact.name}} version
192- inputs :
193- targetType : filePath
194- filePath : $(Build.SourcesDirectory)/eng/scripts/Update-PackageVersion.ps1
195- arguments : >
196- -ServiceDirectory '${{parameters.ServiceDirectory}}'
197- -PackageName '${{artifact.name}}'
133+ - template : /eng/common/pipelines/templates/steps/create-apireview.yml
134+ parameters :
135+ ArtifactPath : $(Pipeline.Workspace)/${{parameters.PipelineArtifactName}}
136+ Artifacts : ${{parameters.Artifacts}}
137+ ConfigFileDir : $(Pipeline.Workspace)/${{parameters.PipelineArtifactName}}/PackageInfo
138+ MarkPackageAsShipped : true
139+ ArtifactName : ${{parameters.PipelineArtifactName}}
140+ SourceRootPath : $(System.DefaultWorkingDirectory)
141+ PackageName : ${{artifact.name}}
142+
143+ # Apply the version increment to each library, which updates the Cargo.toml and changelog files.
144+ - task : PowerShell@2
145+ displayName : Increment ${{artifact.name}} version
146+ inputs :
147+ targetType : filePath
148+ filePath : $(Build.SourcesDirectory)/eng/scripts/Update-PackageVersion.ps1
149+ arguments : >
150+ -ServiceDirectory '${{parameters.ServiceDirectory}}'
151+ -PackageName '${{artifact.name}}'
198152
199153 - template : /eng/common/pipelines/templates/steps/create-pull-request.yml
200154 parameters :
201155 PRBranchName : increment-package-version-${{parameters.ServiceDirectory}}-$(Build.BuildId)
202- CommitMsg : " Increment package version after release of ${{ join(', ', parameters.Artifacts.*. name) }}"
156+ CommitMsg : " Increment package version after release of ${{ artifact. name }}"
203157 PRTitle : " Increment versions for ${{parameters.ServiceDirectory}} releases"
204158 CloseAfterOpenForTesting : ' ${{parameters.TestPipeline}}'
205159 ${{ if startsWith(variables['Build.SourceBranch'], 'refs/pull/') }} :
206160 BaseBranchName : main
161+
162+ - ${{ if eq(parameters.TestPipeline, true) }} :
163+ - job : ManualApproval
164+ displayName : " Manual approval"
165+ dependsOn : PublishPackage
166+ condition : ne(variables['Skip.PublishPackage'], 'true')
167+ pool : server
168+ timeoutInMinutes : 120 # 2 hours
169+ steps :
170+ - task : ManualValidation@1
171+ timeoutInMinutes : 60 # 1 hour
172+ inputs :
173+ notifyUsers : ' ' # Required, but empty string allowed
174+ allowApproversToApproveTheirOwnRuns : true
175+ instructions : " Approve yank of ${{ artifact.name }}"
176+ onTimeout : ' resume'
177+
178+ - job : YankCrates
179+ displayName : " Yank Crates"
180+ dependsOn : ManualApproval
181+ condition : and(succeeded(), ne(variables['Skip.PublishPackage'], 'true'))
182+ steps :
183+ - template : /eng/common/pipelines/templates/steps/sparse-checkout.yml
184+
185+ - download : current
186+ displayName : Download ${{parameters.PipelineArtifactName}} artifact
187+ artifact : ${{parameters.PipelineArtifactName}}
188+
189+ - task : PowerShell@2
190+ displayName : Yank Crates
191+ env :
192+ CARGO_REGISTRY_TOKEN : $(azure-sdk-cratesio-token)
193+ inputs :
194+ targetType : filePath
195+ filePath : $(Build.SourcesDirectory)/eng/scripts/Yank-Crates.ps1
196+ arguments :
197+ -CrateNames '${{artifact.name}}'
198+ -PackageInfoDirectory '$(Pipeline.Workspace)/${{parameters.PipelineArtifactName}}/PackageInfo'
0 commit comments