Pipelines | Move CI and PR jobs off Microsoft-hosted agents - #4515
Pipelines | Move CI and PR jobs off Microsoft-hosted agents#4515cheenamalhotra wants to merge 14 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR completes the hosted-agent retirement work for the Azure DevOps CI/PR YAML by moving previously Microsoft-hosted jobs onto 1ES pools (except macOS), parameterizing pool/image selection across shared templates, and removing redundant hosted Azure package test jobs that duplicated integration coverage.
Changes:
- Parameterized
poolName/vmImagefor multiple CI/PR stages and jobs, switching selection to 1ES-styleimageOverridedemands. - Removed redundant hosted Linux/Windows Azure package test jobs and trimmed downstream
dependsOnaccordingly. - Passed explicit pool names into stress and Kerberos pipelines that reuse templates without importing the default CI variable groups.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| eng/pipelines/stages/verify-nuget-packages-ci-stage.yml | Parameterizes pool/image and moves verify job to 1ES pool selection. |
| eng/pipelines/stages/generate-secrets-ci-stage.yml | Parameterizes pool/image and moves secrets job to 1ES pool selection. |
| eng/pipelines/stages/build-azure-package-ci-stage.yml | Removes redundant hosted Azure test jobs; keeps macOS hosted; trims pack dependencies. |
| eng/pipelines/stages/build-abstractions-package-ci-stage.yml | Routes Linux/Windows abstractions tests to 1ES images; keeps macOS hosted. |
| eng/pipelines/pr/stages/pack-stage.yml | Parameterizes pool/image and moves PR pack stage onto 1ES pool selection. |
| eng/pipelines/pr/stages/generate-secrets-stage.yml | Parameterizes pool/image and moves PR secrets stage onto 1ES pool selection. |
| eng/pipelines/pr/stages/collect-coverage-stage.yml | Parameterizes pool/image and moves PR coverage stage onto 1ES pool selection. |
| eng/pipelines/jobs/pack-sqlserver-package-ci-job.yml | Parameterizes pool/image and moves SqlServer pack job onto 1ES pool selection. |
| eng/pipelines/jobs/pack-logging-package-ci-job.yml | Parameterizes pool/image and moves Logging pack job onto 1ES pool selection. |
| eng/pipelines/jobs/pack-azure-package-ci-job.yml | Parameterizes pool/image and moves Azure pack job onto 1ES pool selection. |
| eng/pipelines/jobs/pack-abstractions-package-ci-job.yml | Parameterizes pool/image and moves Abstractions pack job onto 1ES pool selection. |
| eng/pipelines/common/templates/jobs/ci-code-coverage-job.yml | Parameterizes pool/image and moves coverage publish job onto 1ES pool selection. |
| eng/pipelines/ci/stress/sqlclient-ci-stress-pipeline.yml | Explicitly passes poolName/vmImage for secrets stage (no CI vars imported). |
| eng/pipelines/ci/kerberos/sqlclient-ci-kerberos-pipeline.yml | Explicitly passes poolName/vmImage for code coverage job (no CI vars imported). |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
b75fd7d to
8fb349a
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated no new comments.
Suppressed comments (2)
eng/pipelines/stages/generate-secrets-ci-stage.yml:60
- The comment says “any Linux image … will do”, but this job is actually pinned to a specific image via the imageOverride demand (defaulting to ADO-UB24-SQL25). This can confuse future edits (e.g., someone might remove/alter the demand thinking it’s unnecessary). Update the comment to clarify that the job only requires a Linux agent, but is still selecting a specific pool image via vmImage/imageOverride.
pool:
# We don't need anything special, so any Linux image in our 1ES pool
# will do.
eng/pipelines/pr/stages/generate-secrets-stage.yml:60
- The comment says “any Linux image … will do”, but this job is actually pinned to a specific image via the imageOverride demand (defaulting to ADO-UB24-SQL25). Update the comment to make it clear the job requires Linux but still selects an explicit pool image via vmImage/imageOverride, to avoid confusion when someone changes pool settings later.
pool:
# We don't need anything special, so any Linux image in our 1ES pool
# will do.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated no new comments.
Suppressed comments (1)
eng/pipelines/github-sync-pipeline.yml:67
- PR description states
eng/pipelines/github-sync-pipeline.ymlis "out of scope and untouched" and still uses a hosted image, but this PR changes the job pool to 1ES with animageOverridedemand. Please reconcile this by either updating the PR description (if the change is intended) or reverting this pool change (if it’s truly out of scope).
# This pipeline only ever runs in the ADO.Net project, but the pool is
# selected conditionally to match the convention used by the other
# pipelines in this repo.
pool:
${{ if eq(variables['System.TeamProject'], 'ADO.Net') }}:
22e6b04 to
1aa857c
Compare
|
Also addressing the two suppressed comments from the earlier review passes:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated no new comments.
Suppressed comments (1)
eng/pipelines/github-sync-pipeline.yml:67
- PR description says
eng/pipelines/github-sync-pipeline.ymlis “out of scope and untouched” and still uses a hosted image, but this diff switches it to 1ES pools with animageOverridedemand. Please either update the PR description to include this pipeline in scope, or revert this file change to keep the stated “remaining hosted usage” accurate.
# This pipeline only ever runs in the ADO.Net project, but the pool is
# selected conditionally to match the convention used by the other
# pipelines in this repo.
pool:
${{ if eq(variables['System.TeamProject'], 'ADO.Net') }}:
There was a problem hiding this comment.
This is a good step to having consistent pool and image selection for our pipline jobs, and getting us off the generic Azure Pipelines pool except for macOS.
I would like to see us using the minimal image wherever possible to save time and resources - i.e. only use an image with a SQL Server if we're running integration tests that need it. Jobs that build, pack, run unit/functional tests, or use a remote SQL Server don't need a local SQL Server. We also don't need the large MMS tooling (that includes Visual Studio and a bunch of other stuff) for most (all?) of our jobs. I realize that some of our SQL Server images are currently based on MMS, so for now we can't avoid it with the local integration jobs.
We currently have ADO-Win25 and ADO-UB24 in both 1ES pools, and those can be used for these legacy pipeline non-integration jobs. The nascent 1ES Pipeline Plan will have us creating new images to meet our new PR/CI pipeline needs, and we can use those in the new pipelines once they are created. I don't expect ADO-Win25 and ADO-UB24 to survive that transition.
I'm also wondering if we really need the pool and image names to be configurable. Do we plan to change either regularly? Would it be sufficient to put the pool name selection in a common template and expose it as a static variable that can be used as ${{ variables.poolName }} at template-expansion time? The image names are essentially hardcoded already anyway, so that's fine.
1aa857c to
0d48a08
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated no new comments.
Suppressed comments (10)
eng/pipelines/stages/verify-nuget-packages-ci-stage.yml:77
- The
${{ if eq(parameters.poolName, 'Azure Pipelines') }}branch is evaluated at template-expansion time. IfpoolNameis provided via a runtime macro (e.g. the default$(ci_var_defaultPoolName)), this comparison will never match, so the job will still take the 1ESdemands: imageOverridepath even when the variable resolves toAzure Pipelinesat runtime (hosted agents), causing the job to fail.
${{ if eq(parameters.poolName, 'Azure Pipelines') }}:
vmImage: ${{ parameters.vmImage }}
# Images provided by 1ES must be selected using a demand.
${{ else }}:
demands:
eng/pipelines/stages/generate-secrets-ci-stage.yml:69
- This pool-type switch uses a compile-time condition (
${{ if eq(parameters.poolName, 'Azure Pipelines') }}), but the defaultpoolNameis the runtime macro$(ci_var_defaultPoolName). If that macro ever resolves toAzure Pipelinesat runtime, the condition still won’t match and the job will incorrectly use the 1ESimageOverridedemand on a hosted pool.
${{ if eq(parameters.poolName, 'Azure Pipelines') }}:
vmImage: ${{ parameters.vmImage }}
# Images provided by 1ES must be selected using a demand.
${{ else }}:
demands:
eng/pipelines/common/templates/jobs/ci-code-coverage-job.yml:46
- The hosted-vs-1ES pool selection relies on
${{ if eq(parameters.poolName, 'Azure Pipelines') }}, which is evaluated during template expansion. Because the defaultpoolNameis$(ci_var_defaultPoolName)(a runtime macro), this condition can’t detect a hosted pool chosen via that variable and will still emit the 1ESimageOverridedemands block.
${{ if eq(parameters.poolName, 'Azure Pipelines') }}:
vmImage: ${{ parameters.vmImage }}
# Images provided by 1ES must be selected using a demand.
${{ else }}:
demands:
eng/pipelines/jobs/pack-sqlserver-package-ci-job.yml:79
- The condition
${{ if eq(parameters.poolName, 'Azure Pipelines') }}is compile-time, butpoolNamedefaults to the runtime macro$(ci_var_defaultPoolName). If that macro resolves toAzure Pipelines(hosted) at runtime, this template will still take thedemands: imageOverridebranch and fail on hosted agents.
${{ if eq(parameters.poolName, 'Azure Pipelines') }}:
vmImage: ${{ parameters.vmImage }}
# Images provided by 1ES must be selected using a demand.
${{ else }}:
demands:
eng/pipelines/jobs/pack-logging-package-ci-job.yml:83
- Because
${{ if eq(parameters.poolName, 'Azure Pipelines') }}is evaluated at template-expansion time, it can’t see the resolved value of the default runtime macro$(ci_var_defaultPoolName). If that variable ever points to the hostedAzure Pipelinespool, the template will still emit the 1ESimageOverridedemands branch and the job will fail.
${{ if eq(parameters.poolName, 'Azure Pipelines') }}:
vmImage: ${{ parameters.vmImage }}
# Images provided by 1ES must be selected using a demand.
${{ else }}:
demands:
eng/pipelines/jobs/pack-azure-package-ci-job.yml:119
- This template’s hosted-vs-1ES branching is compile-time (
${{ if eq(parameters.poolName, 'Azure Pipelines') }}), but the default pool name is the runtime macro$(ci_var_defaultPoolName). If that macro resolves toAzure Pipelinesat runtime, the hosted branch will not be selected and the job will still run with 1ESimageOverridedemands, which hosted agents don’t satisfy.
${{ if eq(parameters.poolName, 'Azure Pipelines') }}:
vmImage: ${{ parameters.vmImage }}
# Images provided by 1ES must be selected using a demand.
${{ else }}:
demands:
eng/pipelines/jobs/pack-abstractions-package-ci-job.yml:107
- The
${{ if eq(parameters.poolName, 'Azure Pipelines') }}check is evaluated during template expansion, but the defaultpoolNameis$(ci_var_defaultPoolName)(runtime). If that macro ever resolves toAzure Pipelines, this template will still emit the 1ESimageOverridedemands branch and fail when run on hosted agents.
${{ if eq(parameters.poolName, 'Azure Pipelines') }}:
vmImage: ${{ parameters.vmImage }}
# Images provided by 1ES must be selected using a demand.
${{ else }}:
demands:
eng/pipelines/pr/stages/pack-stage.yml:73
- The pool-type switch uses a compile-time template expression (
${{ if eq(parameters.poolName, 'Azure Pipelines') }}), butpoolNamedefaults to$(PoolNameDefault)(runtime macro from a variable group). IfPoolNameDefaultresolves toAzure Pipelines, this condition still won’t match and the stage will incorrectly use the 1ESimageOverridedemands path, failing on hosted agents.
${{ if eq(parameters.poolName, 'Azure Pipelines') }}:
vmImage: ${{ parameters.vmImage }}
# Images provided by 1ES must be selected using a demand.
${{ else }}:
demands:
eng/pipelines/pr/stages/generate-secrets-stage.yml:69
${{ if eq(parameters.poolName, 'Azure Pipelines') }}is evaluated at template-expansion time, so it can’t detect that the runtime macro$(PoolNameDefault)resolved toAzure Pipelinesat runtime. In that scenario the 1ESimageOverridedemand branch will still be emitted and the hosted job will fail.
${{ if eq(parameters.poolName, 'Azure Pipelines') }}:
vmImage: ${{ parameters.vmImage }}
# Images provided by 1ES must be selected using a demand.
${{ else }}:
demands:
eng/pipelines/pr/stages/collect-coverage-stage.yml:47
- The branch between hosted (
vmImage) and 1ES (demands: imageOverride) is compile-time (${{ if eq(parameters.poolName, 'Azure Pipelines') }}), but the default pool name is the runtime macro$(PoolNameDefault). If the variable group setsPoolNameDefaulttoAzure Pipelines, the condition will still not match and this stage will emit the 1ES demands block, which will fail on hosted agents.
${{ if eq(parameters.poolName, 'Azure Pipelines') }}:
vmImage: ${{ parameters.vmImage }}
# Images provided by 1ES must be selected using a demand.
${{ else }}:
demands:
This was the last job outside of macOS still running on a Microsoft-hosted agent. Move it to ADO-UB24-SQL25 on the 1ES pool, selecting the pool based on the project the way the stress and package pipelines do. The job runs a PowerShell script with pwsh, which the ADO-UB24-SQL25 image already provides -- the stress job relies on the same thing without installing PowerShell first. After this change, the only remaining Microsoft-hosted jobs are the macOS ones, since our 1ES pools do not offer macOS images. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 10246002-c950-42a7-adf5-1698f9af4b3d
The pack, secrets, coverage and NuGet verification templates now take poolName/vmImage parameters, but selected the image with a 1ES imageOverride demand unconditionally. That breaks if a caller (or a variable group that has not been migrated yet) still points poolName at the hosted 'Azure Pipelines' pool, which requires vmImage instead. Use the same conditional pool block the test-* job templates already use, so these templates work with either pool type. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 10246002-c950-42a7-adf5-1698f9af4b3d
0d48a08 to
410e337
Compare
Retire every SQL Server 2022 agent image in favour of the SQL Server 2025
equivalents:
ADO-MMS22-SQL22 -> ADO-MMS25-SQL25
ADO-UB22-SQL22 -> ADO-UB24-SQL25
This covers the CI test configurations, the PR pipeline platform list,
the Azure package integration test jobs (including the SQL root path,
which becomes SQL25RootPath), the Managed Instance jobs, the stress test
jobs, and the Linux enclave configuration.
Two notes on the change:
- CI test stage names derive from the image keys, so stages such as
Win22_Sql22 are now named Win25_Sql25. Any branch policies or
required status checks that reference the old stage names will need
to be updated.
- The Linux SQL configuration previously ran on both ADO-UB20-SQL22
and ADO-UB22-SQL22. We only have a single Ubuntu SQL 2025 image, so
it now runs on ADO-UB24-SQL25 alone.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 10246002-c950-42a7-adf5-1698f9af4b3d
The Linux enclave image key doubles as the generated ADO stage name and is referenced by branch policies and required status checks, so it is kept as-is. The 'Sql19' suffix also remains accurate because these tests target a remote Enclave-enabled SQL Server 2019; only the agent image moved to Ubuntu 24. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 10246002-c950-42a7-adf5-1698f9af4b3d
The SQL Server 2025 agent images ship the engine but not the command line
tools, so the Linux SQL configuration steps failed with:
ERROR: 'sqlcmd' was not found on PATH or in the standard mssql-tools locations.
Add a shared 'Install sqlcmd [Linux]' step that reuses an existing sqlcmd when
the image provides one and otherwise installs mssql-tools18, then publishes the
resolved path via the SqlCmdBin variable. Both the PR and CI Linux
configuration steps now run it, and the CI step no longer hardcodes
/opt/mssql-tools/bin/sqlcmd, which does not exist on these images.
sqlcmd from mssql-tools18 encrypts by default, so the step also publishes
SqlCmdTrustArg ('-C') to trust the local server's self-signed certificate.
Without it every connection to localhost would fail certificate validation.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 10246002-c950-42a7-adf5-1698f9af4b3d
Introduce primaryTargetFrameworks and primaryTargetFrameworksUnix, which apply only to the primary test configurations: local SQL Server 2025 and Azure SQL, on both Windows and Linux. Those configurations now run net10.0 in addition to the existing target frameworks. Restricting .NET 10 to the primary configurations keeps the added agent cost bounded rather than multiplying it across every legacy SQL Server image. The other pipelines that extend the CI core pin the new parameters to their existing target framework lists, so their behaviour is unchanged. Note that the driver itself only targets net462, net8.0, and net9.0, so the net10.0 test assemblies resolve the net9.0 driver build. These jobs therefore validate the driver on the .NET 10 runtime rather than validating a .NET 10 build of the driver. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 10246002-c950-42a7-adf5-1698f9af4b3d
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 19 changed files in this pull request and generated no new comments.
Suppressed comments (13)
eng/pipelines/stages/verify-nuget-packages-ci-stage.yml:73
- The pool block always selects the agent image via an
imageOverridedemand. IfpoolNameis set toAzure Pipelines, this job will fail because hosted agents requirevmImageselection and don’t expose theimageOverridecapability. Use the same conditional pool logic used ineng/pipelines/jobs/test-azure-package-ci-job.yml/test-abstractions-package-ci-job.yml.
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/stages/generate-secrets-ci-stage.yml:67
- This stage always uses an
imageOverridedemand to select the image. IfpoolNameisAzure Pipelines, hosted agents requirevmImageand the job won’t start. Add the same Azure Pipelines vs 1ES conditional pool block used by the test job templates.
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/stages/compute-versions-ci-stage.yml:47
- The pool block always uses an
imageOverridedemand. If a caller setspoolName: Azure Pipelines, this will fail because hosted pools require specifyingvmImageinstead of a demand. Match the conditional pool selection pattern used in the test job templates.
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/common/templates/jobs/ci-code-coverage-job.yml:42
- This job template always selects the image via an
imageOverridedemand, which breaks ifpoolNameis ever set to the hostedAzure Pipelinespool (hosted agents requirevmImage). Consider using the same conditional pool block used by the test job templates to support both pool types.
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/pr/stages/pack-stage.yml:69
- This PR stage always selects the image via an
imageOverridedemand. IfPoolNameDefault(or a caller override) points atAzure Pipelines, this won’t work because hosted pools requirevmImage. Use the same conditional pool selection pattern as the test job templates.
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/pr/stages/generate-secrets-stage.yml:63
- This PR secrets stage always uses an
imageOverridedemand to select the image. If the pool isAzure Pipelines(or becomes it during rollout), hosted agents requirevmImageinstead. Add the Azure Pipelines vs 1ES conditional pool block used elsewhere.
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/pr/stages/collect-coverage-stage.yml:43
- This PR coverage collection stage always selects the agent image via an
imageOverridedemand. IfpoolNameisAzure Pipelines, hosted agents requirevmImageselection instead, so the job would fail to queue. Use the same conditional pool block as the test job templates.
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/jobs/pack-sqlserver-package-ci-job.yml:75
- This job template always selects the agent image via an
imageOverridedemand. IfpoolNameis set toAzure Pipelines, hosted pools requirevmImageselection and the job will fail to queue. Use the same conditional pool block used by thetest-*job templates.
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/jobs/pack-logging-package-ci-job.yml:76
- This job template always selects the agent image via an
imageOverridedemand. IfpoolNameis everAzure Pipelines, hosted pools requirevmImageselection and don’t expose theimageOverridecapability. Add the Azure Pipelines vs 1ES conditional pool block used in other templates.
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/jobs/pack-azure-package-ci-job.yml:99
- This job template always uses an
imageOverridedemand to pick the VM image. IfpoolNameisAzure Pipelines, hosted pools requirevmImageselection, so this job would fail. Use the same conditional pool logic used bytest-azure-package-ci-job.yml.
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/jobs/pack-abstractions-package-ci-job.yml:93
- This job template always selects the agent image via an
imageOverridedemand. IfpoolNameis set toAzure Pipelines, hosted pools requirevmImageand don’t provideimageOverride. Add the same conditional pool block used in thetest-*job templates.
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/dotnet-sqlclient-ci-core.yml:506
- The stage name key
Win22_Azure_Sqlno longer matches the agent image (ADO-Win25/ Windows Server 2025). Sinceci-run-tests-stage.ymlusesimage.keyas the stage name, this mismatch is easy to misinterpret later (and suggests the stage is still on Win22). Either rename the key toWin25_Azure_Sql, or add a NOTE explaining why the key is intentionally kept asWin22_*despite running on Win25.
windows_azure_sql:
pool: ${{parameters.defaultPoolName }}
images:
Win22_Azure_Sql: ADO-Win25
Win11_Azure_Sql: ADO-CI-Win11
eng/pipelines/dotnet-sqlclient-ci-core.yml:639
Win22_Enclave_Sql19is used as the generated stage name (seeci-run-tests-stage.yml), but it now runs onADO-Win25. If this key is intentionally kept for branch policy/status check compatibility (similar to the note onUbuntu20_Enclave_Sql19), add an explicit NOTE here as well; otherwise, consider renaming it toWin25_Enclave_Sql19to avoid misleading stage names.
windows_enclave_sql:
pool: ADO-CI-AE-1ES-Pool
images:
Win22_Enclave_Sql19: ADO-Win25
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 19 changed files in this pull request and generated no new comments.
Suppressed comments (11)
eng/pipelines/stages/verify-nuget-packages-ci-stage.yml:73
- The pool block selects the image via an
imageOverridedemand unconditionally. That works for 1ES pools, but will fail ifpoolNameis ever set to the hostedAzure Pipelinespool (which requiresvmImageselection), contradicting the template’s intent to support both pool types.
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/stages/generate-secrets-ci-stage.yml:67
- This pool block uses an
imageOverridedemand unconditionally. If a caller setspoolName: Azure Pipelines, the job won’t start because hosted agents don’t support selecting images via demands (they requirevmImage).
pool:
# This job has no special image requirements, so use a minimal Linux image.
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/stages/compute-versions-ci-stage.yml:47
- The template parameterizes
poolName/vmImage, but the job’s pool block still assumes a 1ES pool by always using animageOverridedemand. This breaks reuse with the hostedAzure Pipelinespool, which requiresvmImage.
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/common/templates/jobs/ci-code-coverage-job.yml:42
- This job template selects the VM image via an
imageOverridedemand only. IfpoolNameis ever set to the hostedAzure Pipelinespool, the job will fail because hosted agents requirevmImageinstead of a demand-based image selector.
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/jobs/pack-sqlserver-package-ci-job.yml:75
- This pack job template always selects the image via an
imageOverridedemand. That works for 1ES pools but will fail ifpoolNameis set to the hostedAzure Pipelinespool (which requiresvmImage).
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/jobs/pack-logging-package-ci-job.yml:76
- This pack job template assumes a 1ES pool by unconditionally using an
imageOverridedemand. If a caller usespoolName: Azure Pipelines, the job won’t be able to select an image and will fail to queue.
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/jobs/pack-azure-package-ci-job.yml:99
- This pack job template selects the image via an
imageOverridedemand only. That won’t work ifpoolNameis set to the hostedAzure Pipelinespool, which requiresvmImageselection instead of a demand.
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/jobs/pack-abstractions-package-ci-job.yml:93
- This pack job template assumes a 1ES pool by always using an
imageOverridedemand. IfpoolNameis ever set to the hostedAzure Pipelinespool, the job will fail because hosted agents requirevmImage.
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/pr/stages/pack-stage.yml:69
- This PR stage always selects the image via an
imageOverridedemand. IfPoolNameDefaultis (or becomes)Azure Pipelines, the stage will fail because hosted agents require image selection viavmImage.
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/pr/stages/generate-secrets-stage.yml:63
- This PR secrets stage assumes a 1ES pool by unconditionally using an
imageOverridedemand. If a caller uses the hostedAzure Pipelinespool, the job won’t start because hosted agents requirevmImageselection.
pool:
# This job has no special image requirements, so use a minimal Linux image.
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
eng/pipelines/pr/stages/collect-coverage-stage.yml:43
- This PR coverage stage selects the VM image via an
imageOverridedemand only. That will fail ifPoolNameDefaultis set to the hostedAzure Pipelinespool, which requiresvmImageinstead.
pool:
name: ${{ parameters.poolName }}
demands:
- imageOverride -equals ${{ parameters.vmImage }}
Stacked PR 3 of 3. Targets
dev/automation/ci-net10-coverage(#4514) - review #4513 and #4514 first.Summary
Every job that previously ran on the Microsoft-hosted
Azure Pipelinespool now runs on our 1ES pools. The sole exception is macOS, since our 1ES pools do not offer macOS images.ADO-UB24-SQL25(orADO-MMS25-SQL25for verify-nuget, which needs Windows).ADO-UB24-SQL25andADO-MMS25-SQL25.pack_azure_package_jobdependencies were trimmed accordingly.ci-build-variables.ymlnorsqlclient-testconfig-v1, so the default pool variables are not defined there.ADO-UB24/ADO-Win25and ontoADO-UB24-SQL25/ADO-MMS25-SQL25.ubuntu-latestimage and ontoADO-UB24-SQL25, using the same internal/public conditional pool convention as the other pipelines.pwshis available natively on that image, so no install step is needed.poolName/vmImage. Selecting the image with a 1ESimageOverridedemand unconditionally would break any caller still pointing at the hostedAzure Pipelinespool, which requiresvmImageinstead. These templates now use the same conditional pool block thetest-*job templates already use.Remaining hosted usage
Intentionally retained, all macOS:
dotnet-sqlclient-ci-core.yml- macOS test configurationstages/build-azure-package-ci-stage.yml- macOS Azure package jobstages/build-abstractions-package-ci-stage.yml- macOS abstractions jobci/stress/sqlclient-ci-stress-stage.yml- macOS stress jobThere is no remaining non-macOS use of a Microsoft-hosted image in
eng/pipelines.Action required before merge
ADO-MMS25-SQL25andADO-UB24-SQL25must be available in bothADO-1ES-PoolandADO-CI-1ES-Pool, since the package and GitHub sync pipelines select the pool based on the project they run in.Checklist
All modified YAML files parse cleanly. These changes have not yet been executed against Azure DevOps. Capacity planning note: this shifts load onto the 1ES pools, so agent allocation should be reviewed before merge.