Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions Build-All.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ using module "PSModules/RepoBuild/RepoBuild.psd1"

.DESCRIPTION
This script is used by the automated build to perform the actual build. The Ubiquity.NET
family of projects all employ a PowerShell driven build that is generally divorced from the
automated build infrastructure used. This is done for several reasons, but the most
family of projects all employ a PowerShell driven build that is generally divorced from
the automated build infrastructure used. This is done for several reasons, but the most
important ones are the ability to reproduce the build locally for inner development and
for flexibility in selecting the actual back end. The back ends have changed a few times
over the years and re-writing the entire build in terms of those back ends each time is
Expand All @@ -28,7 +28,8 @@ Param(
[switch]$ForceClean
)

Set-StrictMode -Version 3.0
$ErrorActionPreference = "Stop"
$InformationPreference = "Continue"

Push-Location $PSScriptRoot
$oldPath = $env:Path
Expand All @@ -48,7 +49,7 @@ try
Remove-Item -Recurse -Force $buildInfo['BuildOutputPath'] -ProgressAction SilentlyContinue | Out-Null
}

mkdir $buildInfo['NuGetOutputPath'] -ErrorAction SilentlyContinue | Out-Null
New-Item -ItemType Directory $buildInfo['NuGetOutputPath'] -ErrorAction SilentlyContinue | Out-Null
dotnet build -c $Configuration --no-incremental 'src/Ubiquity.NET.Versioning.slnx'
}
catch
Expand Down
6 changes: 2 additions & 4 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,23 @@
Global references are included in ALL projects in this repository
-->
<ItemGroup>
<GlobalPackageReference Include="Ubiquity.NET.Versioning.Build.Tasks" Version="5.0.6-alpha"/>

<GlobalPackageReference Include="Ubiquity.NET.Versioning.Build.Tasks" Version="5.0.6" />
<!--
NOTE: This analyzer is sadly, perpetually in "pre-release" mode. There have been many issues/discussion on the point
and it has not changed official plans for the library. So policies regarding "NO-Prerelease" components need to be
overruled on this one
-->
<GlobalPackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556" Condition="'$(UseStyleCop)' != 'false'" />
</ItemGroup>

<!--
Package versions made consistent across all packages referenced in this repository
-->
<ItemGroup>
<PackageVersion Include="Sprache" Version="2.3.1" />

<!-- Tests all use the same framework versions -->
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
<PackageVersion Include="MSTest.TestAdapter" Version="3.9.1" />
<PackageVersion Include="MSTest.TestFramework" Version="3.9.1" />
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
</ItemGroup>
</Project>
9 changes: 9 additions & 0 deletions PsModules/CommonBuild/Public/Get-CurrentBuildKind.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ function Get-CurrentBuildKind
$currentBuildKind = [BuildKind]::LocalBuild

# IsAutomatedBuild is the top level gate (e.g. if it is false, all the others must be false)
# This supports identification of APPVEYOR or GitHub explicitly but also supports the common
# `CI` environment variable. Additional build back-ends that don't set the env var therefore,
# would need special handling here.
$isAutomatedBuild = [System.Convert]::ToBoolean($env:CI) `
-or [System.Convert]::ToBoolean($env:APPVEYOR) `
-or [System.Convert]::ToBoolean($env:GITHUB_ACTIONS)
Expand All @@ -40,6 +43,12 @@ function Get-CurrentBuildKind
# below, so default to a CiBuild (e.g. not a PR, And not a RELEASE)
$currentBuildKind = [BuildKind]::CiBuild

# Based on back-end type - determine if this is a release or CI build
# The assumption here is that a TAG is pushed to the repo for releases
# and therefore that is what distinguishes a release build. Other conditions
# would need to use other criteria to determine a PR buddy build, CI build
# and release build.

# IsPullRequestBuild indicates an automated buddy build and should not be trusted
$isPullRequestBuild = $env:GITHUB_BASE_REF -or $env:APPVEYOR_PULL_REQUEST_NUMBER

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ function Initialize-CommonBuildEnvironment

