Package Management: Feeds, Versioning & Upstream
Design package management with Azure Artifacts and GitHub Packages. Configure feeds, upstream sources, views, and implement versioning strategies including SemVer and CalVer.
What is package management in DevOps?
Think of a supermarketβs supply chain.
Your supermarket doesnβt grow its own tomatoes β it gets them from trusted suppliers, stores them in a warehouse, and puts the freshest ones on the shelf. If a supplier ships a bad batch, the warehouse rejects it before it reaches customers.
Package management works the same way. Your team creates reusable code libraries (packages) and stores them in a feed (the warehouse). Pipelines and developers pull packages from the feed instead of duplicating code. The feed controls quality (views), sources (upstream connections to public registries), and versions (SemVer) β just like a warehouse controls freshness, suppliers, and stock rotation.
Azure Artifacts vs GitHub Packages
| Feature | Azure Artifacts | GitHub Packages |
|---|---|---|
| Package types | NuGet, npm, Maven, Gradle, Python (pip), Universal Packages | npm, NuGet, Maven, Gradle, Docker (Container Registry), RubyGems |
| Feed scoping | Project-scoped or organisation-scoped feeds with granular permissions | Repository-scoped or organisation-scoped, inherits GitHub permissions model |
| Upstream sources | Built-in upstream proxy β connects to public registries through the feed, caches packages locally | No built-in upstream proxy β developers configure standard registry URLs directly |
| Views (promotion) | @Local, @Prerelease, @Release β promote packages through quality stages | No built-in view system β use tags, labels, or branch conventions instead |
| Storage pricing | 2 GB free per organisation, then pay-per-GB overage | 500 MB free on free tier, higher limits on Team and Enterprise plans |
| Universal Packages | Yes β store any file type (ZIP, binaries, datasets) as a versioned package | No direct equivalent β use release assets or Container Registry for arbitrary files |
| Best for | Enterprise teams needing complex feed hierarchies, upstream proxying, and quality promotion | Teams already on GitHub wanting package hosting tightly integrated with repos and Actions |
Feeds and upstream sources
A feed is a hosted package repository β your teamβs private package store.
Project-scoped vs organisation-scoped feeds
Project-scoped feeds are visible only within a single Azure DevOps project. Use them for project-specific packages that other teams should not consume directly.
Organisation-scoped feeds are visible across all projects in the organisation. Use them for shared libraries (authentication, logging, data-access layers) that multiple teams depend on.
Decision rule: If more than one project consumes the package, it belongs in an org-scoped feed. If itβs an internal implementation detail of one project, keep it project-scoped.
Upstream sources β the proxy layer
An upstream source connects your private feed to a public registry (npmjs.com, nuget.org, pypi.org). When a developer requests a package that isnβt cached locally, Azure Artifacts fetches it from the upstream, caches it, and serves it.
Why upstream matters:
- Single feed URL β developers point to one feed, not multiple registries
- Resilience β cached packages survive public registry outages
- Security β administrators control which external packages enter the organisation
- Speed β cached packages are served from your Azure region, not a distant CDN
Developer request β Private Feed
βββ Cache hit β Serve immediately
βββ Cache miss β Fetch from upstream β Cache β Serve
Views β promoting packages through quality stages
Azure Artifacts provides three built-in views that act as quality gates for your packages:
| View | Contains | Typical Consumer |
|---|---|---|
| @Local | Everything published β including untested | Package authors, CI pipelines |
| @Prerelease | Packages that passed initial validation | QA teams, staging environments |
| @Release | Production-approved packages | Release pipelines, all production consumers |
Packages enter at @Local and are promoted (manually or via pipeline automation) through @Prerelease to @Release. Each consumer subscribes to the appropriate view.
Scenario: Jordan's feed strategy at Cloudstream Media
βοΈ Jordan Rivera at Cloudstream Media manages shared libraries consumed by 12 microservices. Before feeds, every team copy-pasted the streaming codec library into their repo β 12 copies, 12 diverging versions, zero coordination.
Jordanβs design:
- Organisation-scoped feed β
cloudstream-sharedβ accessible to all teams - Upstream sources β npmjs.com and nuget.org connected so developers never need to configure public registries
- View-based promotion β packages enter @Local on publish, move to @Prerelease after integration tests pass, and reach @Release only after QA sign-off
- Pipeline automation β the CI pipeline publishes to @Local; the release pipeline promotes to @Release after all gates pass
Avery (dev lead) asks: βCan I still use pre-release packages in dev?β Absolutely β dev environments point to @Local. Only production points to @Release.
Versioning strategies
Semantic Versioning (SemVer)
Format: MAJOR.MINOR.PATCH (e.g., 2.4.1)
| Component | When to Increment | Example |
|---|---|---|
| MAJOR | Breaking changes β API contracts change, backward compatibility broken | 1.x.x to 2.0.0 |
| MINOR | New features added β fully backward compatible | 2.3.x to 2.4.0 |
| PATCH | Bug fixes only β no new features, fully backward compatible | 2.4.0 to 2.4.1 |
Pre-release labels: 2.4.1-beta.1, 2.4.1-rc.2 β these have lower precedence than the release version (2.4.1-beta.1 sorts before 2.4.1).
Build metadata: 2.4.1+build.457 β ignored for version precedence.
Caret vs tilde ranges
This is a frequent exam target:
| Range | Meaning | Example: given ^2.4.1 | Allows |
|---|---|---|---|
| Caret (^) | Allows minor and patch updates | ^2.4.1 | 2.4.1 up to but not including 3.0.0 |
| Tilde (~) | Allows patch updates only | ~2.4.1 | 2.4.1 up to but not including 2.5.0 |
Memory trick: Tilde is tighter (both start with T) β it only allows patches. Caret is wider β it allows minor bumps too.
Calendar Versioning (CalVer)
Format: Uses dates β e.g., 2026.04 or 2026.04.21
| Format | Example | Used By |
|---|---|---|
YYYY.MM | 2026.04 | Ubuntu, Terraform providers |
YYYY.MM.DD | 2026.04.21 | pip, some internal tools |
YY.MM | 26.04 | Ubuntu (short form) |
When to use CalVer over SemVer: When releases follow a time-based schedule rather than a feature-based one, and when βwhen was this releasedβ communicates more value than βwhat changed.β
| Aspect | SemVer | CalVer |
|---|---|---|
| Communicates | What changed β breaking, feature, or fix | When it was released |
| Breaking change signal | Explicit β MAJOR version bump | None β requires release notes or changelogs |
| Best for | Libraries, APIs, NuGet/npm packages consumed by other code | Products, platforms, time-based release trains |
| Dependency ranges | Supports caret/tilde ranges for flexible version locking | Must pin exact versions β ranges are meaningless with dates |
| Exam weight | Primary strategy tested β know the rules cold | Know when to recommend it, not deep details |
Pipeline artefact versioning
Build artefacts need version stamps too. Common strategies in Azure Pipelines:
- Build ID β
$(Build.BuildId)β unique, auto-incrementing integer - Git SHA β the commit hash provides traceability back to source
- SemVer from source β extract from
package.json,.csproj, orpom.xml - Composite β
$(Major).$(Minor).$(Rev:r)β manual major/minor with auto-incrementing revision
In GitHub Actions, use github.run_number (increments per workflow) or github.sha for commit-based versioning.
Exam tip: SemVer precision on the exam
The exam tests precise SemVer rules. Watch for:
- The
0.x.xrange is considered unstable β minor bumps can include breaking changes (no stability guarantee until1.0.0) - Pre-release versions sort before the release:
1.0.0-alphacomes before1.0.0 - Build metadata (
+build.123) is ignored for precedence β1.0.0+build.1and1.0.0+build.2are considered equal - Caret on
0.x.xbehaves differently:^0.2.3only allows patch updates (same as tilde) because the major is 0
Knowledge check
Jordan wants production pipelines at Cloudstream Media to consume only QA-approved packages, while development pipelines should access everything including untested packages. What should Jordan configure?
A shared library team at version 2.4.1 adds a new optional parameter to their login method without changing existing behaviour. According to SemVer, what should the next version be?
Dr. Amira's government client requires that no public NuGet packages enter the build environment without being cached and scanned first. Which Azure Artifacts feature satisfies this?
π¬ Video coming soon
Next up: Testing Strategy β design quality gates, release gates, and comprehensive testing strategies that protect your pipelines from shipping broken code.