33# https://aka.ms/yaml
44
55parameters :
6- - name : managedPool
7- displayName : ' Use the netstandard Managed DevOps Pool (adds ImageOverride demands per OS)'
8- type : boolean
9- default : true
6+ - name : poolMode
7+ displayName : ' Pool routing: mixed shares the netstandard Managed DevOps Pool and Microsoft-hosted agents across stages; managed forces all stages onto the managed pool; hosted forces all stages onto hosted agents'
8+ type : string
9+ default : mixed
10+ values :
11+ - mixed
12+ - managed
13+ - hosted
1014
1115trigger :
1216 batch : ' true'
@@ -52,20 +56,42 @@ schedules:
5256variables :
5357 FullBuild : ${{ ne(variables['Build.Reason'], 'PullRequest') }}
5458 ScheduledBuild : ${{ in(variables['Build.Reason'], 'Schedule', 'Manual') }}
55- # When managedPool is true, route Windows/Linux jobs to the 'netstandard'
56- # Managed DevOps Pool and select images via ImageOverride demands. See
57- # https://learn.microsoft.com/azure/devops/managed-devops-pools/configure-images#use-demands-to-specify-an-image
58- # Mac jobs always run on Microsoft-hosted agents because Managed DevOps Pools
59+ # macOS jobs always run on Microsoft-hosted agents because Managed DevOps Pools
5960 # does not provide macOS images.
60- ${{ if parameters.managedPool }} :
61- poolName : ' netstandard'
62- windowsImage : ' windows-2022-g2'
63- linuxImage : ' ubuntu-22.04-g2'
64- ${{ else }} :
65- poolName : ' '
66- windowsImage : ' windows-2025-vs2026'
67- linuxImage : ' ubuntu-24.04'
6861 macImage : ' macOS-15'
62+ # Two pool profiles are defined so stages can be routed independently and the
63+ # netstandard Managed DevOps Pool and the Microsoft-hosted agents share the
64+ # workload of a single run (see the per-stage mapping below). Each profile is
65+ # a (poolName, windowsImage, linuxImage) triple; poolName='' selects hosted
66+ # agents (vmImage), otherwise the named Managed DevOps Pool is used with an
67+ # ImageOverride demand per OS. See
68+ # https://learn.microsoft.com/azure/devops/managed-devops-pools/configure-images#use-demands-to-specify-an-image
69+ #
70+ # poolMode collapses the two profiles for the all-managed / all-hosted
71+ # overrides; 'mixed' (default) keeps them distinct so both pools run in
72+ # parallel. Stages reference mgd*/host* only, so no per-stage conditionals
73+ # are needed.
74+ ${{ if eq(parameters.poolMode, 'hosted') }} :
75+ mgdPoolName : ' '
76+ mgdWindowsImage : ' windows-2025-vs2026'
77+ mgdLinuxImage : ' ubuntu-24.04'
78+ hostPoolName : ' '
79+ hostWindowsImage : ' windows-2025-vs2026'
80+ hostLinuxImage : ' ubuntu-24.04'
81+ ${{ elseif eq(parameters.poolMode, 'managed') }} :
82+ mgdPoolName : ' netstandard'
83+ mgdWindowsImage : ' windows-2022-g2'
84+ mgdLinuxImage : ' ubuntu-22.04-g2'
85+ hostPoolName : ' netstandard'
86+ hostWindowsImage : ' windows-2022-g2'
87+ hostLinuxImage : ' ubuntu-22.04-g2'
88+ ${{ else }} :
89+ mgdPoolName : ' netstandard'
90+ mgdWindowsImage : ' windows-2022-g2'
91+ mgdLinuxImage : ' ubuntu-22.04-g2'
92+ hostPoolName : ' '
93+ hostWindowsImage : ' windows-2025-vs2026'
94+ hostLinuxImage : ' ubuntu-24.04'
6995
7096stages :
7197- stage : build
@@ -74,8 +100,8 @@ stages:
74100 jobs :
75101 - template : .azurepipelines/sln.yml
76102 parameters :
77- poolImage : ${{ variables.windowsImage }}
78- poolName : ${{ variables.poolName }}
103+ poolImage : ${{ variables.hostWindowsImage }}
104+ poolName : ${{ variables.hostPoolName }}
79105 jobnamesuffix : win2025
80106 # PR builds discover every *.slnx and restrict to a small TFM set so each
81107 # matrix job's bin tree fits on the managed-pool agent's small temp
@@ -94,19 +120,19 @@ stages:
94120 parameters :
95121 configuration : Release
96122 framework : net48
97- agents : ' @{ windows = "${{ variables.windowsImage }}" }'
123+ agents : ' @{ windows = "${{ variables.mgdWindowsImage }}" }'
98124 jobnamesuffix : net48
99- poolName : ${{ variables.poolName }}
100- windowsImage : ${{ variables.windowsImage }}
125+ poolName : ${{ variables.mgdPoolName }}
126+ windowsImage : ${{ variables.mgdWindowsImage }}
101127 - template : .azurepipelines/test.yml
102128 parameters :
103129 configuration : Release
104130 framework : net10.0
105- agents : ' @{ windows = "${{ variables.windowsImage }}" }'
131+ agents : ' @{ windows = "${{ variables.mgdWindowsImage }}" }'
106132 jobnamesuffix : net100
107133 customtestarget : net10.0
108- poolName : ${{ variables.poolName }}
109- windowsImage : ${{ variables.windowsImage }}
134+ poolName : ${{ variables.mgdPoolName }}
135+ windowsImage : ${{ variables.mgdWindowsImage }}
110136 - template : .azurepipelines/test.yml
111137 parameters :
112138 configuration : Release
@@ -115,8 +141,8 @@ stages:
115141 jobnamesuffix : net100mac
116142 customtestarget : net10.0
117143 hosted : true
118- poolName : ${{ variables.poolName }}
119- windowsImage : ${{ variables.windowsImage }}
144+ poolName : ${{ variables.mgdPoolName }}
145+ windowsImage : ${{ variables.mgdWindowsImage }}
120146 # macOS runs only on Schedule/Manual (nightly + on-demand), not on
121147 # PR or master push, to keep the PR gate fast and Windows-focused.
122148 condition : and(succeeded(), ne(variables.ScheduledBuild, 'False'))
@@ -128,10 +154,10 @@ stages:
128154 - template : .azurepipelines/test-aot.yml
129155 parameters :
130156 configuration : Release
131- agents : ' @{ windows = "${{ variables.windowsImage }}"; linux="${{ variables.linuxImage }}"}'
157+ agents : ' @{ windows = "${{ variables.mgdWindowsImage }}"; linux="${{ variables.mgdLinuxImage }}"}'
132158 jobnamesuffix : net100aot
133- poolName : ${{ variables.poolName }}
134- windowsImage : ${{ variables.windowsImage }}
159+ poolName : ${{ variables.mgdPoolName }}
160+ windowsImage : ${{ variables.mgdWindowsImage }}
135161- stage : testdebug
136162 dependsOn : [build]
137163 displayName : ' Test Core and SDK Debug'
@@ -142,18 +168,18 @@ stages:
142168 framework : net10.0
143169 configuration : Debug
144170 jobnamesuffix : net100debug
145- poolName : ${{ variables.poolName }}
146- windowsImage : ${{ variables.windowsImage }}
147- agents : ' @{ windows = "${{ variables.windowsImage }}"; linux = "${{ variables.linuxImage }}" }'
171+ poolName : ${{ variables.hostPoolName }}
172+ windowsImage : ${{ variables.hostWindowsImage }}
173+ agents : ' @{ windows = "${{ variables.hostWindowsImage }}"; linux = "${{ variables.hostLinuxImage }}" }'
148174 - template : .azurepipelines/test.yml
149175 parameters :
150176 framework : net10.0
151177 configuration : Debug
152178 jobnamesuffix : net100debugmac
153179 agents : ' @{ mac = "${{ variables.macImage }}" }'
154180 hosted : true
155- poolName : ${{ variables.poolName }}
156- windowsImage : ${{ variables.windowsImage }}
181+ poolName : ${{ variables.hostPoolName }}
182+ windowsImage : ${{ variables.hostWindowsImage }}
157183- stage : testnet90
158184 dependsOn : [build]
159185 displayName : ' Test .NET 9.0'
@@ -164,18 +190,18 @@ stages:
164190 framework : net9.0
165191 configuration : Release
166192 jobnamesuffix : net90
167- poolName : ${{ variables.poolName }}
168- windowsImage : ${{ variables.windowsImage }}
169- agents : ' @{ windows = "${{ variables.windowsImage }}"; linux = "${{ variables.linuxImage }}" }'
193+ poolName : ${{ variables.mgdPoolName }}
194+ windowsImage : ${{ variables.mgdWindowsImage }}
195+ agents : ' @{ windows = "${{ variables.mgdWindowsImage }}"; linux = "${{ variables.mgdLinuxImage }}" }'
170196 - template : .azurepipelines/test.yml
171197 parameters :
172198 framework : net9.0
173199 configuration : Release
174200 jobnamesuffix : net90mac
175201 agents : ' @{ mac = "${{ variables.macImage }}" }'
176202 hosted : true
177- poolName : ${{ variables.poolName }}
178- windowsImage : ${{ variables.windowsImage }}
203+ poolName : ${{ variables.mgdPoolName }}
204+ windowsImage : ${{ variables.mgdWindowsImage }}
179205- stage : testnet80
180206 dependsOn : [build]
181207 displayName : ' Test .NET 8.0'
@@ -186,18 +212,18 @@ stages:
186212 framework : net8.0
187213 configuration : Release
188214 jobnamesuffix : net80
189- poolName : ${{ variables.poolName }}
190- windowsImage : ${{ variables.windowsImage }}
191- agents : ' @{ windows = "${{ variables.windowsImage }}"; linux = "${{ variables.linuxImage }}" }'
215+ poolName : ${{ variables.hostPoolName }}
216+ windowsImage : ${{ variables.hostWindowsImage }}
217+ agents : ' @{ windows = "${{ variables.hostWindowsImage }}"; linux = "${{ variables.hostLinuxImage }}" }'
192218 - template : .azurepipelines/test.yml
193219 parameters :
194220 framework : net8.0
195221 configuration : Release
196222 jobnamesuffix : net80mac
197223 agents : ' @{ mac = "${{ variables.macImage }}" }'
198224 hosted : true
199- poolName : ${{ variables.poolName }}
200- windowsImage : ${{ variables.windowsImage }}
225+ poolName : ${{ variables.hostPoolName }}
226+ windowsImage : ${{ variables.hostWindowsImage }}
201227- stage : testnet472
202228 dependsOn : [build]
203229 displayName : ' Test .NET 4.7.2'
@@ -208,10 +234,10 @@ stages:
208234 framework : net472
209235 configuration : Release
210236 jobnamesuffix : net472
211- agents : ' @{ windows = "${{ variables.windowsImage }}" }'
237+ agents : ' @{ windows = "${{ variables.hostWindowsImage }}" }'
212238 customtestarget : net472
213- poolName : ${{ variables.poolName }}
214- windowsImage : ${{ variables.windowsImage }}
239+ poolName : ${{ variables.hostPoolName }}
240+ windowsImage : ${{ variables.hostWindowsImage }}
215241- stage : testnetstandard20
216242 dependsOn : [build]
217243 displayName : ' Test .NETStandard 2.0'
@@ -222,10 +248,10 @@ stages:
222248 framework : net48
223249 configuration : Release
224250 jobnamesuffix : netstandard20
225- agents : ' @{ windows = "${{ variables.windowsImage }}"}'
251+ agents : ' @{ windows = "${{ variables.mgdWindowsImage }}"}'
226252 customtestarget : netstandard2.0
227- poolName : ${{ variables.poolName }}
228- windowsImage : ${{ variables.windowsImage }}
253+ poolName : ${{ variables.mgdPoolName }}
254+ windowsImage : ${{ variables.mgdWindowsImage }}
229255- stage : testnetstandard21
230256 dependsOn : [build]
231257 displayName : ' Test .NETStandard 2.1'
@@ -237,9 +263,9 @@ stages:
237263 configuration : Release
238264 jobnamesuffix : netstandard21
239265 customtestarget : netstandard2.1
240- poolName : ${{ variables.poolName }}
241- windowsImage : ${{ variables.windowsImage }}
242- agents : ' @{ windows = "${{ variables.windowsImage }}"; linux = "${{ variables.linuxImage }}" }'
266+ poolName : ${{ variables.mgdPoolName }}
267+ windowsImage : ${{ variables.mgdWindowsImage }}
268+ agents : ' @{ windows = "${{ variables.mgdWindowsImage }}"; linux = "${{ variables.mgdLinuxImage }}" }'
243269 - template : .azurepipelines/test.yml
244270 parameters :
245271 framework : net8.0
@@ -248,8 +274,8 @@ stages:
248274 customtestarget : netstandard2.1
249275 agents : ' @{ mac = "${{ variables.macImage }}" }'
250276 hosted : true
251- poolName : ${{ variables.poolName }}
252- windowsImage : ${{ variables.windowsImage }}
277+ poolName : ${{ variables.mgdPoolName }}
278+ windowsImage : ${{ variables.mgdWindowsImage }}
253279- stage : coverage
254280 dependsOn : [testdebug,testfastpr]
255281 displayName : ' Code Coverage'
@@ -258,7 +284,7 @@ stages:
258284 - template : .azurepipelines/testcc.yml
259285 parameters :
260286 configuration : Release
261- poolImage : ${{ variables.linuxImage }}
287+ poolImage : ${{ variables.hostLinuxImage }}
262288 framework : net10.0
263289 jobnamesuffix : net100cc
264- poolName : ${{ variables.poolName }}
290+ poolName : ${{ variables.hostPoolName }}
0 commit comments