How do you create a basic YAML build pipeline for a .NET or Node.js project in Azure DevOps?
Quick Answer
Create an azure-pipelines.yml file in your repo root defining a trigger, agent pool, and build steps. Azure DevOps detects the file and offers to create the pipeline, or you can use az pipelines create to wire it up via CLI.
Detailed Answer
Think of a YAML pipeline file like a recipe card you tape to your refrigerator. Anyone who opens the fridge (clones the repo) immediately knows exactly how to cook the dish (build the project) without asking the chef (searching through a GUI for hidden configuration).
The minimum viable YAML pipeline has three elements: a trigger that specifies which branches activate the pipeline, a pool that defines which agent runs the work, and steps that list the actual build commands. For a .NET project, the steps typically include restore, build, test, and publish. For Node.js, they include npm install, lint, test, and build. Azure DevOps provides starter templates when you create a new pipeline through the portal, automatically detecting your project type.
When the pipeline runs, Azure DevOps provisions a fresh agent from the specified pool. Microsoft-hosted agents come pre-installed with common SDKs (.NET, Node.js, Python, Java, Go) and tools (Docker, kubectl, Terraform). The agent clones your repository, executes each step sequentially, and reports results back. Build artifacts like compiled binaries or Docker images can be published for downstream stages.
In production, even a basic pipeline should include caching for package restore (to speed up builds from 5 minutes to 90 seconds), test result publishing (so failures appear in the PR UI), and branch filters (to avoid running on documentation-only branches). The variables section externalizes configuration like SDK versions so upgrades require changing one line.
The most common gotcha for beginners is indentation errors in YAML causing cryptic parse failures. Azure DevOps provides a YAML editor with IntelliSense in the portal, but many teams prefer editing locally with the Azure Pipelines VS Code extension that provides schema validation. Another frequent issue is the agent not having a required tool version — use the UseDotNet@2 or NodeTool@0 tasks to explicitly install the version you need rather than relying on whatever is pre-installed.
Code Example
# azure-pipelines.yml — Basic .NET build pipeline for payments-api
trigger:
- main
- feature/*
pool:
vmImage: 'ubuntu-latest'
variables:
buildConfiguration: 'Release'
dotnetVersion: '8.0.x'
steps:
- task: UseDotNet@2
displayName: 'Install .NET SDK'
inputs:
packageType: 'sdk'
version: '$(dotnetVersion)'
- task: DotNetCoreCLI@2
displayName: 'Restore NuGet packages'
inputs:
command: 'restore'
projects: 'src/payments-api/**/*.csproj'
feedsToUse: 'select'
vstsFeed: 'contoso-internal-feed'
- task: DotNetCoreCLI@2
displayName: 'Build payments-api'
inputs:
command: 'build'
projects: 'src/payments-api/**/*.csproj'
arguments: '--configuration $(buildConfiguration) --no-restore'
- task: DotNetCoreCLI@2
displayName: 'Run unit tests'
inputs:
command: 'test'
projects: 'tests/**/*.csproj'
arguments: '--configuration $(buildConfiguration) --collect:"XPlat Code Coverage"'
- task: PublishTestResults@2
displayName: 'Publish test results'
inputs:
testResultsFormat: 'VSTest'
testResultsFiles: '**/*.trx'
---
# azure-pipelines.yml — Basic Node.js pipeline for fraud-detector
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
displayName: 'Use Node.js 20.x'
inputs:
versionSpec: '20.x'
- script: npm ci
displayName: 'Install dependencies (clean)'
- script: npm run lint
displayName: 'Run ESLint'
- script: npm run test -- --coverage
displayName: 'Run Jest tests with coverage'
- script: npm run build
displayName: 'Build production bundle'Interview Tip
A junior engineer typically shows a pipeline with only script steps (bash commands), missing the opportunity to demonstrate knowledge of built-in tasks like DotNetCoreCLI@2 or NodeTool@0 that provide structured inputs, retry logic, and telemetry integration. Interviewers look for awareness of caching, test result publishing, and explicit SDK version pinning. Mention that you would add a Cache@2 step for node_modules or NuGet packages to cut build times significantly, and that PublishTestResults makes failures visible directly in pull request comments.