Skip to content

Runbook: ConnectSoft API Library Template

This runbook documents how to use and manage the CI/CD pipeline and local development flow for projects generated with the ConnectSoft API Library Template. It provides essential information for developers and operations teams to build, test, deploy, and troubleshoot API libraries effectively.

Local Development

Prerequisites

To ensure a smooth local development experience, make sure you have the following installed:

  • .NET SDKs:
  • Integrated Development Environment (IDE):
  • Git: For version control operations.
  • Optional: WireMock.Net: For mock server testing (automatically included in test project).

Build the Solution

To build the entire solution locally, navigate to the root of your project and run:

# Using the modern .slnx format (recommended for VS 2022 v17.14+ and .NET SDK 9.0.200+)
dotnet build ConnectSoft.ApiLibraryTemplate.slnx --configuration Release

# Fallback to the traditional .sln format if .slnx is not supported or preferred
dotnet build ConnectSoft.ApiLibraryTemplate.sln --configuration Release

This will compile all projects within the solution in Release configuration.

Run Tests

To execute unit tests and collect code coverage locally:

# Run tests for the entire solution and collect code coverage
dotnet test ConnectSoft.ApiLibraryTemplate.slnx \
  --collect:"XPlat Code Coverage" \
  --settings ConnectSoft.ApiLibraryTemplate.runsettings

The --settings ConnectSoft.ApiLibraryTemplate.runsettings argument applies specific test run configurations, such as code coverage filters.

Run Specific Test Categories

# Run only unit tests
dotnet test ConnectSoft.ApiLibraryTemplate.slnx --filter "TestCategory=Unit"

# Run only integration tests
dotnet test ConnectSoft.ApiLibraryTemplate.slnx --filter "TestCategory=Integration"

# Run tests with mock server
dotnet test ConnectSoft.ApiLibraryTemplate.slnx --filter "FullyQualifiedName~MockedServer"

Debugging

  • Open the solution in Visual Studio or Rider.
  • Set breakpoints in your library code or test projects.
  • Run tests in debug mode or attach the debugger to a running process that consumes your library.

Local CI Simulation

To simulate the core build, test, and pack steps of the CI pipeline locally:

# Restore NuGet packages
dotnet restore ConnectSoft.ApiLibraryTemplate.slnx

# Build the solution in Release configuration
dotnet build ConnectSoft.ApiLibraryTemplate.slnx --configuration Release

# Run tests and collect code coverage
dotnet test ConnectSoft.ApiLibraryTemplate.slnx \
  --collect:"XPlat Code Coverage" \
  --settings ConnectSoft.ApiLibraryTemplate.runsettings

# Create the NuGet package
dotnet pack ConnectSoft.ApiLibraryTemplate.slnx \
  --configuration Release \
  --no-build \
  --output ./packages

CI/CD Overview

The ConnectSoft API Library Template includes a pre-configured Azure DevOps CI/CD pipeline (azure-pipelines.yml) designed for automated building, testing, and publishing of your library as a NuGet package.

The pipeline supports:

  • Multi-targeting: Builds the library against both .NET 8 and .NET 9 frameworks.
  • Code coverage enforcement: Collects code coverage using Cobertura and enforces a configurable minimum threshold.
  • Build quality checks: Integrates with BuildQualityChecks@10 to ensure code quality standards are met before publishing.
  • NuGet package creation and publishing: Automatically packs the library into a NuGet package and publishes it to a specified Azure Artifacts feed.
  • Security checks: Includes steps to check for deprecated packages and package vulnerabilities.
  • .slnx support: Supports both modern .slnx and legacy .sln solution formats.

Pipeline Structure

The azure-pipelines.yml defines a series of sequential steps:

Step Display Name Task Purpose
Install .NET Core SDK (8.x) UseDotNet@2 Ensures .NET 8 SDK is available for building.
Install .NET Core SDK (.NET 9 required for .slnx support) UseDotNet@2 Ensures .NET 9 SDK is available for multi-targeting builds and .slnx support.
Nuget authenticate NuGetAuthenticate@1 Configures NuGet to authenticate with Azure Artifacts feeds, allowing package restore and publish.
dotnet restore packages for entire solution DotNetCoreCLI@2 Restores all NuGet packages required by the solution from configured feeds.
Check deprecated packages in entire solution DotNetCoreCLI@2 Lists any deprecated NuGet packages used in the solution, helping to identify outdated dependencies.
Check packages vulnerabilities DotNetCoreCLI@2 Scans for known vulnerabilities in NuGet packages, including transitive dependencies.
dotnet build entire solution DotNetCoreCLI@2 Compiles all projects in the solution in the specified Release configuration.
dotnet test entire solution DotNetCoreCLI@2 Executes all unit tests, collects code coverage, and publishes test results to Azure DevOps.
Publish code coverage report PublishCodeCoverageResults@2 Publishes the collected Cobertura code coverage report to Azure DevOps for visualization.
Check build quality - with code coverage $(codeCoverageThreshold) BuildQualityChecks@10 Enforces a minimum code coverage threshold. The pipeline will fail if coverage falls below this value.
dotnet pack - create nuget package DotNetCoreCLI@2 Creates the NuGet package (.nupkg) for the library. This step is skipped for test projects.
dotnet push package to azure devops artifacts DotNetCoreCLI@2 Publishes the created NuGet package to the specified Azure Artifacts feed. This step only runs on successful builds of the master branch.

