NowAround.DevOps.Versioning.Cli 1.0.2

NowAround.DevOps.Versioning.Cli

NowAround.DevOps.Versioning.Cli is a .NET tool for Azure DevOps semantic version calculation. It reads git release tags and Azure DevOps pull request metadata, then emits a package version for PR, main, and release pipelines.

Design

The tool separates version decision from release execution:

  • PR validation decides a bump and persists it as a PR label.
  • Main and release pipelines read only persisted semver:* labels.
  • Stable release state is represented by git tags such as v1.2.3.
  • Package versions are emitted as Azure Pipeline variables.

This makes main and release builds deterministic: they do not infer from titles or branches after the PR has merged.

Modes

PR mode:

nowaround-versioning calculate --mode pr --output azure-pipelines

Output shape:

X.Y.Z-pr.<pullRequestId>.<buildId>

If the current PR is missing a semver:* label, PR mode infers a bump from description markers, branch prefixes, title prefixes, or --unknown-bump-policy, then adds the matching PR label.

Main mode:

nowaround-versioning calculate --mode main --output azure-pipelines

Output shape:

X.Y.Z-ci.<buildId>

Main mode scans completed PRs since the latest stable tag and fails if an included PR has no semver:* label.

Release mode:

nowaround-versioning calculate --mode release --output azure-pipelines

Output shape:

X.Y.Z

Release mode uses the same strict label-only behavior as main mode.

Inputs

The tool reads Azure Pipelines variables by default:

SYSTEM_COLLECTIONURI
SYSTEM_TEAMPROJECT
BUILD_REPOSITORY_ID
SYSTEM_ACCESSTOKEN
SYSTEM_PULLREQUEST_PULLREQUESTID
BUILD_BUILDID

Equivalent CLI options are available:

nowaround-versioning calculate \
  --mode pr \
  --collection-uri "https://dev.azure.com/ORG/" \
  --project "PROJECT" \
  --repository-id "GUID" \
  --access-token "$SYSTEM_ACCESSTOKEN" \
  --pull-request-id "123" \
  --build-id "4567"

Azure Pipelines System.AccessToken uses bearer authentication. For local testing with a PAT:

nowaround-versioning calculate \
  --mode pr \
  --access-token "$AZURE_DEVOPS_PAT" \
  --access-token-type pat

Output

With --output azure-pipelines, the tool writes:

##vso[task.setvariable variable=BaseVersion]...
##vso[task.setvariable variable=NextVersion]...
##vso[task.setvariable variable=PackageVersion]...
##vso[task.setvariable variable=VersionBump]...
##vso[task.setvariable variable=LastStableTag]...

With --output json, it emits the full calculation result, including included PR decisions.

Artifact Publish Decisions

Artifact publish decisions are separate from SemVer calculation. semver:* labels decide the version bump. artifact:* labels decide whether NuGet packages and/or Docker images should be published with the calculated PackageVersion.

Enable artifact decision variables with:

nowaround-versioning calculate \
  --mode main \
  --output azure-pipelines \
  --unknown-bump-policy fail \
  --include-artifact-decisions \
  --artifact-default none

--artifact-default accepts none, nuget, docker, or all. If omitted, the default is none for PR/main mode and all for release mode. In main mode, --artifact-triggering-pr-required fails the pipeline when the triggering PR cannot be found; otherwise publishing is disabled with ArtifactDecisionSource=no-triggering-pr.

Supported artifact labels:

artifact:publish
artifact:nuget
artifact:docker
artifact:none

Use at most one artifact:* decision label on a PR. Multiple artifact decision labels fail the run.

Main mode artifact decision looks only at the completed PR that produced the current main run's BUILD_SOURCEVERSION merge commit. It does not use the full unreleased PR set scanned for SemVer calculation.

When enabled, Azure Pipelines output includes:

PublishArtifacts
PublishNuGet
PublishDockerImage
ArtifactDecision
ArtifactDecisionSource
ArtifactDecisionLabels
TriggeringPullRequestId

Publish conditions:

condition: and(succeeded(), eq(variables['PublishNuGet'], 'true'))
condition: and(succeeded(), eq(variables['PublishDockerImage'], 'true'))

Supported Labels

semver:major
semver:minor
semver:patch
semver:none

Only one semver:* label is allowed per PR. Multiple labels fail the run.

Git Requirements

Use full history and tags:

- checkout: self
  fetchDepth: 0
  persistCredentials: true

Existing Repositories

Before enabling the tool on an existing repository, create one bootstrap stable tag on the current main commit or on the last released commit:

git checkout main
git pull
git tag -a v1.2.3 -m "Bootstrap versioning from v1.2.3"
git push origin v1.2.3

Use the version that represents the current released package. The tag must match the configured stable tag pattern, which defaults to v[0-9]*.[0-9]*.[0-9]*.

Without this tag, pr, main, and release modes treat all reachable completed PRs as unreleased history. Existing completed PRs that do not already have exactly one semver:* label can then fail the pipeline.

The latest stable tag defaults to:

v[0-9]*.[0-9]*.[0-9]*

The default tag prefix is:

v

Both can be customized with --stable-tag-pattern and --tag-prefix.

Implementation Notes

The tool uses:

  • git tag, git rev-list, git rev-parse, and git merge-base for local repository history.
  • Azure DevOps Git REST API for pull requests and PR labels.
  • System.Text.Json and HttpClient instead of the large Azure DevOps SDK dependency, keeping the package small.

The package does not create release tags or push NuGet packages. Pipelines should use $(PackageVersion) for those steps.

This package has no dependencies.

Version Downloads Last updated
2.0.0 24 06/15/2026
1.2.1 4 06/15/2026
1.2.0 42 06/01/2026
1.2.0-ci.251 1 06/01/2026
1.2.0-ci.216 1 05/23/2026
1.1.0 42 05/23/2026
1.1.0-ci.211 1 05/23/2026
1.1.0-ci.209 1 05/23/2026
1.0.3 5 05/23/2026
1.0.2 3 05/23/2026
1.0.1 33 05/15/2026
1.0.0 6 05/14/2026
0.1.1 5 05/14/2026
0.1.0 5 05/14/2026
0.0.3 8 05/14/2026
0.0.2 3 05/14/2026
0.0.1 4 05/14/2026