From ea09368305cc929d6bda38000b339db467fed7cd Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Tue, 20 May 2025 17:43:08 +0800 Subject: [PATCH] chore: update build.cake. --- .github/workflows/build.yml | 3 +- .github/workflows/bump-up-version.yml | 6 +- build/build.cake | 180 +++++++++++++++++++++----- 3 files changed, 150 insertions(+), 39 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3f178b25..8af687e1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - + - name: Setup .NET Core SDK uses: actions/setup-dotnet@v4 with: @@ -21,5 +21,4 @@ jobs: run: | dotnet new tool-manifest dotnet tool install cake.tool --version 4.0.0 - dotnet tool install minver-cli --version 3.0.0 dotnet cake diff --git a/.github/workflows/bump-up-version.yml b/.github/workflows/bump-up-version.yml index 675a2ac0..5cd5a9dc 100644 --- a/.github/workflows/bump-up-version.yml +++ b/.github/workflows/bump-up-version.yml @@ -31,8 +31,7 @@ jobs: git config --local user.email "836904362@qq.com" dotnet new tool-manifest dotnet tool install cake.tool --version 4.0.0 - dotnet tool install minver-cli --version 3.0.0 - dotnet cake --target publish --username="${{ github.actor }}" --email="836904362@qq.com" --pre-release=${{ inputs.pre_release }} + dotnet cake --target publish --username="${{ github.actor }}" --email="836904362@qq.com" --pre-release=${{ inputs.pre_release }} --nuget-token=${{ secrets.NUGETTOKEN }} - name: Push git changes uses: ad-m/github-push-action@master @@ -41,9 +40,6 @@ jobs: branch: ${{ github.ref }} tags: true - - name: Push to nuget - run: dotnet nuget push ./build/outputs/nuget/HandyControl.*nupkg -k ${{ secrets.NUGETTOKEN }} -s https://api.nuget.org/v3/index.json - - name: Create github release uses: softprops/action-gh-release@v2 with: diff --git a/build/build.cake b/build/build.cake index 82a62416..ab6e28ee 100644 --- a/build/build.cake +++ b/build/build.cake @@ -1,8 +1,10 @@ #addin nuget:?package=Cake.Git&version=4.0.0 -#addin nuget:?package=Cake.MinVer&version=3.0.0 #tool nuget:?package=NuGet.CommandLine&version=6.9.1 using System; +using System.Text.RegularExpressions; +using System.Linq; +using System.Net; using System.Xml; using System.Xml.Serialization; using static System.IO.Directory; @@ -16,12 +18,14 @@ const string LibNuspecTemplateFilePath = "lib.nuspec.template"; const string LangNuspecTemplateFilePath = "lang.nuspec.template"; const string InstallerNuspecTemplateFilePath = "installer.nuspec.template"; const string ConfigFilePath = "build.config.xml"; +const string NugetSourceUrl = "https://api.nuget.org/v3/index.json"; var target = Argument("target", "build"); var preReleasePhase = Argument("pre-release-phase", "rc"); var preRelease = Argument("pre-release", false); var username = Argument("username", "NaBian"); var email = Argument("email", "836904362@qq.com"); +var nugetToken = Argument("nuget-token", ""); var libVersion = ""; var nugetVersion = ""; @@ -57,7 +61,11 @@ Setup(context => context.Information($"preReleasePhase: {preReleasePhase}"); context.Information($"preRelease: {preRelease}"); - FillVersions(GetAutoIncrement()); + + var releaseVersion = GetNextVersion(GetLatestVersion(), preRelease, preReleasePhase); + libVersion = releaseVersion.Split('-')[0] + ".0"; + nugetVersion = releaseVersion; + context.Information($"libVersion: {libVersion}"); context.Information($"nugetVersion: {nugetVersion}"); @@ -305,6 +313,22 @@ Task("create demo installers") } }); +Task("push to nuget") + .Does(() => +{ + if (string.IsNullOrEmpty(nugetToken)) + { + throw new Exception("NuGet token is required!"); + } + + var packages = GetFiles("./build/outputs/nuget/HandyControl.*nupkg"); + NuGetPush(packages, new NuGetPushSettings + { + ApiKey = nugetToken, + Source = NugetSourceUrl + }); +}); + Task("publish") .IsDependentOn("update license") .IsDependentOn("update version") @@ -321,6 +345,7 @@ Task("publish") .IsDependentOn("create installer nuspec files") .IsDependentOn("pack nuspec files") .IsDependentOn("create demo installers") + .IsDependentOn("push to nuget") ; Task("build") @@ -374,49 +399,71 @@ private void ReplaceFileText(string filePath, string key, string value) ); } -private void FillVersions(MinVerAutoIncrement? autoIncrement) +private string GetLatestVersion() { - if (autoIncrement is null) - { - return; - } + var lastTag = GitTags(gitRootPath, true).Last(); + Semver.TryParse(lastTag.FriendlyName.Replace(TagPrefix, ""), out var version); - var settings = new MinVerSettings - { - TagPrefix = TagPrefix, - DefaultPreReleasePhase = preReleasePhase, - AutoIncrement = autoIncrement, - }; - var minVer = MinVer(settings); - - libVersion = minVer.FileVersion; - nugetVersion = preRelease - ? $"{minVer.Major}.{minVer.Minor}.{minVer.Patch}-{minVer.PreRelease}" - : $"{minVer.Major}.{minVer.Minor}.{minVer.Patch}"; + return version.ToString(); } -private MinVerAutoIncrement? GetAutoIncrement() +// author: https://github.com/orgs/HandyOrg/people/DingpingZhang +private static string GetNextVersion(string versionText, bool canBumpMinor, string previewVersion) { - const string minorKey = "feat:"; - - var lastTag = GitTags(gitRootPath, true).Last(); - var sha = lastTag.Target.ToString(); - var logs = GitLog(gitRootPath, sha); - - if (logs.Count == 0) + if (string.IsNullOrEmpty(versionText)) { - return null; + return "0.1.0"; } - foreach (var log in logs.Take(logs.Count - 1)) + if (!Semver.TryParse(versionText, out var version)) { - if (log.Message.StartsWith(minorKey)) + throw new InvalidOperationException($"The {versionText} is not a valid version."); + } + + bool isPreviewCurrent = !string.IsNullOrEmpty(version.PreviewCode); + bool isPreviewNext = !string.IsNullOrEmpty(previewVersion); + + if (!isPreviewCurrent && !isPreviewNext) + { + // stable -> stable: bump(stable) + if (canBumpMinor) { - return MinVerAutoIncrement.Minor; + version.Minor++; + version.Patch = 0; + } + else + { + version.Patch++; } } + else if (!isPreviewCurrent && isPreviewNext) + { + // stable -> preview: bump(stable) + rc + if (canBumpMinor) + { + version.Minor++; + version.Patch = 0; + } + else + { + version.Patch++; + } - return MinVerAutoIncrement.Patch; + version.PreviewCode = previewVersion; + } + else if (isPreviewCurrent && !isPreviewNext) + { + // preview -> stable: preview - rc + version.PreviewCode = string.Empty; + version.PreviewPatch = 0; + } + else + { + // preview -> preview: stable + bump(rc) + version.PreviewPatch++; + } + + return version.ToString(); } private bool IsFramework(string framework) => !framework.Contains("."); @@ -506,4 +553,73 @@ public class BuildTask public bool BuildDemo { get; set; } } +// author: https://github.com/orgs/HandyOrg/people/DingpingZhang +public class Semver +{ + private static readonly Regex SemverPattern = new Regex(@"^(?\d+)\.(?\d+)\.(?\d+)(-(?[a-z]+)(?\d+)?)?$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled); + + public int Major; + public int Minor; + public int Patch; + public string PreviewCode; + public int PreviewPatch; + + public override string ToString() => string.IsNullOrEmpty(PreviewCode) + ? $"{Major}.{Minor}.{Patch}" + : $"{Major}.{Minor}.{Patch}-{PreviewCode}{(PreviewPatch == 0 ? string.Empty : PreviewPatch)}"; + + public static bool TryParse(string version, out Semver semver) + { + var match = SemverPattern.Match(version); + + semver = null; + if (match.Success) + { + string prePatch = match.Groups["prePatch"].Value; + semver = new Semver + { + Major = int.Parse(match.Groups["major"].Value), + Minor = int.Parse(match.Groups["minor"].Value), + Patch = int.Parse(match.Groups["patch"].Value), + PreviewCode = match.Groups["preCode"].Value, + PreviewPatch = string.IsNullOrEmpty(prePatch) ? 0 : int.Parse(prePatch), + }; + } + + return match.Success; + } + + public static int Compare(Semver left, Semver right) + { + var version1 = new Version(left.Major, left.Minor, left.Patch); + var version2 = new Version(right.Major, right.Minor, right.Patch); + + int result = version1.CompareTo(version2); + if (result != 0) + { + return result; + } + + var isEmptyPreviewCode1 = string.IsNullOrEmpty(left.PreviewCode); + var isEmptyPreviewCode2 = string.IsNullOrEmpty(right.PreviewCode); + if (isEmptyPreviewCode1 && isEmptyPreviewCode2) + { + return 0; + } + + if (isEmptyPreviewCode1) + { + return 1; + } + + if (isEmptyPreviewCode2) + { + return -1; + } + + result = string.Compare(left.PreviewCode, right.PreviewCode, ignoreCase: true); + return result == 0 ? left.PreviewPatch - right.PreviewPatch : result; + } +} + #endregion