Configurable Pipeline Variables

The pipeline uses several variables that can be configured in Azure DevOps (Pipeline -> Edit -> Variables) or directly in azure-pipelines.yml:

Variable Name Description Default Value (in YAML)
majorMinorVersion Defines the major and minor version components for semantic versioning. 1.0
semanticVersion Automatically incremented counter for the patch version. Resets when majorMinorVersion changes. $[counter(variables['majorMinorVersion'], 0)]
solution Path to the solution file(s) to build. Uses .slnx by default when useSlnx=true. **/*.slnx or **/*.sln
solutionFile The actual solution file to use (determined by useSlnx parameter). ConnectSoft.ApiLibraryTemplate.slnx or .sln
useSlnx Pipeline parameter to toggle between .slnx and .sln formats. true
buildPlatform The build platform target. Any CPU
buildConfiguration The build configuration (e.g., Debug, Release). Release
artifactName The name of the build artifact. drop
publishVstsFeed The GUID or name of the Azure Artifacts feed to publish NuGet packages to. e4c108b4-7989-4d22-93d6-391b77a39552/1889adca-ccb6-4ece-aa22-cad1ae4a35f3
restoreVstsFeed The GUID or name of the Azure Artifacts feed to restore NuGet packages from. e4c108b4-7989-4d22-93d6-391b77a39552/1889adca-ccb6-4ece-aa22-cad1ae4a35f3
codeCoverageThreshold The minimum required code coverage percentage for the BuildQualityChecks task. 60

Pipeline Parameters

Parameter Name Type Default Description
useSlnx boolean true Toggle to use .slnx format (true) or fallback to .sln (false).

Solution Format Handling (.slnx vs .sln)

The pipeline supports both modern .slnx and legacy .sln solution formats.

.slnx Format (Default)

Benefits:

  • 48% faster CLI builds
  • Better IDE performance
  • XML-based, easier to parse

Requirements:

  • .NET SDK 9.0.200+
  • Visual Studio 2022 v17.14+

Pipeline Configuration:

parameters:
  - name: useSlnx
    displayName: 'Use .slnx format'
    type: boolean
    default: true

variables:
  ${{ if eq(parameters.useSlnx, true) }}:
    solutionFile: 'ConnectSoft.ApiLibraryTemplate.slnx'
  ${{ else }}:
    solutionFile: 'ConnectSoft.ApiLibraryTemplate.sln'

Fallback to .sln

If you encounter issues with .slnx, you can temporarily switch to .sln:

  1. Pipeline UI: Set useSlnx parameter to false when running the pipeline.
  2. YAML: Change useSlnx default to false in azure-pipelines.yml.

Test Coverage Validation

The pipeline enforces a minimum code coverage threshold to maintain code quality. This is configured by the codeCoverageThreshold variable.

- task: mspremier.BuildQualityChecks.QualityChecks-task.BuildQualityChecks@10
  displayName: 'Check build quality - with code coverage $(codeCoverageThreshold)'
  inputs:
    checkCoverage: true
    coverageFailOption: fixed
    coverageType: lines
    coverageThreshold: '$(codeCoverageThreshold)'
  condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))

You can override the codeCoverageThreshold value via:

  • Pipeline UI: Edit the pipeline and modify the variable.
  • azure-pipelines.yml: Directly change the variable definition in the YAML file.
  • Variable Group: Link a variable group to the pipeline and define the variable there.
  • Minimum: 60% (default)
  • Good: 70-80%
  • Excellent: 80%+

Package Publishing

NuGet packages are automatically pushed to the configured Azure Artifacts feed upon a successful build of the master branch.

Publishing Process

  1. Build Succeeds: All build, test, and quality checks pass.
  2. Package Created: dotnet pack creates the .nupkg file.
  3. Package Published: dotnet push publishes to Azure Artifacts feed.
  4. Versioning: Uses semantic versioning: {majorMinorVersion}.{semanticVersion}.

