# 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