diff --git a/.editorconfig b/.editorconfig index c07b3349..dbb607dd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -15,7 +15,7 @@ indent_style = space tab_width = 4 # New line preferences -end_of_line = crlf +end_of_line = unset insert_final_newline = false trim_trailing_whitespace = true @@ -24,9 +24,18 @@ end_of_line = lf [*.sln] # Visual studio defaults +end_of_line = crlf insert_final_newline = true indent_style = tab +[*.csproj] +# Visual studio defaults +end_of_line = crlf +insert_final_newline = true +indent_style = space +tab_width = 4 +indent_size = 4 + [*.md] trim_trailing_whitespace = false insert_final_newline = true # Conflicts with markdownlint when false @@ -36,10 +45,15 @@ indent_size = 2 # Incorrect indentation happens when this is not 2 indent_size = 2 # Incorrect indentation happens when this is not 2 [*.ps1] +end_of_line = crlf charset = utf-8-bom indent_style = space indent_size = 2 [*.js] indent_style = tab -indent_size = 2 \ No newline at end of file +indent_size = 2 + +[*.{bat,cmd}] +end_of_line = crlf +charset = latin1 \ No newline at end of file diff --git a/.gitattributes b/.gitattributes index 2363e13d..68cc7e0c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,29 +1,104 @@ -* text eol=crlf whitespace=tab-in-indent,tabwidth=4 - -*.sh text eol=lf - -*.md text whitespace=-blank-at-eol - -# Custom for Visual Studio -*.cs text diff=csharp -*.sln merge=union whitespace=-tab-in-indent,-blank-at-eof,indent-with-non-tab -*.csproj merge=union -*.vbproj merge=union -*.fsproj merge=union -*.dbproj merge=union - -# Standard to msysgit -*.doc diff=astextplain -*.DOC diff=astextplain -*.docx diff=astextplain -*.DOCX diff=astextplain -*.dot diff=astextplain -*.DOT diff=astextplain -*.pdf diff=astextplain -*.PDF diff=astextplain -*.rtf diff=astextplain -*.RTF diff=astextplain - -*.png binary - -.editorconfig text whitespace=-blank-at-eol \ No newline at end of file +# Common settings that generally should always be used with your language specific settings + +# Auto detect text files and perform LF normalization +* text=auto + +# +# The above will handle all files NOT found below +# + +# Documents +*.bibtex text diff=bibtex +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain +*.md text diff=markdown +*.mdx text diff=markdown +*.tex text diff=tex +*.adoc text +*.textile text +*.mustache text +*.csv text eol=crlf +*.tab text +*.tsv text +*.txt text +*.sql text +*.epub diff=astextplain + +# Graphics +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.tif binary +*.tiff binary +*.ico binary +# SVG treated as text by default. +*.svg text +# If you want to treat it as binary, +# use the following line instead. +# *.svg binary +*.eps binary + +# Scripts +*.bash text eol=lf +*.fish text eol=lf +*.ksh text eol=lf +*.sh text eol=lf +*.zsh text eol=lf +# These are explicitly windows files and should use crlf +*.bat text eol=crlf +*.cmd text eol=crlf +*.ps1 text eol=crlf + +# Serialisation +*.json text +*.toml text +*.xml text +*.yaml text +*.yml text + +# Archives +*.7z binary +*.bz binary +*.bz2 binary +*.bzip2 binary +*.gz binary +*.lz binary +*.lzma binary +*.rar binary +*.tar binary +*.taz binary +*.tbz binary +*.tbz2 binary +*.tgz binary +*.tlz binary +*.txz binary +*.xz binary +*.Z binary +*.zip binary +*.zst binary + +# Text files where line endings should be preserved +*.patch -text + +*.cs text diff=csharp +*.cshtml text diff=html +*.csx text diff=csharp +*.sln text eol=crlf +*.csproj text eol=crlf + +# +# Exclude files from exporting +# + +.gitattributes export-ignore +.gitignore export-ignore +.gitkeep export-ignore \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 08b7f751..4dc33091 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,7 +1,28 @@ version: 2 updates: +- package-ecosystem: github-actions + directory: "/" + labels: + - "Build" + schedule: + interval: daily - package-ecosystem: nuget directory: "/src" + labels: + - "Build" + groups: + analyzers: + patterns: + - "*Analyzers" + serilog: + patterns: + - "Serilog.*" + tests: + patterns: + - "NUnit.*" + - "Microsoft.NET.Test.Sdk" + - "NSubstitute" + - "coverlet.msbuild" schedule: interval: daily open-pull-requests-limit: 10 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e9da64c4..e51cabf7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,31 +35,32 @@ jobs: WYAM_DEPLOY_REMOTE: https://github.com/GitTools/GitReleaseManager CODECOV_REPO_TOKEN: ${{ secrets.CODECOV_REPO_TOKEN }} GPR_USER: gittools-bot - GPR_PASSWORD: ${{ secrets.GPR_PASSWORD }} + GPR_PASSWORD: ${{ secrets.NUGET_GITHUB_TOKEN }} steps: - name: Checkout the repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Fetch all tags and branches run: git fetch --prune --unshallow - - name: Install .NET SDK 2.1.x, 3.1.x, 5.0.x, and 6.0.x - uses: actions/setup-dotnet@v3 + - name: Install .NET SDK 2.1.x, 3.1.x, 5.0.x, 6.0.x, and 7.0.x + uses: actions/setup-dotnet@v4 with: dotnet-version: | 2.1.x 3.1.x 5.0.x 6.0.x + 7.0.x - name: Cache Tools - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: tools key: ${{ runner.os }}-tools-${{ hashFiles('recipe.cake') }} - name: Build project - uses: cake-build/cake-action@v1 + uses: cake-build/cake-action@v3 with: script-path: recipe.cake target: CI @@ -67,14 +68,14 @@ jobs: cake-version: tool-manifest - name: Upload Issues-Report - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: if-no-files-found: warn name: ${{ matrix.os }} issues path: BuildArtifacts/report.html - name: Upload Packages - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 if: runner.os == 'Windows' with: if-no-files-found: warn diff --git a/GitReleaseManager.yaml b/GitReleaseManager.yaml index 19f4193f..0adbfb05 100644 --- a/GitReleaseManager.yaml +++ b/GitReleaseManager.yaml @@ -19,8 +19,10 @@ create: include-sha-section: true sha-section-heading: "SHA256 Hashes of the release artifacts" sha-section-line-format: "- `{1}\t{0}`" + include-contributors: true close: use-issue-comments: true + set-due-date: true issue-comment: |- :tada: This issue has been resolved in version {milestone} :tada: diff --git a/docs/input/docs/configuration/default-configuration.md b/docs/input/docs/configuration/default-configuration.md index a4fc818e..de4055a6 100644 --- a/docs/input/docs/configuration/default-configuration.md +++ b/docs/input/docs/configuration/default-configuration.md @@ -20,6 +20,7 @@ create: sha-section-heading: "SHA256 Hashes of the release artifacts" sha-section-line-format: "- `{1}\t{0}`" allow-update-to-published: false + include-contributors: false export: include-created-date-in-title: false created-date-string-format: '' @@ -28,6 +29,7 @@ export: multiline-regex: false close: use-issue-comments: false + set-due-date: false issue-comment: |- :tada: This issue has been resolved in version {milestone} :tada: @@ -135,6 +137,11 @@ control the look and feel of the generated release notes. - A boolean value which indicates whether or not updates can be applied to published releases. The default value is false. **NOTE:** This configuration option was added in version 0.11.0 of GitReleaseManager. +- **include-contributors** + - A boolean value which indicates whether the list of contributors is included + in the release notes. A contributor is defined as someone who opened an issue + or submitted a PR. **NOTE:** This configuration option was added in version + 0.19.0 of GitReleaseManager. See the [example create configuration section](create-configuration) to see an example of how a footer can be configured. @@ -176,10 +183,16 @@ tokenized values, such as milestone, owner, repository, with the actual values. - A boolean value which indicates whether or not comments are added to any closed issues that are included within a milestone, when it is being closed. - - **issue-comment** - - This is a template for what comment should be added to each issue. Within +- **issue-comment** + - This is a template for what comment should be added to each issue. Within this comment template, it is possible to replace information for example, the milestone name, the owner/repository information, etc. +- **set-due-date** + - A boolean value which indicates whether or not to set the due date of the + milestone when closing it. The date which it is set to, is the same as the + date at which the command was run, it is not possible to provide a + different date. **NOTE:** This configuration option was added in version + 0.19.0 of GitReleaseManager. ## Default branch diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 1edd6be7..5f9ac9f3 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -14,20 +14,20 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + runtime; build; native; contentfiles; analyzers; buildtransitive all - + All diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props new file mode 100644 index 00000000..82a68959 --- /dev/null +++ b/src/Directory.Packages.props @@ -0,0 +1,39 @@ + + + true + true + $(NoWarn);NU1507 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/GitReleaseManager.Cli/GitReleaseManager.Cli.csproj b/src/GitReleaseManager.Cli/GitReleaseManager.Cli.csproj index 43f1f73b..a3c7fb80 100644 --- a/src/GitReleaseManager.Cli/GitReleaseManager.Cli.csproj +++ b/src/GitReleaseManager.Cli/GitReleaseManager.Cli.csproj @@ -16,17 +16,18 @@ - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all - - - - - + + + + + + - \ No newline at end of file + diff --git a/src/GitReleaseManager.Cli/Program.cs b/src/GitReleaseManager.Cli/Program.cs index dc44e89c..96280e1c 100644 --- a/src/GitReleaseManager.Cli/Program.cs +++ b/src/GitReleaseManager.Cli/Program.cs @@ -13,6 +13,8 @@ using GitReleaseManager.Core.Provider; using GitReleaseManager.Core.ReleaseNotes; using GitReleaseManager.Core.Templates; +using GraphQL.Client.Http; +using GraphQL.Client.Serializer.SystemTextJson; using Microsoft.Extensions.DependencyInjection; using NGitLab; using Octokit; @@ -211,6 +213,12 @@ private static void RegisterVcsProvider(BaseVcsOptions vcsOptions, IServiceColle // default to Github serviceCollection .AddSingleton((_) => new GitHubClient(new ProductHeaderValue("GitReleaseManager")) { Credentials = new Credentials(vcsOptions.Token) }) + .AddSingleton(_ => + { + var client = new GraphQLHttpClient(new GraphQLHttpClientOptions { EndPoint = new Uri("https://api.github.com/graphql") }, new SystemTextJsonSerializer()); + client.HttpClient.DefaultRequestHeaders.Add("Authorization", $"bearer {vcsOptions.Token}"); + return client; + }) .AddSingleton(); } } diff --git a/src/GitReleaseManager.Core.Tests/GitReleaseManager.Core.Tests.csproj b/src/GitReleaseManager.Core.Tests/GitReleaseManager.Core.Tests.csproj index c12da586..6cd27416 100644 --- a/src/GitReleaseManager.Core.Tests/GitReleaseManager.Core.Tests.csproj +++ b/src/GitReleaseManager.Core.Tests/GitReleaseManager.Core.Tests.csproj @@ -1,36 +1,37 @@ - 8.0 + 9.0 net6.0;net7.0 GitReleaseManager.Core.Tests Test Project for GitReleaseManager.Core $(NoWarn);CA1707;Serilog004; - + - - runtime; build; native; contentfiles; analyzers; buildtransitive - all + + runtime; build; native; contentfiles; analyzers; buildtransitive + all - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all - - - - all - runtime; build; native; contentfiles; analyzers + + + + + all + runtime; build; native; contentfiles; analyzers - - - + + + - \ No newline at end of file + diff --git a/src/GitReleaseManager.Core.Tests/Provider/GitHubProviderTests.cs b/src/GitReleaseManager.Core.Tests/Provider/GitHubProviderTests.cs index a9e1c563..a70d9c58 100644 --- a/src/GitReleaseManager.Core.Tests/Provider/GitHubProviderTests.cs +++ b/src/GitReleaseManager.Core.Tests/Provider/GitHubProviderTests.cs @@ -20,7 +20,7 @@ using NotFoundException = GitReleaseManager.Core.Exceptions.NotFoundException; using RateLimit = GitReleaseManager.Core.Model.RateLimit; using Release = GitReleaseManager.Core.Model.Release; -using ReleaseAsset= GitReleaseManager.Core.Model.ReleaseAsset; +using ReleaseAsset = GitReleaseManager.Core.Model.ReleaseAsset; using ReleaseAssetUpload = GitReleaseManager.Core.Model.ReleaseAssetUpload; namespace GitReleaseManager.Core.Tests.Provider diff --git a/src/GitReleaseManager.Core.Tests/VcsServiceTests.cs b/src/GitReleaseManager.Core.Tests/VcsServiceTests.cs index 86306af7..03de7a4d 100644 --- a/src/GitReleaseManager.Core.Tests/VcsServiceTests.cs +++ b/src/GitReleaseManager.Core.Tests/VcsServiceTests.cs @@ -350,8 +350,7 @@ public async Task Should_Create_Release_From_Milestone_With_Assets() null, _assets, false, - null - ).ConfigureAwait(false); + null).ConfigureAwait(false); result.ShouldBeSameAs(release); await _releaseNotesBuilder.Received(1).BuildReleaseNotesAsync(OWNER, REPOSITORY, MILESTONE_TITLE, ReleaseTemplates.DEFAULT_NAME).ConfigureAwait(false); diff --git a/src/GitReleaseManager.Core/Configuration/CloseConfig.cs b/src/GitReleaseManager.Core/Configuration/CloseConfig.cs index 48495888..dce0696f 100644 --- a/src/GitReleaseManager.Core/Configuration/CloseConfig.cs +++ b/src/GitReleaseManager.Core/Configuration/CloseConfig.cs @@ -22,5 +22,12 @@ public sealed class CloseConfig [Sample(":tada: This issue has been resolved in version {milestone} :tada:\n\nThe release is available on:\n\n- [NuGet package(@{milestone})](https://nuget.org/packages/{repository}/{milestone})\n- [GitHub release](https://github.com/{owner}/{repository}/releases/tag/{milestone})\n\nYour **[GitReleaseManager](https://github.com/GitTools/GitReleaseManager)** bot :package::rocket:")] [YamlMember(Alias = "issue-comment", ScalarStyle = YamlDotNet.Core.ScalarStyle.Literal)] public string IssueCommentFormat { get; set; } + + /// + /// Gets or sets a value indicating whether the due date should be set when closing the milestone. + /// + [Description("Whether to set the due date when closing the milestone.")] + [YamlMember(Alias = "set-due-date")] + public bool SetDueDate { get; set; } } } \ No newline at end of file diff --git a/src/GitReleaseManager.Core/Configuration/Config.cs b/src/GitReleaseManager.Core/Configuration/Config.cs index 15083cc2..262c12bc 100644 --- a/src/GitReleaseManager.Core/Configuration/Config.cs +++ b/src/GitReleaseManager.Core/Configuration/Config.cs @@ -27,6 +27,7 @@ public Config() ShaSectionHeading = "SHA256 Hashes of the release artifacts", ShaSectionLineFormat = "- `{1}\t{0}`", AllowUpdateToPublishedRelease = false, + IncludeContributors = false, }; Export = new ExportConfig @@ -42,6 +43,7 @@ public Config() { IssueComments = false, IssueCommentFormat = ISSUE_COMMENT_FORMAT, + SetDueDate = false, // by default, do not set the due date to match previous behavior }; DefaultBranch = "master"; diff --git a/src/GitReleaseManager.Core/Configuration/CreateConfig.cs b/src/GitReleaseManager.Core/Configuration/CreateConfig.cs index 512e4a28..00baed7d 100644 --- a/src/GitReleaseManager.Core/Configuration/CreateConfig.cs +++ b/src/GitReleaseManager.Core/Configuration/CreateConfig.cs @@ -34,5 +34,8 @@ public class CreateConfig [YamlMember(Alias = "allow-update-to-published")] public bool AllowUpdateToPublishedRelease { get; set; } + + [YamlMember(Alias = "include-contributors")] + public bool IncludeContributors { get; set; } } } \ No newline at end of file diff --git a/src/GitReleaseManager.Core/Exceptions/InvalidIssuesException.cs b/src/GitReleaseManager.Core/Exceptions/InvalidIssuesException.cs index bad42797..c9ecda2d 100644 --- a/src/GitReleaseManager.Core/Exceptions/InvalidIssuesException.cs +++ b/src/GitReleaseManager.Core/Exceptions/InvalidIssuesException.cs @@ -37,4 +37,4 @@ protected InvalidIssuesException( { } } -} +} \ No newline at end of file diff --git a/src/GitReleaseManager.Core/Extensions/JsonExtensions.cs b/src/GitReleaseManager.Core/Extensions/JsonExtensions.cs new file mode 100644 index 00000000..d8920c65 --- /dev/null +++ b/src/GitReleaseManager.Core/Extensions/JsonExtensions.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; + +namespace GitReleaseManager.Core.Extensions +{ + internal static class JsonExtensions + { + /// + /// Get a JsonElement from a path. Each level in the path is seperated by a dot. + /// + /// The parent Json element. + /// The path of the desired child element. + /// The child element. + public static JsonElement GetJsonElement(this JsonElement jsonElement, string path) + { + if (jsonElement.ValueKind is JsonValueKind.Null || jsonElement.ValueKind is JsonValueKind.Undefined) + { + return default(JsonElement); + } + + string[] segments = path.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); + + foreach (var segment in segments) + { + if (int.TryParse(segment, out var index) && jsonElement.ValueKind == JsonValueKind.Array) + { + jsonElement = jsonElement.EnumerateArray().ElementAtOrDefault(index); + if (jsonElement.ValueKind is JsonValueKind.Null || jsonElement.ValueKind is JsonValueKind.Undefined) + { + return default(JsonElement); + } + + continue; + } + + jsonElement = jsonElement.TryGetProperty(segment, out var value) ? value : default; + + if (jsonElement.ValueKind is JsonValueKind.Null || jsonElement.ValueKind is JsonValueKind.Undefined) + { + return default(JsonElement); + } + } + + return jsonElement; + } + + /// + /// Get the first JsonElement matching a path from the provided list of paths. + /// + /// The parent Json element. + /// The path of the desired child element. + /// The child element. + public static JsonElement GetFirstJsonElement(this JsonElement jsonElement, IEnumerable paths) + { + if (jsonElement.ValueKind is JsonValueKind.Null || jsonElement.ValueKind is JsonValueKind.Undefined) + { + return default(JsonElement); + } + + var element = default(JsonElement); + + foreach (var path in paths) + { + element = jsonElement.GetJsonElement(path); + + if (element.ValueKind is JsonValueKind.Null || element.ValueKind is JsonValueKind.Undefined) + { + continue; + } + + break; + } + + return element; + } + + public static string GetJsonElementValue(this JsonElement jsonElement) => jsonElement.ValueKind != JsonValueKind.Null && + jsonElement.ValueKind != JsonValueKind.Undefined + ? jsonElement.ToString() + : default; + } +} diff --git a/src/GitReleaseManager.Core/GitReleaseManager.Core.csproj b/src/GitReleaseManager.Core/GitReleaseManager.Core.csproj index bca953b3..7e614e0c 100644 --- a/src/GitReleaseManager.Core/GitReleaseManager.Core.csproj +++ b/src/GitReleaseManager.Core/GitReleaseManager.Core.csproj @@ -17,18 +17,20 @@ - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all - - - - - - + + + + + + @@ -38,13 +40,13 @@ - - TextTemplatingFileGenerator - ReleaseTemplates.g.cs - - + + TextTemplatingFileGenerator + ReleaseTemplates.g.cs + + - + - \ No newline at end of file + diff --git a/src/GitReleaseManager.Core/MappingProfiles/GitHubProfile.cs b/src/GitReleaseManager.Core/MappingProfiles/GitHubProfile.cs index dff999dc..11e90526 100644 --- a/src/GitReleaseManager.Core/MappingProfiles/GitHubProfile.cs +++ b/src/GitReleaseManager.Core/MappingProfiles/GitHubProfile.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json; using AutoMapper; using GitReleaseManager.Core.Extensions; @@ -8,10 +9,11 @@ public class GitHubProfile : Profile { public GitHubProfile() { + // These mappings convert the result of Octokit queries to model classes CreateMap() .ForMember(dest => dest.PublicNumber, act => act.MapFrom(src => src.Number)) .ForMember(dest => dest.InternalNumber, act => act.MapFrom(src => src.Id)) - .ForMember(dest => dest.IsPullRequest, act => act.MapFrom(src => src.HtmlUrl.IndexOf("/pull/", StringComparison.OrdinalIgnoreCase) >= 0)) + .ForMember(dest => dest.IsPullRequest, act => act.MapFrom(src => src.HtmlUrl.Contains("/pull/", StringComparison.OrdinalIgnoreCase))) .ReverseMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); @@ -23,11 +25,35 @@ public GitHubProfile() CreateMap().ReverseMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); + CreateMap().ReverseMap(); CreateMap(); CreateMap() .ForMember(dest => dest.PublicNumber, act => act.MapFrom(src => src.Number)) .ForMember(dest => dest.InternalNumber, act => act.MapFrom(src => src.Number)) .AfterMap((src, dest) => dest.Version = src.Version()); + + // These mappings convert the result of GraphQL queries to model classes + CreateMap() + .ForMember(dest => dest.PublicNumber, act => act.MapFrom(src => src.GetProperty("number").GetInt32())) + .ForMember(dest => dest.InternalNumber, act => act.MapFrom(src => -1)) // Not available in graphQL (there's a "id" property but it contains a string which represents the Node ID of the object). + .ForMember(dest => dest.Title, act => act.MapFrom(src => src.GetProperty("title").GetString())) + .ForMember(dest => dest.HtmlUrl, act => act.MapFrom(src => src.GetProperty("url").GetString())) + .ForMember(dest => dest.IsPullRequest, act => act.MapFrom(src => src.GetProperty("url").GetString().Contains("/pull/", StringComparison.OrdinalIgnoreCase))) + .ForMember(dest => dest.User, act => act.MapFrom(src => src.GetProperty("author"))) + .ForMember(dest => dest.Labels, act => act.MapFrom(src => src.GetJsonElement("labels.nodes").EnumerateArray())) + .ReverseMap(); + + CreateMap() + .ForMember(dest => dest.Name, act => act.MapFrom(src => src.GetProperty("name").GetString())) + .ForMember(dest => dest.Color, act => act.MapFrom(src => src.GetProperty("color").GetString())) + .ForMember(dest => dest.Description, act => act.MapFrom(src => src.GetProperty("description").GetString())) + .ReverseMap(); + + CreateMap() + .ForMember(dest => dest.Login, act => act.MapFrom(src => src.GetProperty("login").GetString())) + .ForMember(dest => dest.HtmlUrl, act => act.MapFrom(src => $"https://github.com{src.GetProperty("resourcePath").GetString()}")) // The resourcePath contains a value similar to "/jericho". That's why we must manually prepend "https://github.com + .ForMember(dest => dest.AvatarUrl, act => act.MapFrom(src => src.GetProperty("avatarUrl").GetString())) + .ReverseMap(); } } } \ No newline at end of file diff --git a/src/GitReleaseManager.Core/MappingProfiles/GitLabProfile.cs b/src/GitReleaseManager.Core/MappingProfiles/GitLabProfile.cs index c209654d..0fad81b0 100644 --- a/src/GitReleaseManager.Core/MappingProfiles/GitLabProfile.cs +++ b/src/GitReleaseManager.Core/MappingProfiles/GitLabProfile.cs @@ -23,12 +23,14 @@ public GitLabProfile() .ForMember(dest => dest.PublicNumber, act => act.MapFrom(src => src.IssueId)) .ForMember(dest => dest.HtmlUrl, act => act.MapFrom(src => src.WebUrl)) .ForMember(dest => dest.IsPullRequest, act => act.MapFrom(src => false)) + .ForMember(dest => dest.User, act => act.MapFrom(src => src.Author)) .ReverseMap(); CreateMap() .ForMember(dest => dest.InternalNumber, act => act.MapFrom(src => src.Id)) .ForMember(dest => dest.PublicNumber, act => act.MapFrom(src => src.Iid)) .ForMember(dest => dest.HtmlUrl, act => act.MapFrom(src => src.WebUrl)) .ForMember(dest => dest.IsPullRequest, act => act.MapFrom(src => true)) + .ForMember(dest => dest.User, act => act.MapFrom(src => src.Author)) .ReverseMap(); CreateMap().ForMember(dest => dest.Name, act => act.MapFrom(src => src)); CreateMap() @@ -43,6 +45,16 @@ public GitLabProfile() .ReverseMap(); CreateMap() .ReverseMap(); + CreateMap() + .ForMember(dest => dest.Username, act => act.MapFrom(src => src.Login)) + .ForMember(dest => dest.WebURL, act => act.MapFrom(src => src.HtmlUrl)) + .ForMember(dest => dest.AvatarURL, act => act.MapFrom(src => src.AvatarUrl)) + .ReverseMap(); + CreateMap() + .ForMember(dest => dest.Username, act => act.MapFrom(src => src.Login)) + .ForMember(dest => dest.WebUrl, act => act.MapFrom(src => src.HtmlUrl)) + .ForMember(dest => dest.AvatarUrl, act => act.MapFrom(src => src.AvatarUrl)) + .ReverseMap(); } } -} +} \ No newline at end of file diff --git a/src/GitReleaseManager.Core/Model/Issue.cs b/src/GitReleaseManager.Core/Model/Issue.cs index 222d8eb9..5ad73c7c 100644 --- a/src/GitReleaseManager.Core/Model/Issue.cs +++ b/src/GitReleaseManager.Core/Model/Issue.cs @@ -15,5 +15,9 @@ public sealed class Issue public IReadOnlyList