# Azure DevOps Pipelines I wanted to share the below build script as it has been a good starting point for .net 6/7/8 projects. It relies solely on the DotNetCoreCLI, NuGet CLI as well as built-in pipeline tasks. I have found that the `variables` and `conditions` used below are also commonly needed across your average-sized project. ## Break Conditions across multiple lines Since pipeline steps/tasks default to `condition: succeeded()`, we need to include that check explicitly when we overwrite the property. This example task only runs for `origin/main` and `origin/hotfix/*` builds after the previous step completed successfully. ```yaml   - task: PublishBuildArtifacts@1     displayName: 'Publish build artifacts'     condition: >       and(         succeeded(),         or(           eq(variables['Build.SourceBranch'], 'refs/heads/main'),           startsWith(variables['Build.SourceBranch'], 'refs/heads/hotfix/')         )       ) ``` ## Common pipeline template Note: - we are only building the solution **once** in the `build` step. The `test` and `package` steps are forbidden from rebuilding with the `--no-build` flag. - the `package` step produces a zip file, saving us from having to manually archive it after. ```yaml variables: azureSubscription: '<subscription connection name>' solution: '**/*.sln' #only when solution not in root folder or use workingDirectory property on steps buildConfiguration: 'Release' artifactName: '<artifact name>' trigger: branches: include: - "main" #paths: # include: # - '<optionally filter which paths should trigger a build>' jobs: - job: 'JobCI' timeoutInMinutes: 0 workspace: clean: all pool: vmImage: 'windows-latest' steps: - task: NuGetToolInstaller@1 displayName: 'NuGet: tool install' - task: NuGetCommand@2 displayName: 'NuGet: restore' inputs: command: restore restoreSolution: '$(solution)' feedsToUse: 'select' - task: DotNetCoreCLI@2 displayName: 'Build' inputs: command: 'build' projects: '$(solution)' configuration: '$(buildConfiguration)' - task: DotNetCoreCLI@2 displayName: 'Test' inputs: command: 'test' projects: '**/*.Tests.csproj' configuration: '$(buildConfiguration)'       arguments: '--no-build' # Steps ABOVE run without condition, incl. pre-merge Build Validation for PRs. # Steps BELOW only run AFTER the PR is merged. - task: DotNetCoreCLI@2 displayName: 'Package' condition: > and( succeeded(), or( eq(variables['Build.SourceBranch'], 'refs/heads/main'), startsWith(variables['Build.SourceBranch'], 'refs/heads/hotfix/') ) ) inputs: command: publish publishWebProjects: true zipAfterPublish: true configuration: '$(buildConfiguration)' arguments: '--no-build --output $(Build.ArtifactStagingDirectory)/$(artifactName)' - task: PublishBuildArtifacts@1 displayName: 'Publish build artifacts' condition: > and( succeeded(), or( eq(variables['Build.SourceBranch'], 'refs/heads/main'), startsWith(variables['Build.SourceBranch'], 'refs/heads/hotfix/') ) ) inputs: PathtoPublish: '$(Build.ArtifactStagingDirectory)/$(artifactName)' ArtifactName: 'drop' publishLocation: 'Container' ``` ## Commonly used built-in vars - $(Build.ArtifactStagingDirectory) - $(Build.SourceBranch) #ado #azuredevops #ci #cicd