DevOps / .NET
Building a Production NuGet Pipeline with Azure DevOps
April 2026 / 6 min read
Posted by Tarek Fawaz
When we extracted our IoT telemetry protocol parser into a standalone NuGet package, we needed a pipeline that publishes stable releases from master and prerelease packages from feature branches - automatically, with proper semantic versioning.
The Goal
Merges to master produce stable versions like 1.2.0. Merges to develop produce 1.2.0-beta.42. Feature branches produce 1.2.0-feature-gps-parser.42.
The Cross-Stage Variable Problem
Azure DevOps multi-stage pipelines have a subtle gotcha: variables set in one stage are not automatically available in subsequent stages. The fix is isOutput=true combined with stageDependencies:
# In the Version stage
- script: |
echo "##vso[task.setvariable variable=pkgVersion;isOutput=true]$(version)"
name: setVersion
# In the Build stage
variables:
packageVersion: $[stageDependencies.Version.ComputeVersion.outputs['setVersion.pkgVersion']]The syntax is stageDependencies.{Stage}.{Job}.outputs['{Step}.{Variable}'].
Branch-Based Versioning
trigger:
branches:
include: [master, develop, feature/*]
stages:
- stage: Version
jobs:
- job: ComputeVersion
steps:
- script: |
BASE=$(grep -oP '(?<=<Version>).*(?=</Version>)' src/*.csproj)
BRANCH=$(echo $BUILD_SOURCEBRANCH | sed 's|refs/heads/||')
if [ "$BRANCH" = "master" ]; then
VERSION="$BASE"
else
SUFFIX=$(echo $BRANCH | sed 's|feature/||;s|/|-|g')
VERSION="$BASE-$SUFFIX.$BUILD_BUILDID"
fi
echo "##vso[task.setvariable variable=pkgVersion;isOutput=true]$VERSION"
name: setVersionKey Lessons
isOutput=trueis mandatory for cross-stage variables- Use
stageDependencies, notdependencies - Test YAML changes on feature branches first
- Pin your .NET SDK version in
global.json
Internal packages deserve the same CI/CD rigor as your main applications.
Need DevOps pipelines for .NET? Get in touch.
Share this post
Instagram doesn't support direct web sharing — we copy a ready-to-paste caption to your clipboard.
