From d1b76061819825d4d797f30da9301df00aa3246e Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 10 May 2022 09:28:39 +0200 Subject: [PATCH] Adjust versioning scheme for .NET to make the third field the commit distance. (#14923) Adjust our versioning scheme so that the NuGet version is `Major.Minor.CommitDistance`. The previous scheme ("Major.Minor.") causes problems on branches producing stable builds, because each new commit would end up with the same NuGet version, and we wouldn't be able to push those to a NuGet feed because there might already be an existing version there. By using the commit distance in the NuGet version we ensure that every commit has a different version. --- Make.config | 40 ++++++++++++++++++---------------------- Make.versions | 14 ++++++-------- dotnet/VERSIONS.md | 32 +++++++++++++------------------- system-dependencies.sh | 8 ++++---- 4 files changed, 41 insertions(+), 53 deletions(-) diff --git a/Make.config b/Make.config index fea77caeb0f..04cf697009f 100644 --- a/Make.config +++ b/Make.config @@ -7,11 +7,11 @@ $(TOP)/Make.config.inc: $(TOP)/Make.config $(TOP)/mk/mono.mk @rm -f $@ @printf "IOS_COMMIT_DISTANCE:=$(shell LANG=C; export LANG && git --git-dir $(TOP)/.git log `git --git-dir $(TOP)/.git blame -- ./Make.versions HEAD | grep IOS_PACKAGE_VERSION= | sed 's/ .*//' `..HEAD --oneline | wc -l | sed 's/ //g')\n" >> $@ @printf "MAC_COMMIT_DISTANCE:=$(shell LANG=C; export LANG && git --git-dir $(TOP)/.git log `git --git-dir $(TOP)/.git blame -- ./Make.versions HEAD | grep MAC_PACKAGE_VERSION= | sed 's/ .*//' `..HEAD --oneline | wc -l | sed 's/ //g')\n" >> $@ - @printf "IOS_NUGET_COMMIT_DISTANCE:=$(shell LANG=C; export LANG; git --git-dir $(TOP)/.git log `git --git-dir $(TOP)/.git blame -- ./Make.versions HEAD | grep IOS_NUGET_VERSION= | sed 's/ .*//' `..HEAD --oneline | wc -l | sed 's/ //g')\n" >> $@ - @printf "TVOS_NUGET_COMMIT_DISTANCE:=$(shell LANG=C; export LANG; git --git-dir $(TOP)/.git log `git --git-dir $(TOP)/.git blame -- ./Make.versions HEAD | grep TVOS_NUGET_VERSION= | sed 's/ .*//' `..HEAD --oneline | wc -l | sed 's/ //g')\n" >> $@ - @printf "WATCHOS_NUGET_COMMIT_DISTANCE:=$(shell LANG=C; export LANG; git --git-dir $(TOP)/.git log `git --git-dir $(TOP)/.git blame -- ./Make.versions HEAD | grep WATCHOS_NUGET_VERSION= | sed 's/ .*//' `..HEAD --oneline | wc -l | sed 's/ //g')\n" >> $@ - @printf "MACOS_NUGET_COMMIT_DISTANCE:=$(shell LANG=C; export LANG; git --git-dir $(TOP)/.git log `git --git-dir $(TOP)/.git blame -- ./Make.versions HEAD | grep MACOS_NUGET_VERSION= | sed 's/ .*//' `..HEAD --oneline | wc -l | sed 's/ //g')\n" >> $@ - @printf "MACCATALYST_NUGET_COMMIT_DISTANCE:=$(shell LANG=C; export LANG; git --git-dir $(TOP)/.git log `git --git-dir $(TOP)/.git blame -- ./Make.versions HEAD | grep MACCATALYST_NUGET_VERSION= | sed 's/ .*//' `..HEAD --oneline | wc -l | sed 's/ //g')\n" >> $@ + @printf "IOS_NUGET_COMMIT_DISTANCE:=$(shell LANG=C; export LANG; git --git-dir $(TOP)/.git log `git --git-dir $(TOP)/.git blame -- ./Make.versions HEAD | grep IOS_NUGET_OS_VERSION= | sed 's/ .*//' `..HEAD --oneline | wc -l | sed 's/ //g')\n" >> $@ + @printf "TVOS_NUGET_COMMIT_DISTANCE:=$(shell LANG=C; export LANG; git --git-dir $(TOP)/.git log `git --git-dir $(TOP)/.git blame -- ./Make.versions HEAD | grep TVOS_NUGET_OS_VERSION= | sed 's/ .*//' `..HEAD --oneline | wc -l | sed 's/ //g')\n" >> $@ + @printf "WATCHOS_NUGET_COMMIT_DISTANCE:=$(shell LANG=C; export LANG; git --git-dir $(TOP)/.git log `git --git-dir $(TOP)/.git blame -- ./Make.versions HEAD | grep WATCHOS_NUGET_OS_VERSION= | sed 's/ .*//' `..HEAD --oneline | wc -l | sed 's/ //g')\n" >> $@ + @printf "MACOS_NUGET_COMMIT_DISTANCE:=$(shell LANG=C; export LANG; git --git-dir $(TOP)/.git log `git --git-dir $(TOP)/.git blame -- ./Make.versions HEAD | grep MACOS_NUGET_OS_VERSION= | sed 's/ .*//' `..HEAD --oneline | wc -l | sed 's/ //g')\n" >> $@ + @printf "MACCATALYST_NUGET_COMMIT_DISTANCE:=$(shell LANG=C; export LANG; git --git-dir $(TOP)/.git log `git --git-dir $(TOP)/.git blame -- ./Make.versions HEAD | grep MACCATALYST_NUGET_OS_VERSION= | sed 's/ .*//' `..HEAD --oneline | wc -l | sed 's/ //g')\n" >> $@ @if which ccache > /dev/null 2>&1; then printf "ENABLE_CCACHE=1\nexport CCACHE_BASEDIR=$(abspath $(TOP)/..)\n" >> $@; echo "Found ccache on the system, enabling it"; fi @if test -d $(TOP)/../maccore; then printf "ENABLE_XAMARIN=1\n" >> $@; echo "Detected the maccore repository, automatically enabled the Xamarin build"; fi @# Build from source if we're on CI and packages aren't available. @@ -130,29 +130,20 @@ NUGET_HARDCODED_PRERELEASE_BRANCH_ALPHANUMERIC:=$(shell export LANG=C; printf "% # READ INSTRUCTIONS ABOVE INSTEAD. ifneq ($(PULL_REQUEST_ID),) # we're a PR, so PR versioning -NUGET_PRERELEASE_IDENTIFIER=ci.pr.gh$(PULL_REQUEST_ID). +NUGET_PRERELEASE_IDENTIFIER=-ci.pr.gh$(PULL_REQUEST_ID) else ifeq ($(NUGETNUGET_RELEASE_BRANCH_ALPHANUMERIC_RELEASE_BRANCH),$(CURRENT_BRANCH_ALPHANUMERIC)) # this is a release branch, so no prerelease identifier NUGET_PRERELEASE_IDENTIFIER= else ifeq ($(NUGET_HARDCODED_PRERELEASE_BRANCH_ALPHANUMERIC),$(CURRENT_BRANCH_ALPHANUMERIC)) # this is a prerelease branch! -NUGET_PRERELEASE_IDENTIFIER=$(NUGET_HARDCODED_PRERELEASE_IDENTIFIER). +NUGET_PRERELEASE_IDENTIFIER=-$(NUGET_HARDCODED_PRERELEASE_IDENTIFIER) else # this is a CI branch! -NUGET_PRERELEASE_IDENTIFIER=ci.$(CURRENT_BRANCH_ALPHANUMERIC). +NUGET_PRERELEASE_IDENTIFIER=-ci.$(CURRENT_BRANCH_ALPHANUMERIC) endif NUGET_BUILD_METADATA=sha.$(CURRENT_HASH) -# The prerelease identifier is missing the per-product commit distance, which is added here -ifneq ($(NUGET_PRERELEASE_IDENTIFIER),) -IOS_NUGET_PRERELEASE_IDENTIFIER=-$(NUGET_PRERELEASE_IDENTIFIER)$(IOS_NUGET_COMMIT_DISTANCE) -TVOS_NUGET_PRERELEASE_IDENTIFIER=-$(NUGET_PRERELEASE_IDENTIFIER)$(TVOS_NUGET_COMMIT_DISTANCE) -WATCHOSOS_NUGET_PRERELEASE_IDENTIFIER=-$(NUGET_PRERELEASE_IDENTIFIER)$(WATCHOSOS_NUGET_COMMIT_DISTANCE) -MACCATALYST_NUGET_PRERELEASE_IDENTIFIER=-$(NUGET_PRERELEASE_IDENTIFIER)$(MACCATALYST_NUGET_COMMIT_DISTANCE) -MACOS_NUGET_PRERELEASE_IDENTIFIER=-$(NUGET_PRERELEASE_IDENTIFIER)$(MACOS_NUGET_COMMIT_DISTANCE) -endif - IOS_PRODUCT=Xamarin.iOS IOS_PACKAGE_NAME=Xamarin.iOS IOS_PACKAGE_NAME_LOWER=$(shell echo $(IOS_PACKAGE_NAME) | tr "[:upper:]" "[:lower:]") @@ -163,10 +154,11 @@ IOS_PACKAGE_VERSION_BUILD=$(IOS_COMMIT_DISTANCE) IOS_PACKAGE_UPDATE_ID=$(shell printf "2%02d%02d%02d%03d" $(IOS_PACKAGE_VERSION_MAJOR) $(IOS_PACKAGE_VERSION_MINOR) $(IOS_PACKAGE_VERSION_REV) $(IOS_PACKAGE_VERSION_BUILD)) IOS_NUGET=Microsoft.iOS +IOS_NUGET_VERSION=$(IOS_NUGET_OS_VERSION).$(IOS_NUGET_COMMIT_DISTANCE) IOS_NUGET_VERSION_MAJOR=$(word 1, $(subst ., ,$(IOS_NUGET_VERSION))) IOS_NUGET_VERSION_MINOR=$(word 2, $(subst ., ,$(IOS_NUGET_VERSION))) IOS_NUGET_VERSION_PATCH=$(word 3, $(subst ., ,$(IOS_NUGET_VERSION))) -IOS_NUGET_VERSION_NO_METADATA=$(IOS_NUGET_VERSION)$(IOS_NUGET_PRERELEASE_IDENTIFIER) +IOS_NUGET_VERSION_NO_METADATA=$(IOS_NUGET_VERSION)$(NUGET_PRERELEASE_IDENTIFIER) IOS_NUGET_VERSION_FULL=$(IOS_NUGET_VERSION_NO_METADATA)+$(NUGET_BUILD_METADATA) IOS_WINDOWS_NUGET=Microsoft.iOS.Windows @@ -177,24 +169,27 @@ IOS_WINDOWS_NUGET_VERSION_NO_METADATA=$(IOS_NUGET_VERSION_NO_METADATA) IOS_WINDOWS_NUGET_VERSION_FULL=$(IOS_NUGET_VERSION_FULL) TVOS_NUGET=Microsoft.tvOS +TVOS_NUGET_VERSION=$(TVOS_NUGET_OS_VERSION).$(TVOS_NUGET_COMMIT_DISTANCE) TVOS_NUGET_VERSION_MAJOR=$(word 1, $(subst ., ,$(TVOS_NUGET_VERSION))) TVOS_NUGET_VERSION_MINOR=$(word 2, $(subst ., ,$(TVOS_NUGET_VERSION))) TVOS_NUGET_VERSION_PATCH=$(word 3, $(subst ., ,$(TVOS_NUGET_VERSION))) -TVOS_NUGET_VERSION_NO_METADATA=$(TVOS_NUGET_VERSION)$(TVOS_NUGET_PRERELEASE_IDENTIFIER) +TVOS_NUGET_VERSION_NO_METADATA=$(TVOS_NUGET_VERSION)$(NUGET_PRERELEASE_IDENTIFIER) TVOS_NUGET_VERSION_FULL=$(TVOS_NUGET_VERSION_NO_METADATA)+$(NUGET_BUILD_METADATA) WATCHOS_NUGET=Microsoft.watchOS +WATCHOS_NUGET_VERSION=$(WATCHOS_NUGET_OS_VERSION).$(WATCHOS_NUGET_COMMIT_DISTANCE) WATCHOS_NUGET_VERSION_MAJOR=$(word 1, $(subst ., ,$(WATCHOS_NUGET_VERSION))) WATCHOS_NUGET_VERSION_MINOR=$(word 2, $(subst ., ,$(WATCHOS_NUGET_VERSION))) WATCHOS_NUGET_VERSION_PATCH=$(word 3, $(subst ., ,$(WATCHOS_NUGET_VERSION))) -WATCHOS_NUGET_VERSION_NO_METADATA=$(WATCHOS_NUGET_VERSION)$(WATCHOSOS_NUGET_PRERELEASE_IDENTIFIER) +WATCHOS_NUGET_VERSION_NO_METADATA=$(WATCHOS_NUGET_VERSION)$(NUGET_PRERELEASE_IDENTIFIER) WATCHOS_NUGET_VERSION_FULL=$(WATCHOS_NUGET_VERSION_NO_METADATA)+$(NUGET_BUILD_METADATA) MACCATALYST_NUGET=Microsoft.MacCatalyst +MACCATALYST_NUGET_VERSION=$(MACCATALYST_NUGET_OS_VERSION).$(MACCATALYST_NUGET_COMMIT_DISTANCE) MACCATALYST_NUGET_VERSION_MAJOR=$(word 1, $(subst ., ,$(MACCATALYST_NUGET_VERSION))) MACCATALYST_NUGET_VERSION_MINOR=$(word 2, $(subst ., ,$(MACCATALYST_NUGET_VERSION))) MACCATALYST_NUGET_VERSION_PATCH=$(word 3, $(subst ., ,$(MACCATALYST_NUGET_VERSION))) -MACCATALYST_NUGET_VERSION_NO_METADATA=$(MACCATALYST_NUGET_VERSION)$(MACCATALYST_NUGET_PRERELEASE_IDENTIFIER) +MACCATALYST_NUGET_VERSION_NO_METADATA=$(MACCATALYST_NUGET_VERSION)$(NUGET_PRERELEASE_IDENTIFIER) MACCATALYST_NUGET_VERSION_FULL=$(MACCATALYST_NUGET_VERSION_NO_METADATA)+$(NUGET_BUILD_METADATA) # Xcode version should have both a major and a minor version (even if the minor version is 0) @@ -493,10 +488,11 @@ MAC_PACKAGE_UPDATE_ID=$(shell echo $(subst ., ,$(MAC_PACKAGE_VERSION).$(MAC_PACK MAC_PACKAGE_TITLE=Xamarin $(MAC_PACKAGE_NAME) $(MAC_PACKAGE_VERSION) MACOS_NUGET=Microsoft.macOS +MACOS_NUGET_VERSION=$(MACOS_NUGET_OS_VERSION).$(MACOS_NUGET_COMMIT_DISTANCE) MACOS_NUGET_VERSION_MAJOR=$(word 1, $(subst ., ,$(MACOS_NUGET_VERSION))) MACOS_NUGET_VERSION_MINOR=$(word 2, $(subst ., ,$(MACOS_NUGET_VERSION))) MACOS_NUGET_VERSION_PATCH=$(word 3, $(subst ., ,$(MACOS_NUGET_VERSION))) -MACOS_NUGET_VERSION_NO_METADATA=$(MACOS_NUGET_VERSION)$(MACOS_NUGET_PRERELEASE_IDENTIFIER) +MACOS_NUGET_VERSION_NO_METADATA=$(MACOS_NUGET_VERSION)$(NUGET_PRERELEASE_IDENTIFIER) MACOS_NUGET_VERSION_FULL=$(MACOS_NUGET_VERSION_NO_METADATA)+$(NUGET_BUILD_METADATA) ifneq ($(TESTS_USE_SYSTEM),) diff --git a/Make.versions b/Make.versions index bfca08b1825..49275fb6d26 100644 --- a/Make.versions +++ b/Make.versions @@ -58,9 +58,7 @@ MAC_PACKAGE_VERSION=8.11.0.$(MAC_COMMIT_DISTANCE) # # Rules: # * The first two numbers represent the major and minor version of the corresponding OS. -# * Reset patch version (third number) to 100 every time either major or minor version is bumped. -# * Bump last two digits of the patch version for service releases. -# * Bump first digit of the patch version for feature releases (and reset the first two digits to 0) +# * A third number will be added later (the commit distance). # # IMPORTANT: There must be *no* managed API differences unless the two first # numbers (major.minor) changes. @@ -68,11 +66,11 @@ MAC_PACKAGE_VERSION=8.11.0.$(MAC_COMMIT_DISTANCE) # WARNING: Do **not** use versions higher than the available Xcode SDK or else we will have issues with mtouch (See https://github.com/xamarin/xamarin-macios/issues/7705) # When bumping the major macOS version in MACOS_NUGET_VERSION also update the macOS version where we execute on bots in jenkins/Jenkinsfile (in the 'node' element) -IOS_NUGET_VERSION=15.4.400 -TVOS_NUGET_VERSION=15.4.400 -WATCHOS_NUGET_VERSION=8.5.400 -MACOS_NUGET_VERSION=12.3.400 -MACCATALYST_NUGET_VERSION=15.4.400 +IOS_NUGET_OS_VERSION=15.4 +TVOS_NUGET_OS_VERSION=15.4 +WATCHOS_NUGET_OS_VERSION=8.5 +MACOS_NUGET_OS_VERSION=12.3 +MACCATALYST_NUGET_OS_VERSION=15.4 # Defines the default platform version if it's not specified in the TFM. The default should not change for a given .NET version: diff --git a/dotnet/VERSIONS.md b/dotnet/VERSIONS.md index 1f62eacaeb7..ed0e247e9f8 100644 --- a/dotnet/VERSIONS.md +++ b/dotnet/VERSIONS.md @@ -8,26 +8,20 @@ This is the scheme: `OsMajor.OsMinor.InternalRelease[-prereleaseX]+sha.1b2c3d4`. * Major: The major OS version. * Minor: The minor OS version. -* Patch: Our internal release version based on `100` as a starting point. - * Service releases will bump the last two digits of the patch version - * Feature releases will round the patch version up to the nearest 100 - (this is the same as bumping the first digit of the patch version, and - resetting the last two digits to 0). - * This follows [how the dotnet SDK does it][1]. +* Patch: Our internal release version based. This is the commit distance since + the Major.Minor version changed. * Pre-release: Optional (e.g.: Xcode previews, CI, etc.) * For CI we use a `ci` prefix + the branch name (cleaned up to only be - alphanumeric) + the commit distance (number of commits since any of the - major.minor.patch versions changed). - * Example: `iOS 15.0.100-ci.main.1234` + alphanumeric). + * Example: `iOS 15.0.123-ci.main` * Alphanumeric means `a-zA-Z0-9-`: any character not in this range will be replaced with a `-`. - * Pull requests have `pr` prefix, followed by `gh`+ PR number + commit - distance. - * Example: `tvOS 15.1.200-ci.pr.gh3333.1234` + * Pull requests have `pr` prefix, followed by `gh`+ PR number. + * Example: `tvOS 15.1.123-ci.pr.gh3333` * If we have a particular feature we want people to subscribe to (such as an Xcode release), we publish previews with a custom pre-release identifier: - * Example: `iOS 15.1.100-xcode13-1.beta.1` + * Example: `iOS 15.1.123-xcode13-1.beta` * This way people can sign up for only official previews, by referencing `iOS *-xcode13-1.beta.*` * It's still possible to sign up for all `xcode13-1` builds, by @@ -37,15 +31,15 @@ This is the scheme: `OsMajor.OsMinor.InternalRelease[-prereleaseX]+sha.1b2c3d4`. * Use the short hash because the long hash is quite long and cumbersome. This leaves the complete version open for duplication, but this is extremely unlikely. - * Example: `iOS 14.0.100+sha.1a2b3c` - * Example (CI build): `iOS 15.0.100-ci.main.1234+sha.1a2b3c` + * Example: `iOS 14.0.123+sha.1a2b3c` + * Example (CI build): `iOS 15.0.123-ci.main+sha.1a2b3c` * Since the build metadata is required for all builds, we're able to recognize incomplete version numbers and determine if a particular version string refers to a stable version or not. - * Example: `iOS 15.0.100`: incomplete version - * Example: `iOS 15.0.100+sha.1a2b3c`: stable - * Example: `iOS 15.0.100-ci.d17-0.1234+sha.1a2b3c`: CI build - * Example: `iOS 15.0.100-xcode13-1.beta.1+sha.1a2b3c`: official + * Example: `iOS 15.0.123`: incomplete version + * Example: `iOS 15.0.123+sha.1a2b3c`: stable + * Example: `iOS 15.0.123-ci.d17-0+sha.1a2b3c`: CI build + * Example: `iOS 15.0.123-xcode13-1.beta+sha.1a2b3c`: official preview * Technically it's possible to remove the prerelease part, but we’d still be able to figure out it’s not a stable version by diff --git a/system-dependencies.sh b/system-dependencies.sh index dffa9fd82bc..0d68e9b19f5 100755 --- a/system-dependencies.sh +++ b/system-dependencies.sh @@ -552,10 +552,10 @@ function check_xcode () { local IOS_SDK_VERSION MACOS_SDK_VERSION WATCH_SDK_VERSION TVOS_SDK_VERSION local XCODE_DEVELOPER_ROOT=`grep ^XCODE_DEVELOPER_ROOT= Make.config | sed 's/.*=//'` - IOS_SDK_VERSION=$(grep ^IOS_NUGET_VERSION= Make.versions | sed -e 's/.*=//' -e 's/.[0-9]*$//') - MACOS_SDK_VERSION=$(grep ^MACOS_NUGET_VERSION= Make.versions | sed -e 's/.*=//' -e 's/.[0-9]*$//') - WATCH_SDK_VERSION=$(grep ^WATCHOS_NUGET_VERSION= Make.versions | sed -e 's/.*=//' -e 's/.[0-9]*$//') - TVOS_SDK_VERSION=$(grep ^TVOS_NUGET_VERSION= Make.versions | sed -e 's/.*=//' -e 's/.[0-9]*$//') + IOS_SDK_VERSION=$(grep ^IOS_NUGET_OS_VERSION= Make.versions | sed -e 's/.*=//') + MACOS_SDK_VERSION=$(grep ^MACOS_NUGET_OS_VERSION= Make.versions | sed -e 's/.*=//') + WATCH_SDK_VERSION=$(grep ^WATCHOS_NUGET_OS_VERSION= Make.versions | sed -e 's/.*=//') + TVOS_SDK_VERSION=$(grep ^TVOS_NUGET_OS_VERSION= Make.versions | sed -e 's/.*=//') local D=$XCODE_DEVELOPER_ROOT/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator${IOS_SDK_VERSION}.sdk if test ! -d $D -a -z "$FAIL"; then