Versioning

The pipeline uses semantic versioning:

  • Major.Minor: Set via majorMinorVersion variable (e.g., 1.0, 2.1).
  • Patch: Auto-incremented via semanticVersion counter.
  • Format: {majorMinorVersion}.{semanticVersion} (e.g., 1.0.0, 1.0.1, 1.0.2).

Publishing Conditions

Packages are only published when:

  • Build is on master branch
  • All tests pass
  • Code coverage meets threshold
  • Build quality checks pass

Troubleshooting

Common Issues and Solutions

Issue Potential Fix
NETSDK1045: The current .NET SDK does not support targeting .NET 9.0. Ensure both .NET 8 SDK and .NET 9 SDK are installed in the pipeline using UseDotNet@2 tasks. Verify the version input for each task.
No artifacts published Confirm that the build is running on the master branch, as the dotnet push task is conditioned on eq(variables['Build.SourceBranch'], 'refs/heads/master'). Check the publishVstsFeed variable for correctness.
NuGet restore failed Verify that the restoreVstsFeed variable points to a valid Azure Artifacts feed and that the NuGetAuthenticate@1 task is correctly configured with appropriate service connections. Check token expiration for service connections.
Code coverage check failed This means the actual code coverage is below the codeCoverageThreshold. You need to either add more unit tests to increase coverage or, as a temporary measure, lower the codeCoverageThreshold (not recommended for long-term quality).
Cannot push package to feed Ensure the publishVstsFeed variable contains the correct feed GUID or name and that the service principal/user running the pipeline has Contributor permissions to the Azure Artifacts feed.
Build fails due to static analysis warnings/errors Review the build logs for specific analyzer warnings (e.g., StyleCop, SonarAnalyzer). Adjust code to meet quality standards or configure analyzer rulesets to suppress specific warnings if deemed acceptable.
.slnx solution file not found or build fails Ensure Visual Studio 2022 v17.14+ and .NET SDK 9.0.200+ are used in the build environment. If issues persist, temporarily switch the useSlnx parameter to false to use the traditional solution file.
Mock server tests fail Verify WireMock.Net is properly configured in test projects. Check that mock server URLs are correctly overridden in test configuration.
Authentication fails in tests Verify test configuration files (appsettings.UnitTests.json, appsettings.MockedServerUnitTests.json) have correct authentication settings. For mock server tests, ensure authentication headers are properly configured.

Debugging Pipeline Issues

  1. Check Build Logs: Review detailed logs in Azure DevOps for specific error messages.
  2. Verify Variables: Ensure all pipeline variables are set correctly.
  3. Test Locally: Reproduce issues locally using the same commands as the pipeline.
  4. Check Permissions: Verify service connections and feed permissions.
  5. Review Dependencies: Check for deprecated or vulnerable packages.

Releasing to Azure Artifacts

NuGet packages are automatically pushed to the configured Azure Artifacts feed upon a successful build of the master branch.

To Trigger a Release

  1. Merge your changes into the master branch.
  2. An Azure DevOps CI pipeline will be automatically triggered.
  3. Upon successful completion, the NuGet package will be published to the feed specified by $(publishVstsFeed).

Manual Release

If you need to manually trigger a release:

  1. Go to Azure DevOps Pipelines.
  2. Select your pipeline.
  3. Click Run pipeline.
  4. Select the branch (typically master).
  5. Optionally override variables.
  6. Click Run.

Version Management

  • Increment Major/Minor: Update majorMinorVersion variable (e.g., from 1.0 to 2.0).
  • Patch Auto-Increment: The semanticVersion counter automatically increments for each build.
  • Reset Counter: Changing majorMinorVersion resets the patch counter.

Local Development Workflow

Daily Development

  1. Pull Latest Changes: git pull origin master
  2. Restore Packages: dotnet restore ConnectSoft.ApiLibraryTemplate.slnx
  3. Build: dotnet build ConnectSoft.ApiLibraryTemplate.slnx
  4. Run Tests: dotnet test ConnectSoft.ApiLibraryTemplate.slnx
  5. Make Changes: Implement features or fixes
  6. Test Locally: Run tests and verify functionality
  7. Commit and Push: git commit -m "Description" && git push

Before Merging to Master

  1. Run Full Test Suite: Ensure all tests pass locally
  2. Check Code Coverage: Verify coverage meets threshold
  3. Review Static Analysis: Fix any analyzer warnings
  4. Update Documentation: Update README.md and documentation if needed
  5. Create Pull Request: Submit PR for review

Additional Resources