# On Windows setup the equivalent of a Developer prompt.
#
# other platform runners may have different defaulted paths etc...
# Other platform runners may have different defaulted paths etc...
# to account for here.
if ($IsWindows)
{
Expand All @@ -100,7 +100,7 @@ function Initialize-CommonBuildEnvironment
# "profile" and the actual command is exposed.
if($null -eq (Find-OnPath vswhere))
{
# NOTE: automated builds in Github do NOT include winget (for reasons unknown)
# NOTE: automated builds in Github do NOT include WinGet (for reasons unknown)
# However, they do contain VSWHERE so should not hit this.
winget install Microsoft.VisualStudio.Locator | Out-Null
}
Expand Down
2 changes: 1 addition & 1 deletion PsModules/CommonBuild/Public/Show-FullBuildInfo.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ function Show-FullBuildInfo
properties so that the full details are available in logs.

.DESCRIPTION
This function displays all the properties of the build info to the information stream. Additionally,
This function displays all the properties of the buildinfo to the information stream. Additionally,
details of the current PATH, the .NET SDKs and runtimes installed is logged to the Verbose stream.
#>
Param($buildInfo)
Expand Down
2 changes: 2 additions & 0 deletions PsModules/RepoBuild/Public/Initialize-BuildEnvironment.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ function Initialize-BuildEnvironment
{
# use common repo-neutral function to perform most of the initialization
$buildInfo = Initialize-CommonBuildEnvironment $repoRoot -FullInit:$FullInit

# Add repo specific values
$buildInfo['OfficialGitRemoteUrl'] = 'https://github.com/UbiquityDotNET/Ubiquity.NET.Versioning.git'

# make sure directories required (but not created by build tools) exist
Expand Down
75 changes: 45 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
# Ubiquity.NET.Versioning
This repo includes support for versioning numbers. This support includes:
1) Automated Constrained Semantic Versioning ([CSemVer](https:/csemver.org)) for MSBuild
1) Automated Constrained Semantic Versioning ([CSemVer](https://csemver.org)) for MSBuild
projects.
2) A standalone library useful for parsing, sorting and validating versions.
- [SemVer](https://semver.org)
- [CSemVer](https://csemver.org)
- This is a Constrained Semantic Version (That is, a strict subset of a SemVer)
- [CSemVer-CI](https://csemver.org)
- This is also a Constrained Semantic Version but is designed for ***POST-RELEASE*** CI
build numbering. It is NOT a CSemVer but IS a SemVer.
- This is also a Constrained Semantic Version but is designed for ***POST-RELEASE***
CI build numbering. It is NOT a CSemVer but IS a SemVer.

## Status
[![NuGet Version](https://img.shields.io/nuget/vpre/Ubiquity.NET.Versioning)](https://www.nuget.org/packages/Ubiquity.NET.Versioning)
![NuGet](https://img.shields.io/nuget/dt/Ubiquity.NET.Versioning.svg)
![PR/CI Work Flow Status](https://img.shields.io/github/actions/workflow/status/UbiquityDotNET/Ubiquity.NET.Versioning/pr-build.yml?label=PR%2FCI%20Build%20Status)
![Release Work Flow Status](https://img.shields.io/github/actions/workflow/status/UbiquityDotNET/Ubiquity.NET.Versioning/release-build.yml?label=Release%20Build%20Status)

## Supported Runtimes
This library supports the following .NET runtime versions.
* .NET 8.0 (LTSC) and later

.NET standard 2.0 does not support the many uses of `static abstract` that are utilized
in this library. Therefore, supporting that runtime is not possible with simple PolyFill's.
It requires fairly significant preprocessor conditional coding AND major changes to the
tests to validate BOTH variants. Thus, unless there is a strong compelling case that's not
something this library will support.

## Overview
Officially, NuGet Packages use a SemVer 2.0 (see http://semver.org).
However, SemVer 2.0 doesn't consider or account for publicly available CI builds.
Expand All @@ -26,41 +36,46 @@ allowing for automated CI builds. These new versions are called a [Constrained S
Version](http://csemver.org) (CSemVer).

## Constrained use of Constrained Semantic Versions
A CSemVer is unique for each CI build and always increments while supporting official releases.
In the real world there are often cases where there are additional builds that are distinct
from official releases and CI builds. Including Local developer builds, builds generated from a
Pull Request (a.k.a Automated buddy build). CSemVer doesn't explicitly define any format for
these cases. So this library defines a pattern of versioning that is fully compatible with
CSemVer and allows for the additional build types in a way that retains precedence having the
least surprising consequences. In particular, local build packages have a higher precedence
than automated builds (CI or release) versions if all other components of the version match.
This ensures that what you are building includes the dependent packages you just built instead
of the last one released publicly.
A CSemVer is unique for each CI build and always increments while supporting official
releases. In the real world there are often cases where there are additional builds that
are distinct from official releases and CI builds. Including Local developer builds,
builds generated from a Pull Request (a.k.a Automated buddy build). CSemVer doesn't
explicitly define any format for these cases. So this library defines a pattern of
versioning that is fully compatible with CSemVer and allows for the additional build types
in a way that retains precedence having the least surprising consequences. In particular,
local build packages have a higher precedence than automated builds (CI or release)
versions if all other components of the version match. This ensures that what you are
building includes the dependent packages you just built instead of the last one released
publicly.

>[!WARNING]
> The formal 'spec' for [CSemVer](https://csemver.org) remains silent on the point of the short
> format.<sup>[1](#footnote_1)</sup> Instead it relies on only examples. However, the examples are inconsistent on the
> requirement of a delimiter between the short name and number components of a version. It
> shows two examples '1.0.0-b03-01' ***AND*** '5.0.0-r-04-13'. So, which is it? Is the
> delimiter required or not?
> The formal 'spec' for [CSemVer](https://csemver.org) remains silent on the point of the
> short format.<sup>[1](#footnote_1)</sup> Instead it relies on only examples. However,
> the examples are inconsistent on the requirement of a delimiter between the short name
> and number components of a version. It shows two examples '1.0.0-b03-01' ***AND***
> '5.0.0-r-04-13'. So, which is it? Is the delimiter required or not?
>
> This may seem like an entirely academic issue, but when parsing an input it impacts the
> validity of inputs. Also, when the dealing with ordering and the length of otherwise equal
> components comes into play it can impact the behavior as well. How are `1.0.0-b03-01` and
> `1.0.0-b-03-01` ordered in relation to each other? Is the former even a valid CSemVer?
> validity of inputs. Also, when the dealing with ordering and the length of otherwise
> equal components comes into play it can impact the behavior as well. How are
> `1.0.0-b03-01` and `1.0.0-b-03-01` ordered in relation to each other? Is the former
> even a valid CSemVer?
>
> ***This implementation is making no assumptions and simply does NOT support the short form.***
> That may seem like a hard stance but given the ambiguities of the spec, documenting the behavior
> is difficult. Additionally, handling all the potential variations makes for extremely complex
> implementation code. All of that for a feature in support of a NuGet client that is now obsolete.
> (NuGet v3 can handle the full name just fine!). Thus, the lack of support in this library.
> ***This implementation is making no assumptions and simply does NOT support the short
> form.*** That may seem like a hard stance but given the ambiguities of the spec,
> documenting the behavior is difficult. Additionally, handling all the potential
> variations makes for extremely complex implementation code. All of that for a feature
> in support of a NuGet client that is now obsolete. (NuGet v3 can handle the full name
> just fine!). Thus, the lack of support in this library.

## End User Documentation
Full documentation on the tasks is available in the project's [docs site](https://ubiquitydotnet.github.io/Ubiquity.NET.Versioning/)
Full documentation on the tasks is available in the project's
[docs site](https://ubiquitydotnet.github.io/Ubiquity.NET.Versioning/)

## Building the tasks
Documentation on building and general maintenance of this repo are provided in the [Wiki](https://github.com/UbiquityDotNET/Ubiquity.NET.Versioning/wiki).
Documentation on building and general maintenance of this repo are provided in the
[Wiki](https://github.com/UbiquityDotNET/Ubiquity.NET.Versioning/wiki).

----
<sup><a id="footnote_1">1</a></sup>See: [This issue](https://github.com/CK-Build/csemver.org/issues/2) which was reported upon
testing this library and found ambiguities.
<sup><a id="footnote_1">1</a></sup>See: [This issue](https://github.com/CK-Build/csemver.org/issues/2)
which was reported upon testing this library and found ambiguities.
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="MSTest.TestFramework" />
<PackageReference Include="MSTest.TestAdapter" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Ubiquity.NET.Versioning\Ubiquity.NET.Versioning.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="TestBuildVersion.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
6 changes: 1 addition & 5 deletions src/Ubiquity.NET.Versioning/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,4 @@
<value>'{0}' must be in range {1}. {2}</value>
<comment>{0} - Value name; {1} - range notation for the value; {2} post message text (Usually a spec reference)</comment>
</data>
<data name="value_0_must_be_in_range_1" xml:space="preserve">
<value>'{0}' must be in range {1}.</value>
<comment>{0} - Value name; {1} - range notation for the value</comment>
</data>
</root>
</root>
16 changes: 11 additions & 5 deletions src/Ubiquity.NET.Versioning/Ubiquity.NET.Versioning.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<IsAotCompatible>true</IsAotCompatible>
<NeutralLanguage>en-US</NeutralLanguage>

<PackageId>Ubiquity.NET.Versioning</PackageId>
<Authors>UbiquityDotNET</Authors>
<Copyright>Copyright (C) 2017-2020, Ubiquity.NET Contributors</Copyright>
Expand All @@ -15,20 +18,23 @@
<PackageTags>Version;CSemVer;CI;SemVer</PackageTags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<PackageReadmeFile>ReadMe.md</PackageReadmeFile>
<IsAotCompatible>True</IsAotCompatible>
<NeutralLanguage>en-US</NeutralLanguage>
<PackageReadmeFile>PackageReadMe.md</PackageReadmeFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Sprache" />
<!-- Override dependent version with explicit form to resolve CVE vulnerability -->
<PackageReference Include="System.Text.RegularExpressions" />
</ItemGroup>

<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
Expand All @@ -37,6 +43,6 @@
</ItemGroup>

<ItemGroup>
<None Update="PackageReadMe.md" Pack="true" PackagePath="ReadMe.md" />
<None Include="PackageReadMe.md" Pack="true" PackagePath="/" />
</ItemGroup>
</Project>
Loading