From ac4862a6b3f2ddbe3e50b63a5f4df6d0b5b2e9a6 Mon Sep 17 00:00:00 2001 From: "Nuno \"Omega Leo\" Diogo" Date: Tue, 18 Feb 2025 21:08:16 +0000 Subject: [PATCH] Added new Changelog generator --- .github/workflows/changelog.yml | 44 +++++++++++++ .github/workflows/nuget-publish.yml | 26 +++++++- .../Attributes/ChangelogAttribute.cs | 18 ++++++ OmegaLeo.HelperLib.Changelog/CHANGELOG.md | 7 +++ .../Models/Changelog.cs | 14 +++++ .../OmegaLeo.HelperLib.Changelog.csproj | 9 +++ .../Tools/ChangelogTool.cs | 63 +++++++++++++++++++ ...OmegaLeo.HelperLib.ChangelogHandler.csproj | 15 +++++ .../Program.cs | 42 +++++++++++++ .../OmegaLeo.HelperLib.ConsoleApp.csproj | 1 + OmegaLeo.HelperLib.ConsoleApp/Program.cs | 2 + OmegaLeo.HelperLib.ConsoleApp/TestClass.cs | 10 +++ OmegaLeo.HelperLib.sln | 12 ++++ OmegaLeo.HelperLib.sln.DotSettings.user | 1 + OmegaLeo.HelperLib/CHANGELOG.md | 2 + 15 files changed, 265 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/changelog.yml create mode 100644 OmegaLeo.HelperLib.Changelog/Attributes/ChangelogAttribute.cs create mode 100644 OmegaLeo.HelperLib.Changelog/CHANGELOG.md create mode 100644 OmegaLeo.HelperLib.Changelog/Models/Changelog.cs create mode 100644 OmegaLeo.HelperLib.Changelog/OmegaLeo.HelperLib.Changelog.csproj create mode 100644 OmegaLeo.HelperLib.Changelog/Tools/ChangelogTool.cs create mode 100644 OmegaLeo.HelperLib.ChangelogHandler/OmegaLeo.HelperLib.ChangelogHandler.csproj create mode 100644 OmegaLeo.HelperLib.ChangelogHandler/Program.cs create mode 100644 OmegaLeo.HelperLib.ConsoleApp/TestClass.cs create mode 100644 OmegaLeo.HelperLib/CHANGELOG.md diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml new file mode 100644 index 0000000..08fdadc --- /dev/null +++ b/.github/workflows/changelog.yml @@ -0,0 +1,44 @@ +name: Create Tag +on: + workflow_dispatch: + inputs: + tagName: + description: 'Tag name:' + type: string + required: true +jobs: + generate_changelog: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + with: + ref: ${{ github.head_ref }} + token: ${{ secrets.TOKEN }} + - name: Setup .NET + uses: actions/setup-dotnet@v1 + with: + dotnet-version: '7.0.x' + - name: Update Project Versions + run: sed -i "s/\(\([0-9]\+\.\)\{2\}\)\([0-9]\+\)/\1${{github.event.inputs.tagName}}/" "./OmegaLeo.HelperLib/OmegaLeo.HelperLib.csproj" + - name: Update Project Versions + run: sed -i "s/\(\([0-9]\+\.\)\{2\}\)\([0-9]\+\)/\1${{github.event.inputs.tagName}}/" "./OmegaLeo.HelperLib.Changelog/OmegaLeo.HelperLib.Changelog.csproj" + - name: Build and Run Changelog Generator + run: dotnet run --project "./OmegaLeo.HelperLib.ChangelogHandler/OmegaLeo.HelperLib.ChangelogHandler.csproj" + env: + UNITYFLOW_SECRET: ${{ secrets.TOKEN }} + - name: Create Tag + run: | + git config --local user.email "nunodiogo@omegaleo.pt" + git config --local user.name "Nuno Diogo" + git add . + git commit -m "Automatically generated changelog for v${{github.event.inputs.tagName}}" + git tag -a "${{ github.event.inputs.tagName }}" -m "Release ${{ github.event.inputs.tagName }}" + git push origin "${{ github.event.inputs.tagName }}" + - name: Create Release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: '${{ github.event.inputs.tagName }}' + release_name: 'Release v${{ github.event.inputs.tagName }}' \ No newline at end of file diff --git a/.github/workflows/nuget-publish.yml b/.github/workflows/nuget-publish.yml index 72fd518..b81fe7f 100644 --- a/.github/workflows/nuget-publish.yml +++ b/.github/workflows/nuget-publish.yml @@ -16,7 +16,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.TOKEN }} outputs: upload_url: ${{ steps.get_release.outputs.upload_url }} - publish_doc_helper: + publish-helper-lib: runs-on: ubuntu-latest needs: [get-release] steps: @@ -40,3 +40,27 @@ jobs: asset_path: ./OmegaLeo.HelperLib/bin/Release/OmegaLeo.HelperLib.${{ github.event.release.tag_name }}.nupkg asset_name: OmegaLeo.HelperLib.${{ github.event.release.tag_name }}.nupkg asset_content_type: application/zip + publish-changelog-lib: + runs-on: ubuntu-latest + needs: [ get-release ] + steps: + - uses: actions/checkout@v2 + - name: Setup .Net Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: '7.0.x' + - name: Update Project Version + run: sed -i "s/\(\([0-9]\+\.\)\{2\}\)\([0-9]\+\)/\1${{ github.event.release.tag_name }}/" "./OmegaLeo.HelperLib/OmegaLeo.HelperLib.Changelog.csproj" + - name: Create Nuget Package + run: dotnet pack "./OmegaLeo.HelperLib.Changelog/OmegaLeo.HelperLib.Changelog.csproj" -c Release /p:Version=${{ github.event.release.tag_name }} /p:PackageReleaseNotes="See https://github.com/omegaleo/OmegaLeo.HelperLib/releases/tag/${{ github.event.release.tag_name }}" + - name: Publish Nuget Package + run: dotnet nuget push ./OmegaLeo.HelperLib.Changelog/bin/Release/OmegaLeo.HelperLib.Changelog.${{ github.event.release.tag_name }}.nupkg --api-key ${{ secrets.nuget_api_key }} --source https://api.nuget.org/v3/index.json --skip-duplicate + - name: Upload assets to release + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.TOKEN }} + with: + upload_url: ${{ needs.get-release.outputs.upload_url }} + asset_path: ./OmegaLeo.HelperLib/bin/Release/OmegaLeo.HelperLib.Changelog.${{ github.event.release.tag_name }}.nupkg + asset_name: OmegaLeo.HelperLib.Changelog.${{ github.event.release.tag_name }}.nupkg + asset_content_type: application/zip \ No newline at end of file diff --git a/OmegaLeo.HelperLib.Changelog/Attributes/ChangelogAttribute.cs b/OmegaLeo.HelperLib.Changelog/Attributes/ChangelogAttribute.cs new file mode 100644 index 0000000..e66633b --- /dev/null +++ b/OmegaLeo.HelperLib.Changelog/Attributes/ChangelogAttribute.cs @@ -0,0 +1,18 @@ +using System; + +namespace OmegaLeo.HelperLib.Changelog.Attributes +{ + [Changelog("v1.0.0", "Created ChangelogAttribute to be used to register changes in the code.")] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] + public class ChangelogAttribute : Attribute + { + public string Version { get; } + public string Description { get; } + + public ChangelogAttribute(string version, string description) + { + Version = version; + Description = description; + } + } +} diff --git a/OmegaLeo.HelperLib.Changelog/CHANGELOG.md b/OmegaLeo.HelperLib.Changelog/CHANGELOG.md new file mode 100644 index 0000000..d853d46 --- /dev/null +++ b/OmegaLeo.HelperLib.Changelog/CHANGELOG.md @@ -0,0 +1,7 @@ +# Changelog + +## Version v1.0.0 + +- **Class: ChangelogTool**: Created the class ChangelogTool to extract changelogs via attributes +- **Class: ChangelogAttribute**: Created ChangelogAttribute to be used to register changes in the code. + diff --git a/OmegaLeo.HelperLib.Changelog/Models/Changelog.cs b/OmegaLeo.HelperLib.Changelog/Models/Changelog.cs new file mode 100644 index 0000000..3bb4848 --- /dev/null +++ b/OmegaLeo.HelperLib.Changelog/Models/Changelog.cs @@ -0,0 +1,14 @@ +namespace OmegaLeo.HelperLib.Changelog.Models +{ + public class Changelog + { + public string Target; + public string Description; + + public Changelog(string target, string description) + { + Target = target; + Description = description; + } + } +} \ No newline at end of file diff --git a/OmegaLeo.HelperLib.Changelog/OmegaLeo.HelperLib.Changelog.csproj b/OmegaLeo.HelperLib.Changelog/OmegaLeo.HelperLib.Changelog.csproj new file mode 100644 index 0000000..30b770a --- /dev/null +++ b/OmegaLeo.HelperLib.Changelog/OmegaLeo.HelperLib.Changelog.csproj @@ -0,0 +1,9 @@ + + + + netstandard2.1 + enable + enable + + + diff --git a/OmegaLeo.HelperLib.Changelog/Tools/ChangelogTool.cs b/OmegaLeo.HelperLib.Changelog/Tools/ChangelogTool.cs new file mode 100644 index 0000000..fcc33ce --- /dev/null +++ b/OmegaLeo.HelperLib.Changelog/Tools/ChangelogTool.cs @@ -0,0 +1,63 @@ +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using OmegaLeo.HelperLib.Changelog.Attributes; + +namespace OmegaLeo.HelperLib.Changelog.Tools +{ + [Changelog("v1.0.0", "Created the class ChangelogTool to extract changelogs via attributes")] + public class ChangelogTool + { + public static Dictionary> ExtractChangelog(Assembly assembly) + { + var changelogByVersion = new Dictionary>(); + + foreach (var type in assembly.GetTypes()) + { + foreach (var attr in type.GetCustomAttributes()) + { + AddChangelogEntry(changelogByVersion, attr.Version, $"Class: {type.Name}", attr.Description); + } + + foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) + { + foreach (var attr in method.GetCustomAttributes()) + AddChangelogEntry(changelogByVersion, attr.Version, $"Method: {type.Name}.{method.Name}()", attr.Description); + } + } + + changelogByVersion = new Dictionary>(changelogByVersion.OrderByDescending(x => x.Key)); + + return changelogByVersion; + } + + public static string GetMarkdown(Assembly assembly) + { + var changelog = ExtractChangelog(assembly); + + var sb = new StringBuilder(); + + sb.AppendLine("# Changelog\n"); + foreach (var version in changelog) + { + sb.AppendLine($"## Version {version.Key}\n"); + foreach (var entry in version.Value) + { + sb.AppendLine($"- **{entry.Target}**: {entry.Description}"); + } + sb.AppendLine(); + } + + return sb.ToString(); + } + + private static void AddChangelogEntry(Dictionary> changelog, string version, string target, string description) + { + if (!changelog.ContainsKey(version)) + changelog[version] = new List(); + + changelog[version].Add(new Models.Changelog(target, description)); + } + } +} \ No newline at end of file diff --git a/OmegaLeo.HelperLib.ChangelogHandler/OmegaLeo.HelperLib.ChangelogHandler.csproj b/OmegaLeo.HelperLib.ChangelogHandler/OmegaLeo.HelperLib.ChangelogHandler.csproj new file mode 100644 index 0000000..649c15b --- /dev/null +++ b/OmegaLeo.HelperLib.ChangelogHandler/OmegaLeo.HelperLib.ChangelogHandler.csproj @@ -0,0 +1,15 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + diff --git a/OmegaLeo.HelperLib.ChangelogHandler/Program.cs b/OmegaLeo.HelperLib.ChangelogHandler/Program.cs new file mode 100644 index 0000000..a2538a7 --- /dev/null +++ b/OmegaLeo.HelperLib.ChangelogHandler/Program.cs @@ -0,0 +1,42 @@ +// See https://aka.ms/new-console-template for more information + +using System.Reflection; +using GameDevLibrary.Helpers; +using OmegaLeo.HelperLib.Changelog.Models; +using OmegaLeo.HelperLib.Changelog.Tools; + +var root = GetSolutionRoot(); + +var changelogs = new Dictionary() +{ + {Path.Join(root, "OmegaLeo.HelperLib.Changelog", "CHANGELOG.md"), typeof(Changelog).Assembly}, + {Path.Join(root, "OmegaLeo.HelperLib", "CHANGELOG.md"), typeof(BenchmarkUtility).Assembly}, +}; + +foreach (var changelog in changelogs) +{ + GenerateChangelog(changelog.Key, changelog.Value); +} + + +void GenerateChangelog(string path, Assembly libraryAssembly) +{ + var changelogMarkdown = ChangelogTool.GetMarkdown(libraryAssembly); + + File.WriteAllText(path,changelogMarkdown); +} + +static string GetSolutionRoot() +{ + string dir = AppContext.BaseDirectory; + + while (!string.IsNullOrEmpty(dir)) + { + if (Directory.GetFiles(dir, "*.sln").Length > 0) + return dir; // Found the solution root + + dir = Directory.GetParent(dir)?.FullName; // Move up a directory + } + + throw new Exception("Solution root not found."); +} \ No newline at end of file diff --git a/OmegaLeo.HelperLib.ConsoleApp/OmegaLeo.HelperLib.ConsoleApp.csproj b/OmegaLeo.HelperLib.ConsoleApp/OmegaLeo.HelperLib.ConsoleApp.csproj index 366bf10..ca1ddff 100644 --- a/OmegaLeo.HelperLib.ConsoleApp/OmegaLeo.HelperLib.ConsoleApp.csproj +++ b/OmegaLeo.HelperLib.ConsoleApp/OmegaLeo.HelperLib.ConsoleApp.csproj @@ -8,6 +8,7 @@ + diff --git a/OmegaLeo.HelperLib.ConsoleApp/Program.cs b/OmegaLeo.HelperLib.ConsoleApp/Program.cs index 1fe41d7..d4f2ccc 100644 --- a/OmegaLeo.HelperLib.ConsoleApp/Program.cs +++ b/OmegaLeo.HelperLib.ConsoleApp/Program.cs @@ -2,9 +2,11 @@ // /media/omegaleo/Development/Library Dev/HelperLib +using System.Reflection; using GameDevLibrary.Extensions; using GameDevLibrary.Helpers; using LibGit2Sharp; +using OmegaLeo.HelperLib.Changelog.Tools; using OmegaLeo.HelperLib.Git; using OmegaLeo.HelperLib.Git.Models; diff --git a/OmegaLeo.HelperLib.ConsoleApp/TestClass.cs b/OmegaLeo.HelperLib.ConsoleApp/TestClass.cs new file mode 100644 index 0000000..65d9104 --- /dev/null +++ b/OmegaLeo.HelperLib.ConsoleApp/TestClass.cs @@ -0,0 +1,10 @@ +using OmegaLeo.HelperLib.Changelog.Attributes; + +namespace OmegaLeo.HelperLib.ConsoleApp; + +[Changelog("v1.0.0", "Test")] +[Changelog("v1.0.1", "Test 1")] +public class TestClass +{ + +} \ No newline at end of file diff --git a/OmegaLeo.HelperLib.sln b/OmegaLeo.HelperLib.sln index a1fbcfb..c73f60a 100644 --- a/OmegaLeo.HelperLib.sln +++ b/OmegaLeo.HelperLib.sln @@ -6,6 +6,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmegaLeo.HelperLib.Git", "O EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmegaLeo.HelperLib.ConsoleApp", "OmegaLeo.HelperLib.ConsoleApp\OmegaLeo.HelperLib.ConsoleApp.csproj", "{3B77B177-FD47-470A-B0EF-01EF8B30CE09}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmegaLeo.HelperLib.Changelog", "OmegaLeo.HelperLib.Changelog\OmegaLeo.HelperLib.Changelog.csproj", "{378D8125-66B5-42B8-9881-33F951E5E04A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmegaLeo.HelperLib.ChangelogHandler", "OmegaLeo.HelperLib.ChangelogHandler\OmegaLeo.HelperLib.ChangelogHandler.csproj", "{359536F7-02DE-43E9-A383-D83853227B0F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -24,5 +28,13 @@ Global {3B77B177-FD47-470A-B0EF-01EF8B30CE09}.Debug|Any CPU.Build.0 = Debug|Any CPU {3B77B177-FD47-470A-B0EF-01EF8B30CE09}.Release|Any CPU.ActiveCfg = Release|Any CPU {3B77B177-FD47-470A-B0EF-01EF8B30CE09}.Release|Any CPU.Build.0 = Release|Any CPU + {378D8125-66B5-42B8-9881-33F951E5E04A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {378D8125-66B5-42B8-9881-33F951E5E04A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {378D8125-66B5-42B8-9881-33F951E5E04A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {378D8125-66B5-42B8-9881-33F951E5E04A}.Release|Any CPU.Build.0 = Release|Any CPU + {359536F7-02DE-43E9-A383-D83853227B0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {359536F7-02DE-43E9-A383-D83853227B0F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {359536F7-02DE-43E9-A383-D83853227B0F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {359536F7-02DE-43E9-A383-D83853227B0F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/OmegaLeo.HelperLib.sln.DotSettings.user b/OmegaLeo.HelperLib.sln.DotSettings.user index a9383eb..28e7949 100644 --- a/OmegaLeo.HelperLib.sln.DotSettings.user +++ b/OmegaLeo.HelperLib.sln.DotSettings.user @@ -1,4 +1,5 @@  + ForceIncluded ForceIncluded ForceIncluded ForceIncluded \ No newline at end of file diff --git a/OmegaLeo.HelperLib/CHANGELOG.md b/OmegaLeo.HelperLib/CHANGELOG.md new file mode 100644 index 0000000..4dc68c6 --- /dev/null +++ b/OmegaLeo.HelperLib/CHANGELOG.md @@ -0,0 +1,2 @@ +# Changelog +