$npx -y skills add wshaddix/dotnet-skills --skill dotnet-ado-patternsDesigning composable Azure DevOps YAML pipelines. Templates, variable groups, multi-stage, triggers.
| 1 | # dotnet-ado-patterns |
| 2 | |
| 3 | Composable Azure DevOps YAML pipeline patterns for .NET projects: template references with `extends`, `stages`, `jobs`, and `steps` keywords for hierarchical pipeline composition, variable groups and variable templates for centralized configuration, pipeline decorators for organization-wide policy injection, conditional insertion with `${{ if }}` and `${{ each }}` expressions, multi-stage pipelines (build, test, deploy), and pipeline triggers for CI, PR, and scheduled runs. |
| 4 | |
| 5 | **Version assumptions:** Azure Pipelines YAML schema. `DotNetCoreCLI@2` task for .NET 8/9/10 builds. Template expressions syntax v2. |
| 6 | |
| 7 | **Scope boundary:** This skill owns composable pipeline design patterns for Azure DevOps YAML. Starter CI templates (basic build/test/pack) are owned by [skill:dotnet-add-ci] -- this skill extends those templates with advanced composition. CLI-specific release pipelines (build-package-release for CLI binaries) are owned by [skill:dotnet-cli-release-pipeline] -- this skill covers general pipeline patterns that CLI pipelines consume. ADO-unique features (environments with approvals, service connections, classic releases) are in [skill:dotnet-ado-unique]. |
| 8 | |
| 9 | **Out of scope:** Starter CI templates -- see [skill:dotnet-add-ci]. CLI release pipelines (tag-triggered build-package-release for CLI tools) -- see [skill:dotnet-cli-release-pipeline]. ADO-unique features (environments, service connections, classic releases) -- see [skill:dotnet-ado-unique]. Build/test specifics -- see [skill:dotnet-ado-build-test]. Publishing pipelines -- see [skill:dotnet-ado-publish]. GitHub Actions workflow patterns -- see [skill:dotnet-gha-patterns]. |
| 10 | |
| 11 | Cross-references: [skill:dotnet-add-ci] for starter templates that these patterns extend, [skill:dotnet-cli-release-pipeline] for CLI-specific release automation. |
| 12 | |
| 13 | --- |
| 14 | |
| 15 | ## Template References |
| 16 | |
| 17 | ### Stage Templates |
| 18 | |
| 19 | Stage templates define reusable pipeline stages that callers insert into their multi-stage pipeline: |
| 20 | |
| 21 | ```yaml |
| 22 | # templates/stages/build-test.yml |
| 23 | parameters: |
| 24 | - name: dotnetVersion |
| 25 | type: string |
| 26 | default: '8.0.x' |
| 27 | - name: buildConfiguration |
| 28 | type: string |
| 29 | default: 'Release' |
| 30 | - name: projects |
| 31 | type: string |
| 32 | default: '**/*.sln' |
| 33 | |
| 34 | stages: |
| 35 | - stage: Build |
| 36 | displayName: 'Build and Test' |
| 37 | jobs: |
| 38 | - job: BuildJob |
| 39 | pool: |
| 40 | vmImage: 'ubuntu-latest' |
| 41 | steps: |
| 42 | - task: UseDotNet@2 |
| 43 | displayName: 'Install .NET SDK' |
| 44 | inputs: |
| 45 | packageType: 'sdk' |
| 46 | version: ${{ parameters.dotnetVersion }} |
| 47 | |
| 48 | - task: DotNetCoreCLI@2 |
| 49 | displayName: 'Restore' |
| 50 | inputs: |
| 51 | command: 'restore' |
| 52 | projects: ${{ parameters.projects }} |
| 53 | |
| 54 | - task: DotNetCoreCLI@2 |
| 55 | displayName: 'Build' |
| 56 | inputs: |
| 57 | command: 'build' |
| 58 | projects: ${{ parameters.projects }} |
| 59 | arguments: '-c ${{ parameters.buildConfiguration }} --no-restore' |
| 60 | ``` |
| 61 | |
| 62 | ### Calling a Stage Template |
| 63 | |
| 64 | ```yaml |
| 65 | # azure-pipelines.yml |
| 66 | trigger: |
| 67 | branches: |
| 68 | include: |
| 69 | - main |
| 70 | |
| 71 | stages: |
| 72 | - template: templates/stages/build-test.yml |
| 73 | parameters: |
| 74 | dotnetVersion: '9.0.x' |
| 75 | buildConfiguration: 'Release' |
| 76 | projects: 'MyApp.sln' |
| 77 | |
| 78 | - template: templates/stages/deploy.yml |
| 79 | parameters: |
| 80 | environment: 'staging' |
| 81 | ``` |
| 82 | |
| 83 | ### Job Templates |
| 84 | |
| 85 | Job templates encapsulate a complete job with its pool and steps: |
| 86 | |
| 87 | ```yaml |
| 88 | # templates/jobs/dotnet-build.yml |
| 89 | parameters: |
| 90 | - name: dotnetVersion |
| 91 | type: string |
| 92 | default: '8.0.x' |
| 93 | - name: projects |
| 94 | type: string |
| 95 | |
| 96 | jobs: |
| 97 | - job: Build |
| 98 | pool: |
| 99 | vmImage: 'ubuntu-latest' |
| 100 | steps: |
| 101 | - task: UseDotNet@2 |
| 102 | inputs: |
| 103 | packageType: 'sdk' |
| 104 | version: ${{ parameters.dotnetVersion }} |
| 105 | |
| 106 | - task: DotNetCoreCLI@2 |
| 107 | displayName: 'Build' |
| 108 | inputs: |
| 109 | command: 'build' |
| 110 | projects: ${{ parameters.projects }} |
| 111 | arguments: '-c Release' |
| 112 | ``` |
| 113 | |
| 114 | ### Step Templates |
| 115 | |
| 116 | Step templates define reusable step sequences inserted into an existing job: |
| 117 | |
| 118 | ```yaml |
| 119 | # templates/steps/dotnet-setup.yml |
| 120 | parameters: |
| 121 | - name: dotnetVersion |
| 122 | type: string |
| 123 | default: '8.0.x' |
| 124 | - name: nugetFeed |
| 125 | type: string |
| 126 | default: '' |
| 127 | |
| 128 | steps: |
| 129 | - task: UseDotNet@2 |
| 130 | displayName: 'Install .NET SDK ${{ parameters.dotnetVersion }}' |
| 131 | inputs: |
| 132 | packageType: 'sdk' |
| 133 | version: ${{ parameters.dotnetVersion }} |
| 134 | |
| 135 | - ${{ if ne(parameters.nugetFeed, '') }}: |
| 136 | - task: NuGetAuthenticate@1 |
| 137 | displayName: 'Authenticate NuGet feed' |
| 138 | |
| 139 | - task: DotNetCoreCLI@2 |
| 140 | displayName: 'Restore packages' |
| 141 | inputs: |
| 142 | command: 'restore' |
| 143 | projects: '**/*.sln' |
| 144 | ${{ if ne(parameters.nugetFeed, '') }}: |
| 145 | feedsToUse: 'select' |
| 146 | vstsFeed: ${{ parameters.nugetFeed }} |
| 147 | ``` |
| 148 | |
| 149 | ### Using Step Templates in a Pi |