diff --git a/.appveyor.yml b/.appveyor.yml index c38995ae..20636ca0 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -8,7 +8,7 @@ image: Visual Studio 2019 # Build Script # #---------------------------------# build_script: - - ps: .\build.ps1 -Target ContinuousIntegration + - ps: .\build.ps1 --target=CI #---------------------------------# # Tests diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 00000000..473566e3 --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "cake.tool": { + "version": "0.38.5", + "commands": [ + "dotnet-cake" + ] + } + } +} \ No newline at end of file diff --git a/.editorconfig b/.editorconfig index 407b825f..c07b3349 100644 --- a/.editorconfig +++ b/.editorconfig @@ -3,6 +3,10 @@ root = true +# Keep this file simple, only basic formatting should be +# defined here. +# Code styles should be defined in src/.editorconfig + [*] charset = utf-8 # Just for consistency # Indentation and spacing diff --git a/.gitattributes b/.gitattributes index 69a0b315..2363e13d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -24,4 +24,6 @@ *.rtf diff=astextplain *.RTF diff=astextplain -*.png binary \ No newline at end of file +*.png binary + +.editorconfig text whitespace=-blank-at-eol \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..08b7f751 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: +- package-ecosystem: nuget + directory: "/src" + schedule: + interval: daily + open-pull-requests-limit: 10 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..0e9ed5c8 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,57 @@ +name: Build + +on: + push: + branches: + - master + - develop + - "feature/**" + - "release/**" + - "hotfix/**" + tags: + - "*" + pull_request: + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ windows-2019 ] + + steps: + - name: Checkout the repository + uses: actions/checkout@v2 + + - name: Fetch all tags and branches + run: git fetch --prune --unshallow + + - name: Cache Tools + uses: actions/cache@v2 + with: + path: tools + key: ${{ runner.os }}-tools-${{ hashFiles('recipe.cake') }} + + - name: Build project + uses: cake-build/cake-action@v1 + with: + script-path: recipe.cake + target: CI + verbosity: Normal + cake-version: 0.38.5 + cake-bootstrap: true + + - name: Upload Issues-Report + uses: actions/upload-artifact@v2 + with: + if-no-files-found: warn + name: ${{ matrix.os }} issues + path: BuildArtifacts/report.html + + - name: Upload Packages + uses: actions/upload-artifact@v2 + if: runner.os == 'Windows' + with: + if-no-files-found: warn + name: package + path: BuildArtifacts/Packages/**/* \ No newline at end of file diff --git a/.gitignore b/.gitignore index 604391e2..896e6f6c 100644 --- a/.gitignore +++ b/.gitignore @@ -327,3 +327,4 @@ config.wyam.packages.xml # Integration Tests tests/integration/tools tests/integration/output +*.g.cs diff --git a/.vscode/settings.json b/.vscode/settings.json index 63837142..19655ed8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,13 +1,17 @@ { "editor.rulers": [80], "cSpell.words": [ + "Usings", "addasset", "buildartifacts", "choco", "gitreleasemanager", "nupkg", "psake", + "readonly", "releasenotes", "showconfig" - ] + ], + "omnisharp.enableEditorConfigSupport": true, + "omnisharp.enableRoslynAnalyzers": true } \ No newline at end of file diff --git a/Documentation/Legal/CREDITS.md b/CREDITS.md similarity index 87% rename from Documentation/Legal/CREDITS.md rename to CREDITS.md index bc87f270..7a752898 100644 --- a/Documentation/Legal/CREDITS.md +++ b/CREDITS.md @@ -7,6 +7,7 @@ GitReleaseManager has been the thoughts and work of the following people: These are the committers to GitTools/GitReleaseManager repository: - [Gary Ewan Park](https://github.com/gep13) - Creater of GitReleaseManager, committer, vision, direction +- [Kim Nordmo](https://github.com/AdmiringWorm) - Committer, vision direction ### Contributors @@ -25,10 +26,9 @@ GitReleaseManager uses the following awesome frameworks (in no particular order) GitReleaseManager is built, with the following fantastic frameworks and services (in no particular order): -- [psake](https://github.com/psake/psake) +- [Cake](https://github.com/cake-build/cake) - [NuGet.exe](https://www.nuget.org/) - [AppVeyor](http://www.appveyor.com/) -- [MyGet](http://www.myget.org/) GitReleaseManager is tested and analyzed with the following rockstar frameworks (in no particular order): @@ -37,7 +37,6 @@ GitReleaseManager is tested and analyzed with the following rockstar frameworks - [InspectCode](https://confluence.jetbrains.com/display/NETCOM/Introducing+InspectCode) - [DupFinder](https://confluence.jetbrains.com/display/NETCOM/Introducing+dupFinder) - [Coveralls](https://coveralls.io/) -- [Coverity Scan](https://scan.coverity.com/) - [NUnit](http://www.nunit.org/) - [OpenCover](https://github.com/opencover/opencover) @@ -45,5 +44,3 @@ We would like to credit other super sweet tools/frameworks that aid in the devel - [ReSharper](https://www.jetbrains.com/resharper/) - [NuGet Framework](https://www.nuget.org/) -- [ReportGenerator](http://danielpalme.github.io/ReportGenerator/) -- [PublishCoverity](http://www.nuget.org/packages/PublishCoverity/) diff --git a/README.md b/README.md index a4d31aa6..d26c0420 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ # GitReleaseManager -![Icon](https://raw.github.com/GitTools/GitReleaseManager/develop/Icons/package_icon_no_credit.png) +![Icon](https://raw.github.com/GitTools/GitReleaseManager/develop/icons/package_icon_no_credit.png) [![License](https://img.shields.io/:license-mit-blue.svg)](https://gep13.mit-license.org) [![Coverage Status](https://coveralls.io/repos/GitTools/GitReleaseManager/badge.svg?branch=develop)](https://coveralls.io/r/GitTools/GitReleaseManager?branch=develop) -[![Coverity Scan Build Status](https://scan.coverity.com/projects/5110/badge.svg)](https://scan.coverity.com/projects/5110) Do you detest creating release notes for your software applications hosted on GitHub? If so, this is the tool for you. @@ -22,18 +21,34 @@ GitReleaseManager allows you to: ## Installation +### .NET Global Tool + +To install GitReleaseManager as a .NET Global tool, execute: + +```sh +dotnet tool install --global GitReleaseManager.Tool +``` + +### Chocolatey + You can install GitReleaseManager via Chocolatey by executing: -`choco install gitreleasemanager.portable` +```sh +choco install gitreleasemanager.portable +``` **NOTE:** Depending on which version of Chocolatey you are using, you may be required to confirm the installation of the application. You can avoid this prompt using the following command: -`choco install gitreleasemanager.portable -y` +```sh +choco install gitreleasemanager.portable -y +``` If you are interested in trying out the latest pre-release version of GitReleaseManager then you can use the following installation command: -`choco install gitreleasemanager.portable -source https://www.myget.org/F/grm_develop/ -pre` +```sh +choco install gitreleasemanager.portable -source https://www.myget.org/F/grm_develop/ -pre +``` This uses the public GitReleaseManager feed which is hosted on [MyGet.org](https://www.myget.org/) @@ -63,7 +78,7 @@ The documentation for GitReleaseManager can be found on [here](https://gittools. ## Credits -GitReleaseManager is brought to you by quite a few people and frameworks. See [CREDITS](https://github.com/GitTools/GitReleaseManager/blob/develop/Documentation/Legal/CREDITS.md) for full information. +GitReleaseManager is brought to you by quite a few people and frameworks. See [CREDITS](https://github.com/GitTools/GitReleaseManager/blob/develop/CREDITS.md) for full information. Full original credit has to go to the people at [Particular Software](https://www.particular.net/), without whom this project would not have been possible. They originally created the [GitHubReleaseNotes](https://github.com/Particular/GitHubReleaseNotes) project, which GitReleaseManager is based on, and draws a lot of inspiration from. diff --git a/Source/.editorconfig b/Source/.editorconfig deleted file mode 100644 index 1edc9f8c..00000000 --- a/Source/.editorconfig +++ /dev/null @@ -1,194 +0,0 @@ -# C# files -[*.cs] - -#### Core EditorConfig Options #### - -#### .NET Coding Conventions #### - -# Organize usings -dotnet_separate_import_directive_groups = false -dotnet_sort_system_directives_first = true - -# this. and Me. preferences -dotnet_style_qualification_for_event = false:silent -dotnet_style_qualification_for_field = false:silent -dotnet_style_qualification_for_method = false:silent -dotnet_style_qualification_for_property = false:error - -# Language keywords vs BCL types preferences -dotnet_style_predefined_type_for_locals_parameters_members = true:silent -dotnet_style_predefined_type_for_member_access = true:silent - -# Parentheses preferences -dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent -dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent - -# Modifier preferences -dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent - -# Expression-level preferences -csharp_style_deconstructed_variable_declaration = true:suggestion -csharp_style_inlined_variable_declaration = true:suggestion -csharp_style_throw_expression = true:suggestion -dotnet_style_coalesce_expression = true:suggestion -dotnet_style_collection_initializer = true:suggestion -dotnet_style_explicit_tuple_names = true:suggestion -dotnet_style_null_propagation = true:suggestion -dotnet_style_object_initializer = true:suggestion -dotnet_style_prefer_auto_properties = true:silent -dotnet_style_prefer_compound_assignment = true:suggestion -dotnet_style_prefer_conditional_expression_over_assignment = true:silent -dotnet_style_prefer_conditional_expression_over_return = true:silent -dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion -dotnet_style_prefer_inferred_tuple_names = true:suggestion -dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion - -# Field preferences -dotnet_style_readonly_field = true:suggestion - -# Parameter preferences -dotnet_code_quality_unused_parameters = all:suggestion - -#### C# Coding Conventions #### - -# var preferences -csharp_style_var_elsewhere = false:silent -csharp_style_var_for_built_in_types = false:silent -csharp_style_var_when_type_is_apparent = false:silent - -# Expression-bodied members -csharp_style_expression_bodied_accessors = true:silent -csharp_style_expression_bodied_constructors = false:silent -csharp_style_expression_bodied_indexers = true:silent -csharp_style_expression_bodied_lambdas = true:silent -csharp_style_expression_bodied_local_functions = false:silent -csharp_style_expression_bodied_methods = false:silent -csharp_style_expression_bodied_operators = false:silent -csharp_style_expression_bodied_properties = true:silent - -# Pattern matching preferences -csharp_style_pattern_matching_over_as_with_null_check = true:suggestion -csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion -csharp_style_prefer_switch_expression = true:suggestion - -# Null-checking preferences -csharp_style_conditional_delegate_call = true:suggestion - -# Modifier preferences -csharp_prefer_static_local_function = true:suggestion -csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async - -# Code-block preferences -csharp_prefer_braces = true:silent -csharp_prefer_simple_using_statement = true:silent - -# Expression-level preferences -csharp_prefer_simple_default_expression = true:suggestion -csharp_style_pattern_local_over_anonymous_function = true:suggestion -csharp_style_prefer_index_operator = true:suggestion -csharp_style_prefer_range_operator = true:suggestion -csharp_style_unused_value_assignment_preference = discard_variable:suggestion -csharp_style_unused_value_expression_statement_preference = discard_variable:silent - -# 'using' directive preferences -csharp_using_directive_placement = outside_namespace:silent - -#### C# Formatting Rules #### - -# New line preferences -csharp_new_line_before_catch = true -csharp_new_line_before_else = true -csharp_new_line_before_finally = true -csharp_new_line_before_members_in_anonymous_types = true -csharp_new_line_before_members_in_object_initializers = true -csharp_new_line_before_open_brace = all -csharp_new_line_between_query_expression_clauses = true - -# Indentation preferences -csharp_indent_block_contents = true -csharp_indent_braces = false -csharp_indent_case_contents = true -csharp_indent_case_contents_when_block = true -csharp_indent_labels = one_less_than_current -csharp_indent_switch_labels = true - -# Space preferences -csharp_space_after_cast = false -csharp_space_after_colon_in_inheritance_clause = true -csharp_space_after_comma = true -csharp_space_after_dot = false -csharp_space_after_keywords_in_control_flow_statements = true -csharp_space_after_semicolon_in_for_statement = true -csharp_space_around_binary_operators = before_and_after -csharp_space_around_declaration_statements = false -csharp_space_before_colon_in_inheritance_clause = true -csharp_space_before_comma = false -csharp_space_before_dot = false -csharp_space_before_open_square_brackets = false -csharp_space_before_semicolon_in_for_statement = false -csharp_space_between_empty_square_brackets = false -csharp_space_between_method_call_empty_parameter_list_parentheses = false -csharp_space_between_method_call_name_and_opening_parenthesis = false -csharp_space_between_method_call_parameter_list_parentheses = false -csharp_space_between_method_declaration_empty_parameter_list_parentheses = false -csharp_space_between_method_declaration_name_and_open_parenthesis = false -csharp_space_between_method_declaration_parameter_list_parentheses = false -csharp_space_between_parentheses = false -csharp_space_between_square_brackets = false - -# Wrapping preferences -csharp_preserve_single_line_blocks = true -csharp_preserve_single_line_statements = true - -#### Naming styles #### - -# Naming rules - -dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion -dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface -dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i - -dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.types_should_be_pascal_case.symbols = types -dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case - -dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members -dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case - -# Symbol specifications - -dotnet_naming_symbols.interface.applicable_kinds = interface -dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.interface.required_modifiers = - -dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum -dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.types.required_modifiers = - -dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method -dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.non_field_members.required_modifiers = - -# Naming styles - -dotnet_naming_style.pascal_case.required_prefix = -dotnet_naming_style.pascal_case.required_suffix = -dotnet_naming_style.pascal_case.word_separator = -dotnet_naming_style.pascal_case.capitalization = pascal_case - -dotnet_naming_style.begins_with_i.required_prefix = I -dotnet_naming_style.begins_with_i.required_suffix = -dotnet_naming_style.begins_with_i.word_separator = -dotnet_naming_style.begins_with_i.capitalization = pascal_case - -# CA1305: Specify IFormatProvider -dotnet_diagnostic.CA1305.severity = none - -# CA1031: Do not catch general exception types -dotnet_diagnostic.CA1031.severity = silent - -# CA1707: Identifiers should not contain underscores -dotnet_diagnostic.CA1707.severity = silent \ No newline at end of file diff --git a/Source/GitReleaseManager.Cli/Directory.Build.props b/Source/GitReleaseManager.Cli/Directory.Build.props deleted file mode 100644 index 94650e73..00000000 --- a/Source/GitReleaseManager.Cli/Directory.Build.props +++ /dev/null @@ -1,12 +0,0 @@ - - - $(MSBuildThisFileDirectory)obj\$(MSBuildProjectName)\ - - - - - - - - - \ No newline at end of file diff --git a/Source/GitReleaseManager.Cli/GitReleaseManager.Cli.csproj b/Source/GitReleaseManager.Cli/GitReleaseManager.Cli.csproj deleted file mode 100644 index 25a08ca4..00000000 --- a/Source/GitReleaseManager.Cli/GitReleaseManager.Cli.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - 8.0 - Exe - GitReleaseManager - netcoreapp2.0;net461 - GitReleaseManager.Cli - Create release notes in markdown given a milestone - false - false - - - - - - - - - - - - - \ No newline at end of file diff --git a/Source/GitReleaseManager.Cli/Options/BaseVcsSubOptions.cs b/Source/GitReleaseManager.Cli/Options/BaseVcsSubOptions.cs deleted file mode 100644 index ae650475..00000000 --- a/Source/GitReleaseManager.Cli/Options/BaseVcsSubOptions.cs +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -//----------------------------------------------------------------------- - -namespace GitReleaseManager.Cli.Options -{ - using System; - using CommandLine; - using Destructurama.Attributed; - - public abstract class BaseVcsOptions : BaseSubOptions - { - internal const string OBSOLETE_MESSAGE = "Authentication using username and password has been deprecated, and will be removed in a future release. Please use --token instead!"; - - [Obsolete(OBSOLETE_MESSAGE)] - [Option('u', "username", HelpText = "(DEPRECATED) The username to access Version Control System with.", Required = true, SetName = "Basic Auth")] - public string UserName { get; set; } - - [Obsolete(OBSOLETE_MESSAGE)] - [LogMasked(Text = "[REDACTED]")] - [Option('p', "password", HelpText = "(DEPRECATED) The password to access Version Control System with.", Required = true, SetName = "Basic Auth")] - public string Password { get; set; } - - [LogMasked(Text = "[REDACTED]")] - [Option("token", HelpText = "The Access Token to access Version Control System with.", Required = true, SetName = "OAuth flow")] - public string Token { get; set; } - - [Option('o', "owner", HelpText = "The owner of the repository.", Required = true)] - public string RepositoryOwner { get; set; } - - [Option('r', "repository", HelpText = "The name of the repository.", Required = true)] - public string RepositoryName { get; set; } - } -} diff --git a/Source/GitReleaseManager.Cli/Options/CloseSubOptions.cs b/Source/GitReleaseManager.Cli/Options/CloseSubOptions.cs deleted file mode 100644 index 13ef35e1..00000000 --- a/Source/GitReleaseManager.Cli/Options/CloseSubOptions.cs +++ /dev/null @@ -1,17 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -//----------------------------------------------------------------------- - -namespace GitReleaseManager.Cli.Options -{ - using CommandLine; - - [Verb("close", HelpText = "Closes the milestone.")] - public class CloseSubOptions : BaseVcsOptions - { - [Option('m', "milestone", HelpText = "The milestone to use.", Required = true)] - public string Milestone { get; set; } - } -} \ No newline at end of file diff --git a/Source/GitReleaseManager.Cli/Options/DiscardSubOptions.cs b/Source/GitReleaseManager.Cli/Options/DiscardSubOptions.cs deleted file mode 100644 index a2163766..00000000 --- a/Source/GitReleaseManager.Cli/Options/DiscardSubOptions.cs +++ /dev/null @@ -1,17 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -//----------------------------------------------------------------------- - -namespace GitReleaseManager.Cli.Options -{ - using CommandLine; - - [Verb("discard", HelpText = "Discards a draft release.")] - public class DiscardSubOptions : BaseVcsOptions - { - [Option('m', "milestone", HelpText = "The milestone to use.", Required = true)] - public string Milestone { get; set; } - } -} diff --git a/Source/GitReleaseManager.Cli/Options/InitSubOptions.cs b/Source/GitReleaseManager.Cli/Options/InitSubOptions.cs deleted file mode 100644 index 8c282d6d..00000000 --- a/Source/GitReleaseManager.Cli/Options/InitSubOptions.cs +++ /dev/null @@ -1,15 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -//----------------------------------------------------------------------- - -namespace GitReleaseManager.Cli.Options -{ - using CommandLine; - - [Verb("init", HelpText = "Creates a sample Yaml Configuration file in root directory")] - public class InitSubOptions : BaseSubOptions - { - } -} \ No newline at end of file diff --git a/Source/GitReleaseManager.Cli/Options/LabelSubOptions.cs b/Source/GitReleaseManager.Cli/Options/LabelSubOptions.cs deleted file mode 100644 index dc67ce84..00000000 --- a/Source/GitReleaseManager.Cli/Options/LabelSubOptions.cs +++ /dev/null @@ -1,15 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -//----------------------------------------------------------------------- - -namespace GitReleaseManager.Cli.Options -{ - using CommandLine; - - [Verb("label", HelpText = "Deletes existing labels and replaces with set of default labels.")] - public class LabelSubOptions : BaseVcsOptions - { - } -} \ No newline at end of file diff --git a/Source/GitReleaseManager.Cli/Options/OpenSubOptions.cs b/Source/GitReleaseManager.Cli/Options/OpenSubOptions.cs deleted file mode 100644 index 405f6966..00000000 --- a/Source/GitReleaseManager.Cli/Options/OpenSubOptions.cs +++ /dev/null @@ -1,17 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -//----------------------------------------------------------------------- - -namespace GitReleaseManager.Cli.Options -{ - using CommandLine; - - [Verb("open", HelpText = "Opens the milestone.")] - public class OpenSubOptions : BaseVcsOptions - { - [Option('m', "milestone", HelpText = "The milestone to use.", Required = true)] - public string Milestone { get; set; } - } -} \ No newline at end of file diff --git a/Source/GitReleaseManager.Cli/Options/PublishSubOptions.cs b/Source/GitReleaseManager.Cli/Options/PublishSubOptions.cs deleted file mode 100644 index 8286ec2d..00000000 --- a/Source/GitReleaseManager.Cli/Options/PublishSubOptions.cs +++ /dev/null @@ -1,17 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -//----------------------------------------------------------------------- - -namespace GitReleaseManager.Cli.Options -{ - using CommandLine; - - [Verb("publish", HelpText = "Publishes the Release.")] - public class PublishSubOptions : BaseVcsOptions - { - [Option('t', "tagName", HelpText = "The name of the release (Typically this is the generated SemVer Version Number).", Required = true)] - public string TagName { get; set; } - } -} \ No newline at end of file diff --git a/Source/GitReleaseManager.Cli/Options/ShowConfigSubOptions.cs b/Source/GitReleaseManager.Cli/Options/ShowConfigSubOptions.cs deleted file mode 100644 index ddcd7e8c..00000000 --- a/Source/GitReleaseManager.Cli/Options/ShowConfigSubOptions.cs +++ /dev/null @@ -1,15 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -//----------------------------------------------------------------------- - -namespace GitReleaseManager.Cli.Options -{ - using CommandLine; - - [Verb("showconfig", HelpText = "Shows the current configuration")] - public class ShowConfigSubOptions : BaseSubOptions - { - } -} \ No newline at end of file diff --git a/Source/GitReleaseManager.Cli/Program.cs b/Source/GitReleaseManager.Cli/Program.cs deleted file mode 100644 index fb6de33f..00000000 --- a/Source/GitReleaseManager.Cli/Program.cs +++ /dev/null @@ -1,276 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -//----------------------------------------------------------------------- - -namespace GitReleaseManager.Cli -{ - using System; - using System.IO; - using System.Net; - using System.Reflection; - using System.Threading.Tasks; - using AutoMapper; - using CommandLine; - using GitReleaseManager.Cli.Logging; - using GitReleaseManager.Cli.Options; - using GitReleaseManager.Core; - using GitReleaseManager.Core.Configuration; - using GitReleaseManager.Core.Helpers; - using Serilog; - - public static class Program - { - private static FileSystem _fileSystem; - private static IMapper _mapper; - private static IVcsProvider _vcsProvider; - - private static async Task Main(string[] args) - { - // Just add the TLS 1.2 protocol to the Service Point manager until - // we've upgraded to latest Octokit. - ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12; - - _fileSystem = new FileSystem(); - - _mapper = AutoMapperConfiguration.Configure(); - - try - { - return await Parser.Default.ParseArguments(args) - .WithParsed(LogConfiguration.ConfigureLogging) - .WithParsed(CreateFiglet) - .WithParsed(LogOptions) - .WithParsed(ReportUsernamePasswordDeprecation) - .MapResult( - (CreateSubOptions opts) => CreateReleaseAsync(opts), - (DiscardSubOptions opts) => DiscardReleaseAsync(opts), - (AddAssetSubOptions opts) => AddAssetsAsync(opts), - (CloseSubOptions opts) => CloseMilestoneAsync(opts), - (OpenSubOptions opts) => OpenMilestoneAsync(opts), - (PublishSubOptions opts) => PublishReleaseAsync(opts), - (ExportSubOptions opts) => ExportReleasesAsync(opts), - (InitSubOptions opts) => CreateSampleConfigFileAsync(opts), - (ShowConfigSubOptions opts) => ShowConfigAsync(opts), - (LabelSubOptions opts) => CreateLabelsAsync(opts), - errs => Task.FromResult(1)).ConfigureAwait(false); - } - catch (AggregateException ex) - { - Log.Fatal("{Message}", ex.Message); - foreach (var innerException in ex.InnerExceptions) - { - Log.Fatal(innerException, "{Message}", innerException.Message); - } - - return 1; - } - catch (Exception ex) - { - Log.Fatal(ex, "{Message}", ex.Message); - return 1; - } - finally - { - Log.CloseAndFlush(); - } - } - - private static void ReportUsernamePasswordDeprecation(BaseVcsOptions options) - { - if (!string.IsNullOrEmpty(options.UserName) || !string.IsNullOrEmpty(options.Password)) - { - Log.Warning(BaseVcsOptions.OBSOLETE_MESSAGE); - } - } - - private static void CreateFiglet(BaseSubOptions options) - { - if (options.NoLogo) - { - return; - } - - var version = Assembly.GetEntryAssembly().GetCustomAttribute().InformationalVersion; - if (version.IndexOf('+') >= 0) - { - version = version.Substring(0, version.IndexOf('+')); - } - // The following ugly formats is to prevent incorrect indentation - // detected by editorconfig formatters. - const string shortFormat = "\n ____ ____ __ __\n" - + " / ___| _ \\| \\/ |\n" - + " | | _| |_) | |\\/| |\n" - + " | |_| | _ <| | | |\n" - + " \\____|_| \\_\\_| |_|\n" - + "{0,21}\n"; - const string longFormat = "\n ____ _ _ ____ _ __ __\n" - + " / ___(_) |_| _ \\ ___| | ___ __ _ ___ ___| \\/ | __ _ _ __ __ _ __ _ ___ _ __\n" - + " | | _| | __| |_) / _ \\ |/ _ \\/ _` / __|/ _ \\ |\\/| |/ _` | '_ \\ / _` |/ _` |/ _ \\ '__|\n" - + " | |_| | | |_| _ < __/ | __/ (_| \\__ \\ __/ | | | (_| | | | | (_| | (_| | __/ |\n" - + " \\____|_|\\__|_| \\_\\___|_|\\___|\\__,_|___/\\___|_| |_|\\__,_|_| |_|\\__,_|\\__, |\\___|_|\n" - + " |___/\n" - + "{0,87}\n"; - - if (GetConsoleWidth() > 87) - { - Log.Information(longFormat, version); - } - else - { - Log.Information(shortFormat, version); - } - } - - private static int GetConsoleWidth() - { - try - { - return Console.WindowWidth; - } - catch - { - Log.Verbose("Unable to get the width of the console."); - } - - try - { - return Console.BufferWidth; - } - catch - { - Log.Verbose("Unable to get the width of the buffer"); - return int.MaxValue; - } - } - - private static async Task CreateReleaseAsync(CreateSubOptions subOptions) - { - Log.Information("Creating release..."); - _vcsProvider = GetVcsProvider(subOptions); - - Core.Model.Release release; - if (!string.IsNullOrEmpty(subOptions.Milestone)) - { - Log.Verbose("Milestone {Milestone} was specified", subOptions.Milestone); - var releaseName = subOptions.Name; - if (string.IsNullOrWhiteSpace(releaseName)) - { - Log.Verbose("No Release Name was specified, using {Milestone}.", subOptions.Milestone); - releaseName = subOptions.Milestone; - } - - release = await _vcsProvider.CreateReleaseFromMilestone(subOptions.RepositoryOwner, subOptions.RepositoryName, subOptions.Milestone, releaseName, subOptions.TargetCommitish, subOptions.AssetPaths, subOptions.Prerelease).ConfigureAwait(false); - } - else - { - Log.Verbose("No milestone was specified, switching to release creating from input file"); - release = await _vcsProvider.CreateReleaseFromInputFile(subOptions.RepositoryOwner, subOptions.RepositoryName, subOptions.Name, subOptions.InputFilePath, subOptions.TargetCommitish, subOptions.AssetPaths, subOptions.Prerelease).ConfigureAwait(false); - } - - Log.Information("Drafted release is available at:\n{HtmlUrl}", release.HtmlUrl); - Log.Verbose("Body:\n{Body}", release.Body); - return 0; - } - - private static async Task DiscardReleaseAsync(DiscardSubOptions subOptions) - { - Log.Information("Discarding release {Milestone}", subOptions.Milestone); - _vcsProvider = GetVcsProvider(subOptions); - - await _vcsProvider.DiscardRelease(subOptions.RepositoryOwner, subOptions.RepositoryName, subOptions.Milestone); - - return 0; - } - - private static async Task AddAssetsAsync(AddAssetSubOptions subOptions) - { - Log.Information("Uploading assets"); - _vcsProvider = GetVcsProvider(subOptions); - - await _vcsProvider.AddAssets(subOptions.RepositoryOwner, subOptions.RepositoryName, subOptions.TagName, subOptions.AssetPaths).ConfigureAwait(false); - - return 0; - } - - private static async Task CloseMilestoneAsync(CloseSubOptions subOptions) - { - Log.Information("Closing milestone {Milestone}", subOptions.Milestone); - _vcsProvider = GetVcsProvider(subOptions); - - await _vcsProvider.CloseMilestone(subOptions.RepositoryOwner, subOptions.RepositoryName, subOptions.Milestone).ConfigureAwait(false); - - return 0; - } - - private static async Task OpenMilestoneAsync(OpenSubOptions subOptions) - { - Log.Information("Opening milestone {Milestone}", subOptions.Milestone); - _vcsProvider = GetVcsProvider(subOptions); - - await _vcsProvider.OpenMilestone(subOptions.RepositoryOwner, subOptions.RepositoryName, subOptions.Milestone).ConfigureAwait(false); - - return 0; - } - - private static async Task PublishReleaseAsync(PublishSubOptions subOptions) - { - _vcsProvider = GetVcsProvider(subOptions); - - await _vcsProvider.PublishRelease(subOptions.RepositoryOwner, subOptions.RepositoryName, subOptions.TagName).ConfigureAwait(false); - return 0; - } - - private static async Task ExportReleasesAsync(ExportSubOptions subOptions) - { - Log.Information("Exporting release {TagName}", subOptions.TagName); - _vcsProvider = GetVcsProvider(subOptions); - - var releasesMarkdown = await _vcsProvider.ExportReleases(subOptions.RepositoryOwner, subOptions.RepositoryName, subOptions.TagName).ConfigureAwait(false); - - using (var sw = new StreamWriter(File.Open(subOptions.FileOutputPath, FileMode.OpenOrCreate))) - { - sw.Write(releasesMarkdown); - } - - return 0; - } - - private static Task CreateSampleConfigFileAsync(InitSubOptions subOptions) - { - Log.Information("Creating sample configuration file"); - var directory = subOptions.TargetDirectory ?? Environment.CurrentDirectory; - ConfigurationProvider.WriteSample(directory, _fileSystem); - return Task.FromResult(0); - } - - private static Task ShowConfigAsync(ShowConfigSubOptions subOptions) - { - var configuration = ConfigurationProvider.GetEffectiveConfigAsString(subOptions.TargetDirectory ?? Environment.CurrentDirectory, _fileSystem); - - Log.Information("{Configuration}", configuration); - return Task.FromResult(0); - } - - private static async Task CreateLabelsAsync(LabelSubOptions subOptions) - { - Log.Information("Creating standard labels"); - _vcsProvider = GetVcsProvider(subOptions); - - await _vcsProvider.CreateLabels(subOptions.RepositoryOwner, subOptions.RepositoryName).ConfigureAwait(false); - return 0; - } - - private static IVcsProvider GetVcsProvider(BaseVcsOptions subOptions) - { - var configuration = ConfigurationProvider.Provide(subOptions.TargetDirectory ?? Environment.CurrentDirectory, _fileSystem); - - Log.Information("Using {Provider} as VCS Provider", "GitHub"); - return new GitHubProvider(_mapper, configuration, subOptions.UserName, subOptions.Password, subOptions.Token); - } - - private static void LogOptions(BaseSubOptions options) - => Log.Debug("{@Options}", options); - } -} \ No newline at end of file diff --git a/Source/GitReleaseManager.IntegrationTests/ClipBoardHelper.cs b/Source/GitReleaseManager.IntegrationTests/ClipBoardHelper.cs deleted file mode 100644 index eec9afd4..00000000 --- a/Source/GitReleaseManager.IntegrationTests/ClipBoardHelper.cs +++ /dev/null @@ -1,22 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -//----------------------------------------------------------------------- - -namespace GitReleaseManager.IntegrationTests -{ - using System.Threading; - using TextCopy; - - public static class ClipBoardHelper - { - public static void SetClipboard(string result) - { - var thread = new Thread(() => Clipboard.SetText(result)); - thread.SetApartmentState(ApartmentState.STA); - thread.Start(); - thread.Join(); - } - } -} \ No newline at end of file diff --git a/Source/GitReleaseManager.IntegrationTests/GitReleaseManager.IntegrationTests.csproj b/Source/GitReleaseManager.IntegrationTests/GitReleaseManager.IntegrationTests.csproj deleted file mode 100644 index 8b066ec1..00000000 --- a/Source/GitReleaseManager.IntegrationTests/GitReleaseManager.IntegrationTests.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - 8.0 - net472;netcoreapp2.2 - GitReleaseManager.IntegrationTests - Integration Test Project for GitReleaseManager - false - $(NoWarn);CA1707 - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Source/GitReleaseManager.Tests/ApprovalTestConfig.cs b/Source/GitReleaseManager.Tests/ApprovalTestConfig.cs deleted file mode 100644 index 44eaf9a9..00000000 --- a/Source/GitReleaseManager.Tests/ApprovalTestConfig.cs +++ /dev/null @@ -1,9 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -//----------------------------------------------------------------------- - -using ApprovalTests.Reporters; - -[assembly: UseReporter(typeof(AllFailingTestsClipboardReporter), typeof(DiffReporter))] \ No newline at end of file diff --git a/Source/GitReleaseManager.Tests/FakeGitHubClient.cs b/Source/GitReleaseManager.Tests/FakeGitHubClient.cs deleted file mode 100644 index bc30f93d..00000000 --- a/Source/GitReleaseManager.Tests/FakeGitHubClient.cs +++ /dev/null @@ -1,121 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -//----------------------------------------------------------------------- - -namespace GitReleaseManager.Tests -{ - using System.Collections.Generic; - using System.Collections.ObjectModel; - using System.Globalization; - using System.Threading.Tasks; - using GitReleaseManager.Core.Model; - using IVcsProvider = GitReleaseManager.Core.IVcsProvider; - - public class FakeGitHubClient : IVcsProvider - { - public FakeGitHubClient() - { - Milestones = new List(); - Issues = new List(); - Releases = new List(); - Release = new Release(); - } - - public List Milestones { get; private set; } - - public List Issues { get; private set; } - - public List Releases { get; private set; } - - public Release Release { get; private set; } - - public int NumberOfCommits { get; set; } - - public Task GetNumberOfCommitsBetween(Milestone previousMilestone, Milestone currentMilestone, string user, string repository) - { - return Task.FromResult(NumberOfCommits); - } - - public Task> GetIssuesAsync(Milestone targetMilestone) - { - return Task.FromResult(Issues); - } - - public Task> GetReleasesAsync(string user, string repository) - { - return Task.FromResult(Releases); - } - - public Task GetSpecificRelease(string tagName, string user, string repository) - { - return Task.FromResult(Release); - } - - public Task> GetReadOnlyMilestonesAsync(string user, string repository) - { - return Task.FromResult(new ReadOnlyCollection(Milestones)); - } - - public string GetCommitsLink(string user, string repository, Milestone milestone, Milestone previousMilestone) - { - if (milestone is null) - { - throw new System.ArgumentNullException(nameof(milestone)); - } - - if (previousMilestone is null) - { - return string.Format(CultureInfo.InvariantCulture, "https://github.com/{0}/{1}/commits/{2}", user, repository, milestone.Title); - } - - return string.Format(CultureInfo.InvariantCulture, "https://github.com/{0}/{1}/compare/{2}...{3}", user, repository, previousMilestone.Title, milestone.Title); - } - - public Task CreateReleaseFromMilestone(string owner, string repository, string milestone, string releaseName, string targetCommitish, IList assets, bool prerelease) - { - throw new System.NotImplementedException(); - } - - public Task CreateReleaseFromInputFile(string owner, string repository, string name, string inputFilePath, string targetCommitish, IList assets, bool prerelease) - { - throw new System.NotImplementedException(); - } - - public Task DiscardRelease(string owner, string repository, string name) - { - throw new System.NotImplementedException(); - } - - public Task AddAssets(string owner, string repository, string tagName, IList assets) - { - throw new System.NotImplementedException(); - } - - public Task ExportReleases(string owner, string repository, string tagName) - { - throw new System.NotImplementedException(); - } - - public Task CloseMilestone(string owner, string repository, string milestoneTitle) - { - throw new System.NotImplementedException(); - } - - public Task OpenMilestone(string owner, string repository, string milestoneTitle) - { - throw new System.NotImplementedException(); - } - - public Task PublishRelease(string owner, string repository, string tagName) - { - throw new System.NotImplementedException(); - } - - public Task CreateLabels(string owner, string repository) - { - throw new System.NotImplementedException(); - } - } -} \ No newline at end of file diff --git a/Source/GitReleaseManager.Tests/GitReleaseManager.Tests.csproj b/Source/GitReleaseManager.Tests/GitReleaseManager.Tests.csproj deleted file mode 100644 index 93c85167..00000000 --- a/Source/GitReleaseManager.Tests/GitReleaseManager.Tests.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - 8.0 - net472;netcoreapp2.2 - GitReleaseManager.Tests - Test Project for GitReleaseManager - false - $(NoWarn);CA1707 - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Source/GitReleaseManager.Tests/ReleaseNotesBuilderTests.NoCommitsNoIssues.approved.txt b/Source/GitReleaseManager.Tests/ReleaseNotesBuilderTests.NoCommitsNoIssues.approved.txt deleted file mode 100644 index b28b04f6..00000000 --- a/Source/GitReleaseManager.Tests/ReleaseNotesBuilderTests.NoCommitsNoIssues.approved.txt +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/Source/GitReleaseManager.Tests/Resources.resx b/Source/GitReleaseManager.Tests/Resources.resx deleted file mode 100644 index 59590530..00000000 --- a/Source/GitReleaseManager.Tests/Resources.resx +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - # Configuration values used when creating new releases -create: - include-footer: false - footer-heading: - footer-content: - footer-includes-milestone: false - milestone-replace-text: - -# Configuration values used when exporting release notes -export: - include-created-date-in-title: false - created-date-string-format: - perform-regex-removal: false - regex-text: - multiline-regex: false - -# The labels that will be used to include issues in release notes. -issue-labels-include: -- Bug -- Feature -- Improvement - -# The labels that will NOT be used when including issues in release notes. -issue-labels-exclude: -- Internal Refactoring - -# Overrides default pluralization and header names for specific labels. -issue-labels-alias: - - name: Bug - header: Foo - plural: Bar - - - name: Improvement - header: Baz - plural: Qux - - \ No newline at end of file diff --git a/Source/GitReleaseManager.ruleset b/Source/GitReleaseManager.ruleset deleted file mode 100644 index f9a98327..00000000 --- a/Source/GitReleaseManager.ruleset +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Source/GitReleaseManager/Configuration/Config.cs b/Source/GitReleaseManager/Configuration/Config.cs deleted file mode 100644 index b9f53fc1..00000000 --- a/Source/GitReleaseManager/Configuration/Config.cs +++ /dev/null @@ -1,101 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -//----------------------------------------------------------------------- - -namespace GitReleaseManager.Core.Configuration -{ - using System.Collections.Generic; - using System.ComponentModel; - using YamlDotNet.Serialization; - - public class Config - { - internal const string IssueCommentFormat = @":tada: This issue has been resolved in version {milestone} :tada: - -The release is available on: - -- [GitHub release](https://github.com/{owner}/{repository}/releases/tag/{milestone}) - -Your **[GitReleaseManager](https://github.com/GitTools/GitReleaseManager)** bot :package::rocket:"; - - public Config() - { - Create = new CreateConfig - { - IncludeFooter = false, - FooterHeading = string.Empty, - FooterContent = string.Empty, - FooterIncludesMilestone = false, - MilestoneReplaceText = string.Empty, - IncludeShaSection = false, - ShaSectionHeading = "SHA256 Hashes of the release artifacts", - ShaSectionLineFormat = "- `{1}\t{0}`", - AllowUpdateToPublishedRelease = false, - }; - - Export = new ExportConfig - { - IncludeCreatedDateInTitle = false, - CreatedDateStringFormat = string.Empty, - PerformRegexRemoval = false, - RegexText = string.Empty, - IsMultilineRegex = false, - }; - - Close = new CloseConfig - { - IssueComments = false, - IssueCommentFormat = IssueCommentFormat, - }; - - IssueLabelsInclude = new List - { - "Bug", - "Duplicate", - "Enhancement", - "Feature", - "Help Wanted", - "Improvement", - "Invalid", - "Question", - "WontFix", - }; - - IssueLabelsExclude = new List - { - "Internal Refactoring", - }; - - LabelAliases = new List(); - } - - [Description("Configuration values used when creating new releases")] - [YamlMember(Alias = "create")] - public CreateConfig Create { get; private set; } - - [Description("Configuration values used when exporting release notes")] - [YamlMember(Alias = "export")] - public ExportConfig Export { get; private set; } - - /// - /// Gets or sets the close configuration values. - /// - [Description("Configuration values used when closing a milestone")] - [YamlMember(Alias = "close")] - public CloseConfig Close { get; set; } - - [Description("The labels that will be used to include issues in release notes.")] - [YamlMember(Alias = "issue-labels-include")] - public IList IssueLabelsInclude { get; private set; } - - [Description("The labels that will NOT be used when including issues in release notes.")] - [YamlMember(Alias = "issue-labels-exclude")] - public IList IssueLabelsExclude { get; private set; } - - [Description("Overrides default pluralization and header names for specific labels.")] - [YamlMember(Alias = "issue-labels-alias")] - public IList LabelAliases { get; private set; } - } -} \ No newline at end of file diff --git a/Source/GitReleaseManager/Configuration/LabelAlias.cs b/Source/GitReleaseManager/Configuration/LabelAlias.cs deleted file mode 100644 index 0656f68e..00000000 --- a/Source/GitReleaseManager/Configuration/LabelAlias.cs +++ /dev/null @@ -1,17 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -//----------------------------------------------------------------------- - -namespace GitReleaseManager.Core.Configuration -{ - public class LabelAlias - { - public string Name { get; set; } - - public string Header { get; set; } - - public string Plural { get; set; } - } -} \ No newline at end of file diff --git a/Source/GitReleaseManager/Exceptions/InvalidStateException.cs b/Source/GitReleaseManager/Exceptions/InvalidStateException.cs deleted file mode 100644 index 901fc24e..00000000 --- a/Source/GitReleaseManager/Exceptions/InvalidStateException.cs +++ /dev/null @@ -1,35 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -// ----------------------------------------------------------------------- - -namespace GitReleaseManager.Core.Exceptions -{ - using System; - - [Serializable] - public class InvalidStateException : Exception - { - public InvalidStateException() - { - } - - public InvalidStateException(string message) - : base(message) - { - } - - public InvalidStateException(string message, Exception inner) - : base(message, inner) - { - } - - protected InvalidStateException( - System.Runtime.Serialization.SerializationInfo info, - System.Runtime.Serialization.StreamingContext context) - : base(info, context) - { - } - } -} \ No newline at end of file diff --git a/Source/GitReleaseManager/Exceptions/MissingReleaseException.cs b/Source/GitReleaseManager/Exceptions/MissingReleaseException.cs deleted file mode 100644 index 61747415..00000000 --- a/Source/GitReleaseManager/Exceptions/MissingReleaseException.cs +++ /dev/null @@ -1,35 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -// ----------------------------------------------------------------------- - -namespace GitReleaseManager.Core.Exceptions -{ - using System; - - [Serializable] - public class MissingReleaseException : Exception - { - public MissingReleaseException() - { - } - - public MissingReleaseException(string message) - : base(message) - { - } - - public MissingReleaseException(string message, Exception inner) - : base(message, inner) - { - } - - protected MissingReleaseException( - System.Runtime.Serialization.SerializationInfo info, - System.Runtime.Serialization.StreamingContext context) - : base(info, context) - { - } - } -} \ No newline at end of file diff --git a/Source/GitReleaseManager/GitHubProvider.cs b/Source/GitReleaseManager/GitHubProvider.cs deleted file mode 100644 index ed93ebeb..00000000 --- a/Source/GitReleaseManager/GitHubProvider.cs +++ /dev/null @@ -1,530 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -//----------------------------------------------------------------------- - -namespace GitReleaseManager.Core -{ - using System; - using System.Collections.Generic; - using System.Collections.ObjectModel; - using System.Globalization; - using System.IO; - using System.Linq; - using System.Security.Cryptography; - using System.Text; - using System.Threading; - using System.Threading.Tasks; - using AutoMapper; - using GitReleaseManager.Core.Configuration; - using GitReleaseManager.Core.Exceptions; - using GitReleaseManager.Core.Extensions; - using Octokit; - using Serilog; - using Issue = GitReleaseManager.Core.Model.Issue; - using Milestone = GitReleaseManager.Core.Model.Milestone; - using Release = GitReleaseManager.Core.Model.Release; - - public class GitHubProvider : IVcsProvider - { - private readonly Config _configuration; - private readonly ILogger _logger = Log.ForContext(); - private readonly IMapper _mapper; - private GitHubClient _gitHubClient; - - [Obsolete("Use overload with token only instead")] - public GitHubProvider(IMapper mapper, Config configuration, string userName, string password, string token) - { - _mapper = mapper; - _configuration = configuration; - CreateClient(userName, password, token); - } - - public GitHubProvider(IMapper mapper, Config configuration, string token) - { - _mapper = mapper; - _configuration = configuration; - CreateClient(token); - } - - public Task GetNumberOfCommitsBetween(Milestone previousMilestone, Milestone currentMilestone, string user, string repository) - { - if (currentMilestone is null) - { - throw new ArgumentNullException(nameof(currentMilestone)); - } - - return GetNumberOfCommitsBetweenInternal(previousMilestone, currentMilestone, user, repository); - } - - public async Task> GetIssuesAsync(Milestone targetMilestone) - { - var githubMilestone = _mapper.Map(targetMilestone); - _logger.Verbose("Finding issues on milestone: {@Milestone}", githubMilestone); - var allIssues = await _gitHubClient.AllIssuesForMilestone(githubMilestone).ConfigureAwait(false); - return _mapper.Map>(allIssues.Where(x => x.State == ItemState.Closed).ToList()); - } - - public async Task> GetReleasesAsync(string user, string repository) - { - _logger.Verbose("Finding all releases on '{User}/{Repository}'", user, repository); - var allReleases = await _gitHubClient.Repository.Release.GetAll(user, repository).ConfigureAwait(false); - return _mapper.Map>(allReleases.OrderByDescending(r => r.CreatedAt).ToList()); - } - - public async Task GetSpecificRelease(string tagName, string user, string repository) - { - return _mapper.Map(await GetReleaseFromTagNameAsync(user, repository, tagName).ConfigureAwait(false)); - } - - public async Task> GetReadOnlyMilestonesAsync(string user, string repository) - { - var milestonesClient = _gitHubClient.Issue.Milestone; - - _logger.Verbose("Finding all closed milestones on '{User}/{Repository}'", user, repository); - var closed = await milestonesClient.GetAllForRepository( - user, - repository, - new MilestoneRequest - { - State = ItemStateFilter.Closed, - }).ConfigureAwait(false); - - _logger.Verbose("Finding all open milestones on '{User}/{Repository}'", user, repository); - var open = await milestonesClient.GetAllForRepository( - user, - repository, - new MilestoneRequest - { - State = ItemStateFilter.Open, - }).ConfigureAwait(false); - - return new ReadOnlyCollection(_mapper.Map>(closed.Concat(open).ToList())); - } - - [Obsolete("Use overload with token only instead")] - public void CreateClient(string userName, string password, string token) - { - var credentials = string.IsNullOrWhiteSpace(token) - ? new Credentials(userName, password) - : new Credentials(token); - - var github = new GitHubClient(new ProductHeaderValue("GitReleaseManager")) { Credentials = credentials }; - _gitHubClient = github; - } - - public void CreateClient(string token) - { - var credentials = new Credentials(token); - var github = new GitHubClient(new ProductHeaderValue("GitReleaseManager")) { Credentials = credentials }; - _gitHubClient = github; - } - - public string GetCommitsLink(string user, string repository, Milestone milestone, Milestone previousMilestone) - { - if (milestone is null) - { - throw new ArgumentNullException(nameof(milestone)); - } - - if (previousMilestone is null) - { - return string.Format(CultureInfo.InvariantCulture, "https://github.com/{0}/{1}/commits/{2}", user, repository, milestone.Title); - } - - return string.Format(CultureInfo.InvariantCulture, "https://github.com/{0}/{1}/compare/{2}...{3}", user, repository, previousMilestone.Title, milestone.Title); - } - - public async Task CreateReleaseFromMilestone(string owner, string repository, string milestone, string releaseName, string targetCommitish, IList assets, bool prerelease) - { - var release = await GetReleaseFromTagNameAsync(owner, repository, milestone).ConfigureAwait(false); - var releaseNotesBuilder = new ReleaseNotesBuilder(this, owner, repository, milestone, _configuration); - var result = await releaseNotesBuilder.BuildReleaseNotes().ConfigureAwait(false); - - if (release == null) - { - var releaseUpdate = CreateNewRelease(releaseName, milestone, result, prerelease, targetCommitish); - _logger.Verbose("Creating new release on '{Owner}/{Repository}'", owner, repository); - _logger.Debug("{@ReleaseUpdate}", releaseUpdate); - release = await _gitHubClient.Repository.Release.Create(owner, repository, releaseUpdate).ConfigureAwait(false); - } - else - { - _logger.Warning("A release for milestone {Milestone} already exists, and will be updated", milestone); - - if (!release.Draft && !_configuration.Create.AllowUpdateToPublishedRelease) - { - throw new InvalidOperationException("Release is not in draft state, so not updating."); - } - - var releaseUpdate = release.ToUpdate(); - releaseUpdate.Body = result; - _logger.Verbose("Updating release {Milestone} on '{Owner}/{Repository}'", milestone, owner, repository); - _logger.Debug("{@ReleaseUpdate}", releaseUpdate); - await _gitHubClient.Repository.Release.Edit(owner, repository, release.Id, releaseUpdate).ConfigureAwait(false); - } - - await AddAssets(owner, repository, milestone, assets).ConfigureAwait(false); - return _mapper.Map(release); - } - - public Task CreateReleaseFromInputFile(string owner, string repository, string name, string inputFilePath, string targetCommitish, IList assets, bool prerelease) - { - if (!File.Exists(inputFilePath)) - { - throw new ArgumentException("Unable to locate input file."); - } - - return CreateReleaseFromInputFileInternal(owner, repository, name, inputFilePath, targetCommitish, assets, prerelease); - } - - public async Task DiscardRelease(string owner, string repository, string name) - { - var release = await GetReleaseFromTagNameAsync(owner, repository, name).ConfigureAwait(false); - - if (release is null) - { - throw new MissingReleaseException(string.Format("Unable to find a release with name {0}", name)); - } - - if (!release.Draft) - { - throw new InvalidStateException("Release is not in draft state, so not discarding."); - } - - await _gitHubClient.Repository.Release.Delete(owner, repository, release.Id).ConfigureAwait(false); - } - - public async Task AddAssets(string owner, string repository, string tagName, IList assets) - { - var release = await GetReleaseFromTagNameAsync(owner, repository, tagName).ConfigureAwait(false); - - if (release is null) - { - _logger.Error("Unable to find Release with specified tagName"); - return; - } - - if (!(assets is null)) - { - foreach (var asset in assets) - { - if (!File.Exists(asset)) - { - var logMessage = string.Format("Requested asset to be uploaded doesn't exist: {0}", asset); - throw new FileNotFoundException(logMessage); - } - - var assetFileName = Path.GetFileName(asset); - - var existingAsset = release.Assets.FirstOrDefault(a => a.Name == assetFileName); - if (existingAsset != null) - { - _logger.Warning("Requested asset to be uploaded already exists on draft release, replacing with new file: {AssetPath}", asset); - await _gitHubClient.Repository.Release.DeleteAsset(owner, repository, existingAsset.Id).ConfigureAwait(false); - } - - var upload = new ReleaseAssetUpload - { - FileName = assetFileName, - ContentType = "application/octet-stream", - RawData = File.Open(asset, System.IO.FileMode.Open, FileAccess.Read, FileShare.ReadWrite), - }; - - _logger.Verbose("Uploading asset '{FileName}' to release '{TagName}' on '{Owner}/{Repository}'", assetFileName, tagName, owner, repository); - _logger.Debug("{@Upload}", upload); - - await _gitHubClient.Repository.Release.UploadAsset(release, upload).ConfigureAwait(false); - - // Make sure to tidy up the stream that was created above - upload.RawData.Dispose(); - } - - if (assets.Any() && _configuration.Create.IncludeShaSection) - { - var stringBuilder = new StringBuilder(release.Body); - - if (!release.Body.Contains(_configuration.Create.ShaSectionHeading)) - { - _logger.Debug("Creating SHA section header"); - stringBuilder.AppendLine(string.Format("### {0}", _configuration.Create.ShaSectionHeading)); - } - - foreach (var asset in assets) - { - var file = new FileInfo(asset); - - if (!file.Exists) - { - continue; - } - - _logger.Debug("Creating SHA checksum for {Name}.", file.Name); - - stringBuilder.AppendFormat(_configuration.Create.ShaSectionLineFormat, file.Name, ComputeSha256Hash(asset)); - stringBuilder.AppendLine(); - } - - stringBuilder.AppendLine(); - - var releaseUpdate = release.ToUpdate(); - releaseUpdate.Body = stringBuilder.ToString(); - _logger.Verbose("Updating release notes with sha checksum"); - _logger.Debug("{@ReleaseUpdate}", releaseUpdate); - await _gitHubClient.Repository.Release.Edit(owner, repository, release.Id, releaseUpdate).ConfigureAwait(false); - } - } - } - - public Task ExportReleases(string owner, string repository, string tagName) - { - var releaseNotesExporter = new ReleaseNotesExporter(this, _configuration, owner, repository); - - return releaseNotesExporter.ExportReleaseNotes(tagName); - } - - public async Task CloseMilestone(string owner, string repository, string milestoneTitle) - { - _logger.Verbose("Finding open milestone with title '{Title}' on '{Owner}/{Repository}'", milestoneTitle, owner, repository); - var milestoneClient = _gitHubClient.Issue.Milestone; - var openMilestones = await milestoneClient.GetAllForRepository(owner, repository, new MilestoneRequest { State = ItemStateFilter.Open }).ConfigureAwait(false); - var milestone = openMilestones.FirstOrDefault(m => m.Title == milestoneTitle); - - if (milestone is null) - { - _logger.Debug("No existing open milestone with title '{Title}' was found", milestoneTitle); - return; - } - - _logger.Verbose("Closing milestone '{Title}' on '{Owner}/{Repository}'", milestoneTitle, owner, repository); - - await milestoneClient.Update(owner, repository, milestone.Number, new MilestoneUpdate { State = ItemState.Closed }).ConfigureAwait(false); - - if (_configuration.Close.IssueComments) - { - await AddIssueCommentsAsync(owner, repository, milestone).ConfigureAwait(false); - } - } - - public async Task OpenMilestone(string owner, string repository, string milestoneTitle) - { - _logger.Verbose("Finding closed milestone with title '{Title}' on '{Owner}/{Repository}'", milestoneTitle, owner, repository); - var milestoneClient = _gitHubClient.Issue.Milestone; - var closedMilestones = await milestoneClient.GetAllForRepository(owner, repository, new MilestoneRequest { State = ItemStateFilter.Closed }).ConfigureAwait(false); - var milestone = closedMilestones.FirstOrDefault(m => m.Title == milestoneTitle); - - if (milestone is null) - { - _logger.Debug("No existing closed milestone with title '{Title}' was found", milestoneTitle); - return; - } - - _logger.Verbose("Opening milestone '{Title}' on '{Owner}/{Repository}'", milestoneTitle, owner, repository); - await milestoneClient.Update(owner, repository, milestone.Number, new MilestoneUpdate { State = ItemState.Open }).ConfigureAwait(false); - } - - public async Task PublishRelease(string owner, string repository, string tagName) - { - var release = await GetReleaseFromTagNameAsync(owner, repository, tagName).ConfigureAwait(false); - - if (release is null) - { - _logger.Verbose("No release with tag '{TagName}' was found on '{Owner}/{Repository}'", tagName, owner, repository); - return; - } - - var releaseUpdate = new ReleaseUpdate { TagName = tagName, Draft = false }; - - _logger.Verbose("Publishing release '{TagName}' on '{Owner}/{Repository}'", tagName, owner, repository); - _logger.Debug("{@ReleaseUpdate}", releaseUpdate); - await _gitHubClient.Repository.Release.Edit(owner, repository, release.Id, releaseUpdate).ConfigureAwait(false); - } - - public async Task CreateLabels(string owner, string repository) - { - var newLabels = new List - { - new NewLabel("Breaking change", "b60205"), - new NewLabel("Bug", "ee0701"), - new NewLabel("Build", "009800"), - new NewLabel("Documentation", "d4c5f9"), - new NewLabel("Feature", "84b6eb"), - new NewLabel("Improvement", "207de5"), - new NewLabel("Question", "cc317c"), - new NewLabel("good first issue", "7057ff"), - new NewLabel("help wanted", "33aa3f"), - }; - - _logger.Verbose("Grabbing all existing labels on '{Owner}/{Repository}'", owner, repository); - var labels = await _gitHubClient.Issue.Labels.GetAllForRepository(owner, repository).ConfigureAwait(false); - - _logger.Verbose("Removing existing labels"); - _logger.Debug("{@Labels}", labels); - var deleteLabelsTasks = labels.Select(label => _gitHubClient.Issue.Labels.Delete(owner, repository, label.Name)); - await Task.WhenAll(deleteLabelsTasks).ConfigureAwait(false); - - _logger.Verbose("Creating new standard labels"); - _logger.Debug("{@Labels}", newLabels); - var createLabelsTasks = newLabels.Select(label => _gitHubClient.Issue.Labels.Create(owner, repository, label)); - await Task.WhenAll(createLabelsTasks).ConfigureAwait(false); - } - - private static NewRelease CreateNewRelease(string name, string tagName, string body, bool prerelease, string targetCommitish) - { - var newRelease = new NewRelease(tagName) - { - Draft = true, - Body = body, - Name = name, - Prerelease = prerelease, - }; - - if (!string.IsNullOrEmpty(targetCommitish)) - { - newRelease.TargetCommitish = targetCommitish; - } - - return newRelease; - } - - private static string ComputeSha256Hash(string asset) - { - // Create a SHA256 - using (var sha256Hash = SHA256.Create()) - { - using (var fileStream = File.Open(asset, System.IO.FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) - { - // ComputeHash - returns byte array - var bytes = sha256Hash.ComputeHash(fileStream); - - // Convert byte array to a string - var builder = new StringBuilder(); - - foreach (var t in bytes) - { - builder.Append(t.ToString("x2")); - } - - return builder.ToString(); - } - } - } - - private async Task AddIssueCommentsAsync(string owner, string repository, Octokit.Milestone milestone) - { - const string detectionComment = ""; - var issueComment = detectionComment + "\n" + _configuration.Close.IssueCommentFormat.ReplaceTemplate(new { owner, repository, Milestone = milestone.Title }); - var issues = await GetIssuesFromMilestoneAsync(owner, repository, milestone.Number).ConfigureAwait(false); - - foreach (var issue in issues) - { - if (issue.State != ItemState.Closed) - { - continue; - } - - SleepWhenRateIsLimited(); - - try - { - if (!await CommentsIncludeString(owner, repository, issue.Number, detectionComment).ConfigureAwait(false)) - { - _logger.Information("Adding release comment for issue #{IssueNumber}", issue.Number); - await _gitHubClient.Issue.Comment.Create(owner, repository, issue.Number, issueComment).ConfigureAwait(false); - } - else - { - _logger.Information("Issue #{IssueNumber} already contains release comment, skipping...", issue.Number); - } - } - catch (ForbiddenException) - { - _logger.Error("Unable to add comment to issue #{IssueNumber}. Insufficient permissions.", issue.Number); - break; - } - } - } - - private async Task CommentsIncludeString(string owner, string repository, int issueNumber, string comment) - { - _logger.Verbose("Finding issue comment created by GitReleaseManager for issue #{IssueNumber}", issueNumber); - var issueComments = await _gitHubClient.Issue.Comment.GetAllForIssue(owner, repository, issueNumber).ConfigureAwait(false); - - return issueComments.Any(c => c.Body.Contains(comment)); - } - - private async Task CreateReleaseFromInputFileInternal(string owner, string repository, string name, string inputFilePath, string targetCommitish, IList assets, bool prerelease) - { - _logger.Verbose("Reading release notes from: '{FilePath}'", inputFilePath); - - var inputFileContents = File.ReadAllText(inputFilePath); - - var releaseUpdate = CreateNewRelease(name, name, inputFileContents, prerelease, targetCommitish); - - _logger.Verbose("Creating new release on '{Owner}/{Repository}'", owner, repository); - _logger.Debug("{@ReleaseUpdate}", releaseUpdate); - - var release = await _gitHubClient.Repository.Release.Create(owner, repository, releaseUpdate).ConfigureAwait(false); - - await AddAssets(owner, repository, name, assets).ConfigureAwait(false); - - return _mapper.Map(release); - } - - private Task> GetIssuesFromMilestoneAsync(string owner, string repository, int milestoneNumber, ItemStateFilter state = ItemStateFilter.Closed) - { - _logger.Verbose("Finding issues with milestone: '{Milestone}", milestoneNumber); - return _gitHubClient.Issue.GetAllForRepository(owner, repository, new RepositoryIssueRequest - { - Milestone = milestoneNumber.ToString(), - State = state, - }); - } - - private async Task GetNumberOfCommitsBetweenInternal(Milestone previousMilestone, Milestone currentMilestone, string user, string repository) - { - try - { - if (previousMilestone == null) - { - _logger.Verbose("Getting commit count between base '{Base}' and head '{Head}'", "master", currentMilestone.Title); - var gitHubClientRepositoryCommitsCompare = await _gitHubClient.Repository.Commit.Compare(user, repository, "master", currentMilestone.Title).ConfigureAwait(false); - return gitHubClientRepositoryCommitsCompare.AheadBy; - } - - _logger.Verbose("Getting commit count between base '{Base}' and head '{Head}'", previousMilestone.Title, "master"); - var compareResult = await _gitHubClient.Repository.Commit.Compare(user, repository, previousMilestone.Title, "master").ConfigureAwait(false); - return compareResult.AheadBy; - } - catch (NotFoundException) - { - _logger.Warning("Unable to find tag for milestone, so commit count will be returned as zero"); - - // If there is no tag yet the Compare will return a NotFoundException - // we can safely ignore - return 0; - } - } - - private async Task GetReleaseFromTagNameAsync(string owner, string repository, string tagName) - { - _logger.Verbose("Finding release with tag name: '{TagName}'", tagName); - var releases = await _gitHubClient.Repository.Release.GetAll(owner, repository).ConfigureAwait(false); - - var release = releases.FirstOrDefault(r => r.TagName == tagName); - return release; - } - - private void SleepWhenRateIsLimited() - { - var lastApi = _gitHubClient.GetLastApiInfo(); - if (lastApi?.RateLimit.Remaining == 0) - { - var sleepTime = lastApi.RateLimit.Reset - DateTimeOffset.Now; - _logger.Warning("Rate limit exceeded, sleeping for {$SleepTime}", sleepTime); - Thread.Sleep(sleepTime); - } - } - } -} \ No newline at end of file diff --git a/Source/GitReleaseManager/GitReleaseManager.Core.csproj b/Source/GitReleaseManager/GitReleaseManager.Core.csproj deleted file mode 100644 index 91b3dad0..00000000 --- a/Source/GitReleaseManager/GitReleaseManager.Core.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - 8.0 - netstandard2.0;net461 - GitReleaseManager.Core - Create release notes in markdown given a milestone - false - false - - - - - - - - - - - \ No newline at end of file diff --git a/Source/GitReleaseManager/IVcsProvider.cs b/Source/GitReleaseManager/IVcsProvider.cs deleted file mode 100644 index 995c05eb..00000000 --- a/Source/GitReleaseManager/IVcsProvider.cs +++ /dev/null @@ -1,46 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -//----------------------------------------------------------------------- - -namespace GitReleaseManager.Core -{ - using System.Collections.Generic; - using System.Collections.ObjectModel; - using System.Threading.Tasks; - using GitReleaseManager.Core.Model; - - public interface IVcsProvider - { - Task GetNumberOfCommitsBetween(Milestone previousMilestone, Milestone currentMilestone, string user, string repository); - - string GetCommitsLink(string user, string repository, Milestone milestone, Milestone previousMilestone); - - Task> GetIssuesAsync(Milestone targetMilestone); - - Task> GetReleasesAsync(string user, string repository); - - Task GetSpecificRelease(string tagName, string user, string repository); - - Task> GetReadOnlyMilestonesAsync(string user, string repository); - - Task CreateReleaseFromMilestone(string owner, string repository, string milestone, string releaseName, string targetCommitish, IList assets, bool prerelease); - - Task CreateReleaseFromInputFile(string owner, string repository, string name, string inputFilePath, string targetCommitish, IList assets, bool prerelease); - - Task DiscardRelease(string owner, string repository, string name); - - Task AddAssets(string owner, string repository, string tagName, IList assets); - - Task ExportReleases(string owner, string repository, string tagName); - - Task CloseMilestone(string owner, string repository, string milestoneTitle); - - Task OpenMilestone(string owner, string repository, string milestoneTitle); - - Task PublishRelease(string owner, string repository, string tagName); - - Task CreateLabels(string owner, string repository); - } -} \ No newline at end of file diff --git a/Source/GitReleaseManager/MappingProfiles/GitHubProfile.cs b/Source/GitReleaseManager/MappingProfiles/GitHubProfile.cs deleted file mode 100644 index d173b2a2..00000000 --- a/Source/GitReleaseManager/MappingProfiles/GitHubProfile.cs +++ /dev/null @@ -1,23 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -// ----------------------------------------------------------------------- - -namespace GitReleaseManager.Core.MappingProfiles -{ - using AutoMapper; - - public class GitHubProfile : Profile - { - public GitHubProfile() - { - CreateMap().ReverseMap(); - CreateMap().ReverseMap(); - CreateMap().ReverseMap(); - CreateMap(); - CreateMap() - .AfterMap((src, dest) => dest.Version = src.Version()); - } - } -} \ No newline at end of file diff --git a/Source/GitReleaseManager/Model/Issue.cs b/Source/GitReleaseManager/Model/Issue.cs deleted file mode 100644 index a602d9e4..00000000 --- a/Source/GitReleaseManager/Model/Issue.cs +++ /dev/null @@ -1,21 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) 2015 - Present - GitTools Contributors -// -// ----------------------------------------------------------------------- - -namespace GitReleaseManager.Core.Model -{ - using System.Collections.Generic; - - public sealed class Issue - { - public string Title { get; set; } - - public string Number { get; set; } - - public string HtmlUrl { get; set; } - - public IReadOnlyList