Package Management with Azure Artifacts: Building an Internal Shared Library
Scenario Overview
You are a DevOps Engineer at Contoso Retail, a mid-sized e-commerce company transitioning from a monolithic application to a microservices architecture. The development team has identified common functionality duplicated across multiple services—logging, authentication helpers, API response models, and utility functions.
Your manager has assigned you the following task:
"We need to stop copying code between our microservices. Create a shared library that our teams can consume through Azure Artifacts. Start with our common API response models and logging utilities. Make sure the library is versioned properly and can be easily updated across all services."
In this lab, you will:
- Set up an Azure Artifacts feed for your organization's internal packages
- Create a .NET 10 shared library with realistic utility code
- Push your code to Azure Repos for version control
- Implement semantic versioning and publish the package
- Consume the package in a simulated microservice
- Create CI/CD pipelines to automate package publishing and consumption
- Update the package and manage version dependencies
This lab takes approximately 40 minutes to complete.
Before you start
You need:
- Microsoft Edge or an Azure DevOps supported browser
- Azure DevOps organization: Create one if you don't have one
- Visual Studio Code with the C# Dev Kit extension
- .NET 10 SDK: Download and install the .NET 10 SDK
- Azure Artifacts credential provider: Download and install the credential provider
Understanding Azure Artifacts in Enterprise Scenarios
Azure Artifacts is essential for organizations adopting microservices or maintaining multiple applications that share common code. Key enterprise benefits include:
- Code reusability: Share common libraries across teams without copy-paste
- Version control: Manage package versions with semantic versioning
- Security: Control who can publish and consume packages
- Auditability: Track package usage and dependencies across projects
- CI/CD integration: Automatically publish packages from build pipelines
In a typical enterprise scenario, you might have:
| Feed | Purpose | Example Packages |
|---|---|---|
contoso-shared |
Cross-cutting concerns | Logging, authentication, utilities |
contoso-domain |
Business domain models | Order models, customer models |
contoso-infra |
Infrastructure code | Database helpers, message bus clients |
Task 1: Set Up the Azure DevOps Project
First, create the Azure DevOps project that will host your shared library.
- Open your Azure DevOps organization in a browser
- Select + New Project
- Configure the project:
- Name:
Contoso.Microservices - Description:
Internal shared libraries and microservice projects for Contoso Retail - Visibility: Private
- Version control: Git
- Work item process: Agile
- Name:
- Select Create
Task 2: Create the Azure Artifacts Feed
Set up a dedicated feed for your organization's internal packages.
-
In your Azure DevOps project, select Artifacts from the left navigation
-
Select + Create Feed
-
Configure the feed:
- Name:
contoso-internal - Visibility:
Members of your Microsoft Entra Tenant(select your organization) - Upstream sources: Select Include packages from common public sources
Why include upstream sources? This allows developers to restore both internal packages AND public NuGet packages from the same feed, simplifying configuration.
- Scope:
Project: Contoso.Microservices
- Name:
-
Select Create
-
After creation, select Connect to Feed
-
Select dotnet under the NuGet section
-
Copy the Artifacts URL (value parameter in the displayed nuget.config xml snippet). It will look like:
https://pkgs.dev.azure.com/<your-org>/Contoso.Microservices/_packaging/contoso-internal/nuget/v3/index.json -
Click the Back arrow to return to the main Artifacts feed page.
Note: By default, the "
Build Service" User has Artifact Feed Collaborator (Feed and Upstream Reader) permissions. As we will run a Build Pipeline later on to not only use, but also publish packages, the permissions need to be updated.
- From the Artifacts / Feeds page (The one that says Connect to the feed to get started), select Feed Settings (the little cog wheel) and navigate to the Permissions tab
- Select the Contoso.MicroServices Build Service (ADO Organization) User
- Click Edit
- Change the permission from Feed and Upstream Reader to Feed Publisher (Contributor)
- Save the changes
Task 3: Create the Shared Library Project
Create a .NET 10 class library with realistic shared utilities.
Initialize the Solution Structure
-
Open a terminal and create the project directory:
mkdir C:\ContosoMicroservices cd C:\ContosoMicroservices -
Create a new solution and class library:
dotnet nuget add source https://api.nuget.org/v3/index.json --name nuget.org dotnet new sln --name Contoso.Shared dotnet new classlib --name Contoso.Shared.Core --framework net10.0 dotnet sln add Contoso.Shared.Core dotnet new gitignore -
Open the project in VS Code:
code .
Add Package Metadata
- Open the
Contoso.Shared.Core/Contoso.Shared.Core.csprojfile and replace its content with:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- Package metadata -->
<PackageId>Contoso.Shared.Core</PackageId>
<Version>1.0.0</Version>
<Authors>Contoso DevOps Team</Authors>
<Company>Contoso Retail</Company>
<Description>Core shared utilities for Contoso microservices including API response models, logging helpers, and common extensions.</Description>
<PackageTags>contoso;shared;utilities;microservices</PackageTags>
<RepositoryType>git</RepositoryType>
</PropertyGroup>
</Project>
Create the API Response Models
In enterprise applications, standardizing API responses ensures consistency across all microservices. The ApiResponse<T> class below wraps all responses with success/failure status, correlation IDs for distributed tracing, and standardized error information.
- Delete the default
Class1.csfile in theContoso.Shared.Corefolder - Create a new folder called
ModelsinsideContoso.Shared.Core - Create a new file
Models/ApiResponse.cswith the following code:
namespace Contoso.Shared.Core.Models;
public class ApiResponse<T>
{
public bool Success { get; set; }
public T? Data { get; set; }
public ApiError? Error { get; set; }
public string CorrelationId { get; set; } = Guid.NewGuid().ToString();
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
public static ApiResponse<T> Ok(T data, string? correlationId = null)
{
return new ApiResponse<T>
{
Success = true,
Data = data,
CorrelationId = correlationId ?? Guid.NewGuid().ToString()
};
}
public static ApiResponse<T> Fail(string errorCode, string message, string? correlationId = null)
{
return new ApiResponse<T>
{
Success = false,
Error = new ApiError(errorCode, message),
CorrelationId = correlationId ?? Guid.NewGuid().ToString()
};
}
}
public record ApiError(string Code, string Message)
{
public string? Details { get; init; }
public Dictionary<string, string[]>? ValidationErrors { get; init; }
}
Create the Logging Extensions
The LogContext class provides structured logging context that enables consistent log entries and distributed tracing across microservices. It captures correlation IDs, service names, and optional user/tenant information for multi-tenant applications.
- Create a new folder called
LogginginsideContoso.Shared.Core - Create a new file
Logging/LogContext.cs:
namespace Contoso.Shared.Core.Logging;
public class LogContext
{
public string CorrelationId { get; set; } = Guid.NewGuid().ToString();
public required string ServiceName { get; set; }
public string? Operation { get; set; }
public string? UserId { get; set; }
public string? TenantId { get; set; }
public Dictionary<string, object?> ToDictionary()
{
return new Dictionary<string, object?>
{
["CorrelationId"] = CorrelationId,
["ServiceName"] = ServiceName,
["Operation"] = Operation,
["UserId"] = UserId,
["TenantId"] = TenantId,
["Timestamp"] = DateTime.UtcNow.ToString("O")
};
}
}
Create String Extension Utilities
These extension methods provide common string operations used across services: Truncate for display purposes, Mask for hiding sensitive data like emails or credit cards, and ToSlug for URL-friendly strings.
- Create a new folder called
ExtensionsinsideContoso.Shared.Core - Create a new file
Extensions/StringExtensions.cs:
namespace Contoso.Shared.Core.Extensions;
public static class StringExtensions
{
public static string Truncate(this string value, int maxLength, string suffix = "...")
{
if (string.IsNullOrEmpty(value)) return value;
if (maxLength <= 0) return string.Empty;
if (value.Length <= maxLength) return value;
return string.Concat(value.AsSpan(0, maxLength - suffix.Length), suffix);
}
public static string Mask(this string value, int visibleChars = 4, char maskChar = '*')
{
if (string.IsNullOrEmpty(value)) return value;
if (value.Length <= visibleChars * 2) return new string(maskChar, value.Length);
var start = value[..visibleChars];
var end = value[^visibleChars..];
var masked = new string(maskChar, value.Length - (visibleChars * 2));
return $"{start}{masked}{end}";
}
public static string ToSlug(this string value)
{
if (string.IsNullOrEmpty(value)) return value;
return value
.ToLowerInvariant()
.Replace(" ", "-")
.Replace("_", "-");
}
}
Build the Project
- In the terminal, build the solution:
dotnet build - Verify there are no build errors
Push the Code to Azure Repos
Now that the shared library is created, push it to Azure Repos for version control. This enables team collaboration and will be the foundation for CI/CD automation later.
-
In Azure DevOps, navigate to Repos in your
Contoso.Microservicesproject -
Since the repo is empty, you'll see setup instructions. Copy the Clone URL (HTTPS), it looks like:
https://dev.azure.com/<your-org>/Contoso.Microservices/_git/Contoso.Microservices -
In your terminal, initialize Git and push the code, updating the URL with your DevOps organization name:
cd C:\ContosoMicroservices git init git add . git commit -m "Initial commit: Contoso.Shared.Core library" git remote add origin https://dev.azure.com/<your-org>/Contoso.Microservices/_git/Contoso.Microservices git push -u origin mainNote: You may be prompted to authenticate. Use your Azure DevOps credentials.
-
In Azure DevOps, refresh the Repos page to verify your code is now visible
Task 4: Create a CI Pipeline to Publish Packages
In a DevOps environment, packages are published automatically through CI pipelines rather than manually. This ensures consistency, traceability, and proper version control.
Create the Pipeline File
- In VS Code, create a new file
azure-pipelines.ymlin the solution root (C:\ContosoMicroservices):
trigger:
branches:
include:
- main
paths:
include:
- Contoso.Shared.Core/**
pool:
vmImage: 'ubuntu-latest'
variables:
buildConfiguration: 'Release'
projectPath: 'Contoso.Shared.Core/Contoso.Shared.Core.csproj'
stages:
- stage: Build
displayName: 'Build and Pack'
jobs:
- job: BuildJob
displayName: 'Build Library'
steps:
- task: UseDotNet@2
displayName: 'Use .NET 10 SDK'
inputs:
packageType: 'sdk'
version: '10.x'
- task: DotNetCoreCLI@2
displayName: 'Restore packages'
inputs:
command: 'restore'
projects: '$(projectPath)'
- task: DotNetCoreCLI@2
displayName: 'Build'
inputs:
command: 'build'
projects: '$(projectPath)'
arguments: '--configuration $(buildConfiguration) --no-restore'
- task: DotNetCoreCLI@2
displayName: 'Pack NuGet package'
inputs:
command: 'pack'
packagesToPack: '$(projectPath)'
configuration: '$(buildConfiguration)'
packDirectory: '$(Build.ArtifactStagingDirectory)'
- publish: '$(Build.ArtifactStagingDirectory)'
artifact: 'nuget-package'
displayName: 'Publish artifact'
- stage: Publish
displayName: 'Publish to Azure Artifacts'
dependsOn: Build
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- job: PublishJob
displayName: 'Push to Feed'
steps:
- download: current
artifact: 'nuget-package'
- task: NuGetAuthenticate@1
displayName: 'Authenticate to Azure Artifacts'
- task: DotNetCoreCLI@2
displayName: 'Push to contoso-internal feed'
inputs:
command: 'push'
packagesToPush: '$(Pipeline.Workspace)/nuget-package/*.nupkg'
nuGetFeedType: 'internal'
publishVstsFeed: 'Contoso.Microservices/contoso-internal'
This pipeline triggers when changes are pushed to the main branch in the Contoso.Shared.Core folder. It builds, packs, and publishes the NuGet package to your Azure Artifacts feed automatically.
Key benefit: The
NuGetAuthenticate@1task handles authentication automatically—no Personal Access Tokens needed for pipeline publishing!
Commit and Push to Trigger the Pipeline
-
Add the pipeline file and push:
cd C:\ContosoMicroservices git add azure-pipelines.yml git commit -m "Add CI pipeline for package publishing" git push
Create the Pipeline in Azure DevOps
-
In Azure DevOps, navigate to Pipelines
-
Select Create Pipeline (or New Pipeline)
-
Select Azure Repos Git
-
Select the Contoso.Microservices repository
-
The
/azure-pipelines.ymlwill get loaded automatically -
Click Run
-
Watch the pipeline execute through both stages:
- Build and Pack: Compiles the library and creates the NuGet package
- Publish to Azure Artifacts: Pushes the package to your feed
-
After completion, navigate to Artifacts > contoso-internal
-
Verify that
Contoso.Shared.Coreversion1.0.0appears in the feed
DevOps Best Practice: By publishing packages through pipelines, you get full traceability—every package version is linked to a specific commit and build.
Task 5: Consume the Package in a Microservice
Now that the package is published through the pipeline, create a microservice that consumes it.
Create the Order Service Project
-
In the terminal, navigate to the solution folder and create a new Web API project:
cd C:\ContosoMicroservices dotnet nuget add source https://api.nuget.org/v3/index.json --name nuget.org dotnet new webapi --name Contoso.OrderService --framework net10.0 --use-controllers dotnet sln add Contoso.OrderService
Configure NuGet to Use Azure Artifacts
Create a nuget.config file so both local development and CI/CD pipelines can restore packages from your Azure Artifacts feed.
-
Create
nuget.configin the solution root (C:\ContosoMicroservices): (This xml can also be found in the Artifacts Feed / Connect to feed / Nuget / dotnet - Project Setup section)<?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <clear /> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> <add key="contoso-internal" value="https://pkgs.dev.azure.com/<your-org>/Contoso.Microservices/_packaging/contoso-internal/nuget/v3/index.json" /> </packageSources> </configuration>Note: Replace
<your-org>with your Azure DevOps organization name.
Install the Shared Package
Important: Before proceeding, verify that the pipeline from Task 4 completed successfully and the package exists in your feed:
- In Azure DevOps, navigate to Artifacts > contoso-internal
- Confirm you see
Contoso.Shared.Coreversion1.0.0listed If the package is not there, check the pipeline run in Pipelines for any errors.
-
Install the Azure Artifacts credential provider if you haven't already (this enables authentication for local development):
- Download the latest release from https://github.com/microsoft/artifacts-credprovider/releases
- Download
Microsoft.Net.Providers.CredentialProvider.zip(for .NET) - Extract the zip file to
%USERPROFILE%\.nuget\plugins(create the folder if it doesn't exist)
Alternatively, if the PowerShell command works in your environment:
iex "& { $(irm https://aka.ms/install-artifacts-credprovider.ps1) }" -
Add the package reference to the Order Service. Open
Contoso.OrderService/Contoso.OrderService.csprojin VS Code and add the following line to the existingItemGrouptag:<PackageReference Include="Contoso.Shared.Core" Version="1.0.0" /> -
Next, in the same
Contoso.OrderService.csproj, add a project reference to Contoso.Shared.Core, by adding the following new ItemGroup section below the PackageReference ItemGroup section:<ItemGroup> <ProjectReference Include="..\Contoso.Shared.Core\Contoso.Shared.Core.csproj" /> </ItemGroup> -
Restore and build the project:
cd C:\ContosoMicroservices dotnet restore --interactive dotnet buildNote: The first time you restore, you'll be prompted to authenticate with Azure DevOps in a browser window. Select your account and allow access. The credential provider caches your credentials for future use.
Use the Shared Library
Now that the shared package is installed, create a controller that uses it. The controller below demonstrates how consuming services use the shared library. Note how ApiResponse<T> provides consistent response formatting, while the Mask and Truncate extension methods handle sensitive data and display formatting.
- Delete
Controllers/WeatherForecastController.csandWeatherForecast.csfrom the project - Create a new file
Controllers/OrdersController.cswith the following code:
using Contoso.Shared.Core.Models;
using Contoso.Shared.Core.Extensions;
using Microsoft.AspNetCore.Mvc;
namespace Contoso.OrderService.Controllers;
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
[HttpGet("{id}")]
public ActionResult<ApiResponse<OrderDto>> GetOrder(int id)
{
if (id <= 0)
{
return BadRequest(ApiResponse<OrderDto>.Fail(
"INVALID_ORDER_ID",
"Order ID must be a positive number"));
}
if (id == 999)
{
return NotFound(ApiResponse<OrderDto>.Fail(
"ORDER_NOT_FOUND",
$"Order with ID {id} was not found"));
}
var order = new OrderDto
{
OrderId = id,
CustomerName = "John Doe",
CustomerEmail = "john.doe@example.com".Mask(3),
TotalAmount = 299.99m,
Status = "Processing",
Description = "This is a sample order with a very long description that should be truncated".Truncate(50)
};
return Ok(ApiResponse<OrderDto>.Ok(order));
}
[HttpGet]
public ActionResult<ApiResponse<List<OrderDto>>> GetOrders()
{
var orders = new List<OrderDto>
{
new() { OrderId = 1, CustomerName = "John Doe", TotalAmount = 299.99m, Status = "Completed" },
new() { OrderId = 2, CustomerName = "Jane Smith", TotalAmount = 149.50m, Status = "Processing" }
};
return Ok(ApiResponse<List<OrderDto>>.Ok(orders));
}
}
public class OrderDto
{
public int OrderId { get; set; }
public string CustomerName { get; set; } = string.Empty;
public string? CustomerEmail { get; set; }
public decimal TotalAmount { get; set; }
public string Status { get; set; } = string.Empty;
public string? Description { get; set; }
}
-
Build and run the project:
cd c:\ContosoMicroServices\Contoso.OrderService dotnet run -
Test the API by opening the http://localhost:port> URL shown in the terminal):
- Navigate to
/api/orders/1- should return a success response - Notice how the email is masked and description is truncated using the shared extensions
- Navigate to
/api/orders/999- should return a ORDER_NOT_FOUND error
- Navigate to
Task 6: Update the Package (Simulating a Bug Fix)
Your team reported that the Mask extension method doesn't handle edge cases properly. Let's fix the bug, update the version, and publish the update through the pipeline.
Make the Fix
The updated method adds a minMaskedChars parameter to ensure short strings are properly masked rather than exposing too much data.
- In VS Code, open
Contoso.Shared.Core/Extensions/StringExtensions.cs - Update the
Maskmethod:
Note: Make sure you don't change any of the other code snippets. Also make sure that the indentation of the code snippet is respected.
public static string Mask(this string value, int visibleChars = 4, char maskChar = '*', int minMaskedChars = 3)
{
if (string.IsNullOrEmpty(value)) return value;
if (visibleChars < 0) visibleChars = 0;
if (value.Length <= visibleChars * 2 + minMaskedChars)
{
return new string(maskChar, Math.Max(value.Length, minMaskedChars));
}
var start = value[..visibleChars];
var end = value[^visibleChars..];
var maskedLength = Math.Max(value.Length - (visibleChars * 2), minMaskedChars);
var masked = new string(maskChar, maskedLength);
return $"{start}{masked}{end}";
}
What does this fix? The original v1.0.0
Maskmethod had an edge case issue with short strings. For example, with the defaultvisibleChars=4, a short email like "ab@c.io" (7 characters) would show 4 characters at the start and 4 at the end—exposing the entire string! The fix adds aminMaskedCharsparameter that ensures at least 3 characters are always masked. Now short strings get fully masked (e.g.,*******) rather than revealing sensitive data.
Update the Version
Following Semantic Versioning, this is a patch release (bug fix with no breaking changes).
- Open the
Contoso.Shared.Core/Contoso.Shared.Core.csprojfile - Update the version and add release notes:
Note: Make sure you only overwrite the
<PropertyGroup>section, keeping the<Project>tags in place.
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageId>Contoso.Shared.Core</PackageId>
<Version>1.0.1</Version>
<Authors>Contoso DevOps Team</Authors>
<Company>Contoso Retail</Company>
<Description>Core shared utilities for Contoso microservices including API response models, logging helpers, and common extensions.</Description>
<PackageTags>contoso;shared;utilities;microservices</PackageTags>
<RepositoryType>git</RepositoryType>
<PackageReleaseNotes>
v1.0.1: Fixed edge case in Mask extension, added minMaskedChars parameter
</PackageReleaseNotes>
</PropertyGroup>
Publish Through the Pipeline
-
Commit and push the changes to trigger the pipeline:
cd C:\ContosoMicroservices git add . git commit -m "Fix: Handle edge cases in Mask extension (v1.0.1)" git push -
In Azure DevOps, navigate to Pipelines and watch the build run
-
After the pipeline completes, go to Artifacts > contoso-internal
-
Click on Contoso.Shared.Core to open the package details
-
Select the Versions tab to see all available versions - you should see both
1.0.0and1.0.1
Update the Order Service
-
Update the package reference in the Order Service. Open
Contoso.OrderService/Contoso.OrderService.csprojand change the version:<PackageReference Include="Contoso.Shared.Core" Version="1.0.1" /> -
Restore and build:
cd C:\ContosoMicroservices dotnet restore dotnet build
Note: If you see an error message when running this step, saying "error NU1102: unable to find package" the solution is to clear the Nuget local cache and run dotnet restore again, using the below commands (More information on this error is documented here).
cd C:\ContosoMicroservices
dotnet nuget locals http-cache --clear
dotnet restore
-
Verify the updated package is working by running the Order Service:
cd C:\ContosoMicroservices\Contoso.OrderService dotnet run -
Open the api app (URL shown in the terminal) and test the
/api/orders/1endpoint. The response should still show the masked email, confirming the updated package works correctly with the new edge case handling. -
Stop the running application (press
Ctrl+Cin the terminal)
Task 7: Create a Pipeline for the Order Service
Complete the DevOps workflow by creating a pipeline for the Order Service. This demonstrates how consuming applications restore packages from Azure Artifacts during CI/CD.
Create the Pipeline File
- Create a new file
azure-pipelines-orderservice.ymlin the solution root:
trigger:
branches:
include:
- main
paths:
include:
- Contoso.OrderService/**
pool:
vmImage: 'ubuntu-latest'
variables:
buildConfiguration: 'Release'
projectPath: 'Contoso.OrderService/Contoso.OrderService.csproj'
stages:
- stage: Build
displayName: 'Build Order Service'
jobs:
- job: BuildJob
displayName: 'Build and Test'
steps:
- task: UseDotNet@2
displayName: 'Use .NET 10 SDK'
inputs:
packageType: 'sdk'
version: '10.x'
- task: NuGetAuthenticate@1
displayName: 'Authenticate to Azure Artifacts'
- task: DotNetCoreCLI@2
displayName: 'Restore packages (including from Azure Artifacts)'
inputs:
command: 'restore'
projects: '$(projectPath)'
feedsToUse: 'config'
nugetConfigPath: 'nuget.config'
- task: DotNetCoreCLI@2
displayName: 'Build'
inputs:
command: 'build'
projects: '$(projectPath)'
arguments: '--configuration $(buildConfiguration) --no-restore'
- task: DotNetCoreCLI@2
displayName: 'Publish'
inputs:
command: 'publish'
projects: '$(projectPath)'
arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)'
publishWebProjects: false
- publish: '$(Build.ArtifactStagingDirectory)'
artifact: 'orderservice'
displayName: 'Publish artifact'
This pipeline demonstrates how the NuGetAuthenticate task enables the build agent to restore packages from your private Azure Artifacts feed using the nuget.config file you created earlier.
Create the Pipeline
-
Commit and push all changes:
cd C:\ContosoMicroServices git add . git commit -m "Add Order Service pipeline and update nuget.config" git push -
In Azure DevOps, navigate to Pipelines
-
Select New Pipeline
-
Select Azure Repos Git > Contoso.Microservices
-
Select Existing Azure Pipelines YAML file
-
Choose:
- Branch: Main
- Path:
/azure-pipelines-orderservice.yml
-
Select Continue
-
Select Run to kick off the pipeline
-
From the running pipeline, select the Build Order Service Stage to open the Job Details.
-
Observe several steps happening in the pipeline:
- Authenticates to Azure Artifacts using the same Azure Artifacts Credential Provider used locally
- Restores
Contoso.Shared.Corefrom your private feed - Builds and publishes the Order Service
DevOps Best Practice: By using Azure Artifacts with CI/CD pipelines, you ensure that all builds use consistent, versioned dependencies. This eliminates "works on my machine" issues and provides full traceability of which package versions are deployed.
Clean Up Resources
If you created resources specifically for this lab and no longer need them:
- In Azure DevOps, navigate to your project and select Project Settings
- Under General, select Overview
- At the bottom of the page, select Delete
- Type the project name to confirm
- Select Delete
Alternatively, keep the project for future labs or experimentation.
Summary
In this lab, you simulated a real-world scenario where a DevOps engineer creates and manages internal packages for a microservices architecture using Azure DevOps.