diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
new file mode 100644
index 0000000..f844c72
--- /dev/null
+++ b/.config/dotnet-tools.json
@@ -0,0 +1,27 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "dotnet-reportgenerator-globaltool": {
+ "version": "5.4.8",
+ "commands": [
+ "reportgenerator"
+ ],
+ "rollForward": false
+ },
+ "gitreleasemanager.tool": {
+ "version": "0.20.0",
+ "commands": [
+ "dotnet-gitreleasemanager"
+ ],
+ "rollForward": false
+ },
+ "gitversion.tool": {
+ "version": "6.4.0",
+ "commands": [
+ "dotnet-gitversion"
+ ],
+ "rollForward": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/.editorconfig b/.editorconfig
index 4981ab1..5a63bb9 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -29,14 +29,251 @@ guidelines = 80 1px solid 5000ff00, 100 1px solid 75ffff00, 120 1px solid ff8b00
# Exceptions required by file format
#───────────────────────────────────────────────────────────────────────────────
+[*.{bash,sh}]
+end_of_line = lf
+
[*.md]
indent_size = 2
tab_width = 2
+[*.sln]
+indent_style = tab
+
#───────────────────────────────────────────────────────────────────────────────
# Exceptions for structured data files (looks better)
#───────────────────────────────────────────────────────────────────────────────
-[*.{json,yaml,yml}]
+# JSON configuration files
+[*.{json,vsconfig}]
+indent_size = 2
+tab_width = 2
+
+# XML project files
+[*.{csproj,dbproj,fsproj,njsproj,proj,pyproj,rproj,shproj,sqlproj,vbproj,vcproj,vcxitems,vcxproj,wixproj}]
+indent_size = 2
+tab_width = 2
+
+# XML configuration files
+[*.{config,nuspec,projitems,props,resx,ruleset,runsettings,svg,targets,vcxproj.filters,vsct,vsixmanifest,xml}]
indent_size = 2
tab_width = 2
+
+# YAML configuration files
+[*.{yaml,yml}]
+indent_size = 2
+tab_width = 2
+
+#───────────────────────────────────────────────────────────────────────────────
+# .NET Coding Conventions
+#───────────────────────────────────────────────────────────────────────────────
+
+[*.cs]
+
+# Organize usings
+dotnet_separate_import_directive_groups = false
+dotnet_sort_system_directives_first = true
+file_header_template = unset
+
+# 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:silent
+
+# 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 = always_for_clarity: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
+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_operator_placement_when_wrapping = beginning_of_line
+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
+dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
+dotnet_style_prefer_simplified_interpolation = true:suggestion
+# dotnet_style_prefer_collection_expression = 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 = true:silent
+csharp_style_var_for_built_in_types = true:silent
+csharp_style_var_when_type_is_apparent = true: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 = true:silent
+csharp_style_expression_bodied_operators = true: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:silent
+
+# Code-block preferences
+csharp_prefer_braces = when_multiline:silent
+csharp_prefer_simple_using_statement = true:suggestion
+
+# Expression-level preferences
+csharp_prefer_simple_default_expression = true:suggestion
+csharp_style_deconstructed_variable_declaration = true:suggestion
+csharp_style_inlined_variable_declaration = 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_throw_expression = 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
+
+# Namespace preferences
+csharp_style_namespace_declarations = file_scoped
+
+#───────────────────────────────────────────────────────────────────────────────
+# C# Formatting
+#───────────────────────────────────────────────────────────────────────────────
+
+# 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 = flush_left
+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 = false
+
+#───────────────────────────────────────────────────────────────────────────────
+# .NET Naming Conventions
+#───────────────────────────────────────────────────────────────────────────────
+
+# 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
+
+#───────────────────────────────────────────────────────────────────────────────
+# Code Analysis Exceptions
+#───────────────────────────────────────────────────────────────────────────────
+
+# CodeAnalysis rules
+# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/
+dotnet_diagnostic.CA1515.severity = none # Consider making public types internal
+
+# StyleCop rules
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/tree/master/documentation
+dotnet_diagnostic.SA1101.severity = none # Prefix local calls with 'this'
+dotnet_diagnostic.SA1309.severity = none # Field names must not begin with underscore
+dotnet_diagnostic.SA1503.severity = none # Braces must not be omitted
+dotnet_diagnostic.SA1600.severity = warning # Elements should be documented
+dotnet_diagnostic.SA1633.severity = none # File must have header
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..0c637c9
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,219 @@
+#───────────────────────────────────────────────────────────────────────────────
+# Common
+# https://github.com/gitattributes/gitattributes/blob/master/Common.gitattributes
+#───────────────────────────────────────────────────────────────────────────────
+
+# 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
+
+#
+# Exclude files from exporting
+#
+
+.gitattributes export-ignore
+.gitignore export-ignore
+.gitkeep export-ignore
+
+#───────────────────────────────────────────────────────────────────────────────
+# CSharp
+# https://github.com/gitattributes/gitattributes/blob/master/CSharp.gitattributes
+#───────────────────────────────────────────────────────────────────────────────
+
+# Auto detect text files and perform LF normalization
+* text=auto
+
+*.cs text diff=csharp
+*.cshtml text diff=html
+*.csx text diff=csharp
+*.sln text eol=crlf
+*.csproj text eol=crlf
+
+#───────────────────────────────────────────────────────────────────────────────
+# Dev Container
+# https://github.com/gitattributes/gitattributes/blob/master/Global/DevContainer.gitattributes
+#───────────────────────────────────────────────────────────────────────────────
+
+# Fix syntax highlighting on GitHub to allow comments
+.devcontainer.json linguist-language=JSON-with-Comments
+devcontainer.json linguist-language=JSON-with-Comments
+
+#───────────────────────────────────────────────────────────────────────────────
+# Markdown
+# https://github.com/gitattributes/gitattributes/blob/master/Markdown.gitattributes
+#───────────────────────────────────────────────────────────────────────────────
+
+# Apply override to all files in the directory
+*.md linguist-detectable
+
+#───────────────────────────────────────────────────────────────────────────────
+# PowerShell
+# https://github.com/gitattributes/gitattributes/blob/master/PowerShell.gitattributes
+#───────────────────────────────────────────────────────────────────────────────
+
+# Basic .gitattributes for a PowerShell repo.
+
+# Source files
+# ============
+*.ps1 text eol=crlf
+*.ps1x text eol=crlf
+*.psm1 text eol=crlf
+*.psd1 text eol=crlf
+*.ps1xml text eol=crlf
+*.pssc text eol=crlf
+*.psrc text eol=crlf
+*.cdxml text eol=crlf
+
+#───────────────────────────────────────────────────────────────────────────────
+# Visual Studio
+# https://github.com/gitattributes/gitattributes/blob/master/Global/VisualStudio.gitattributes
+#───────────────────────────────────────────────────────────────────────────────
+
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just comment the entries below and
+# uncomment the group further below
+###############################################################################
+
+*.sln text eol=crlf
+*.csproj text eol=crlf
+*.vbproj text eol=crlf
+*.vcxproj text eol=crlf
+*.vcproj text eol=crlf
+*.dbproj text eol=crlf
+*.fsproj text eol=crlf
+*.lsproj text eol=crlf
+*.wixproj text eol=crlf
+*.modelproj text eol=crlf
+*.sqlproj text eol=crlf
+*.wwaproj text eol=crlf
+
+*.xproj text eol=crlf
+*.props text eol=crlf
+*.filters text eol=crlf
+*.vcxitems text eol=crlf
+
+
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+#*.xproj merge=binary
+#*.props merge=binary
+#*.filters merge=binary
+#*.vcxitems merge=binary
+
+#───────────────────────────────────────────────────────────────────────────────
+# Visual Studio Code
+# https://github.com/gitattributes/gitattributes/blob/master/Global/VisualStudioCode.gitattributes
+#───────────────────────────────────────────────────────────────────────────────
+
+# Fix syntax highlighting on GitHub to allow comments
+.vscode/*.json linguist-language=JSON-with-Comments
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
deleted file mode 100644
index 225c6b4..0000000
--- a/.github/FUNDING.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-# This file configures the "Sponsor" button in the repo.
-# Please see the documentation for all configuration options:
-# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/displaying-a-sponsor-button-in-your-repository
-
-buy_me_a_coffee: TaffarelJr
-thanks_dev: u/gh/TaffarelJr
diff --git a/.github/ISSUE_TEMPLATE/01_bug_report.yml b/.github/ISSUE_TEMPLATE/01_bug_report.yml
index 0ad1776..d113ab5 100644
--- a/.github/ISSUE_TEMPLATE/01_bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/01_bug_report.yml
@@ -7,7 +7,7 @@ body:
attributes:
value: >
Thanks for helping to fix something that's broken! 🤗 See the
- [`CONTRIBUTING.md`](https://github.com/TaffarelJr/.github/blob/main/CONTRIBUTING.md#how-do-i-submit-a-good-bug-report)
+ [`CONTRIBUTING.md`](https://github.com/TaffarelJr/.template-NuGet/blob/main/CONTRIBUTING.md#how-do-i-submit-a-good-bug-report)
file for tips on writing an effective bug report.
- type: checkboxes
@@ -19,19 +19,19 @@ body:
options:
- label: >
I've searched the
- [Documentation](https://github.com/TaffarelJr/.github/tree/main/docs)
- and [Wiki](https://github.com/TaffarelJr/.github/wiki)
+ [Documentation](https://github.com/TaffarelJr/.template-NuGet/tree/main/docs)
+ and [Wiki](https://github.com/TaffarelJr/.template-NuGet/wiki)
for information on this topic,
and I'm sure it's a bug.
required: true
- label: >
I've searched and/or posted in the
- [Discussions](https://github.com/TaffarelJr/.github/discussions)
+ [Discussions](https://github.com/TaffarelJr/.template-NuGet/discussions)
about this bug.
required: true
- label: >
I've searched the existing
- [Issues](https://github.com/TaffarelJr/.github/issues)
+ [Issues](https://github.com/TaffarelJr/.template-NuGet/issues)
and this bug has not been reported yet.
required: true
diff --git a/.github/ISSUE_TEMPLATE/02_performance_issue.yml b/.github/ISSUE_TEMPLATE/02_performance_issue.yml
index eae6216..0b121bf 100644
--- a/.github/ISSUE_TEMPLATE/02_performance_issue.yml
+++ b/.github/ISSUE_TEMPLATE/02_performance_issue.yml
@@ -7,7 +7,7 @@ body:
attributes:
value: >
Thanks for helping us make our code faster! 🤗 See the
- [`CONTRIBUTING.md`](https://github.com/TaffarelJr/.github/blob/main/CONTRIBUTING.md#how-do-i-submit-a-good-bug-report)
+ [`CONTRIBUTING.md`](https://github.com/TaffarelJr/.template-NuGet/blob/main/CONTRIBUTING.md#how-do-i-submit-a-good-bug-report)
file for tips on writing an effective performance issue.
- type: checkboxes
@@ -19,19 +19,19 @@ body:
options:
- label: >
I've searched the
- [Documentation](https://github.com/TaffarelJr/.github/tree/main/docs)
- and [Wiki](https://github.com/TaffarelJr/.github/wiki)
+ [Documentation](https://github.com/TaffarelJr/.template-NuGet/tree/main/docs)
+ and [Wiki](https://github.com/TaffarelJr/.template-NuGet/wiki)
for information on this topic,
and I'm sure it's not performing the way it should.
required: true
- label: >
I've searched and/or posted in the
- [Discussions](https://github.com/TaffarelJr/.github/discussions)
+ [Discussions](https://github.com/TaffarelJr/.template-NuGet/discussions)
about this problem.
required: true
- label: >
I've searched the existing
- [Issues](https://github.com/TaffarelJr/.github/issues)
+ [Issues](https://github.com/TaffarelJr/.template-NuGet/issues)
and this problem has not been reported yet.
required: true
diff --git a/.github/ISSUE_TEMPLATE/03_feature_request.yml b/.github/ISSUE_TEMPLATE/03_feature_request.yml
index 37d4b1c..67b8093 100644
--- a/.github/ISSUE_TEMPLATE/03_feature_request.yml
+++ b/.github/ISSUE_TEMPLATE/03_feature_request.yml
@@ -7,7 +7,7 @@ body:
attributes:
value: >
Thanks for helping us add more value! 🤗 See the
- [`CONTRIBUTING.md`](https://github.com/TaffarelJr/.github/blob/main/CONTRIBUTING.md#how-do-i-submit-a-good-enhancement-suggestion)
+ [`CONTRIBUTING.md`](https://github.com/TaffarelJr/.template-NuGet/blob/main/CONTRIBUTING.md#how-do-i-submit-a-good-enhancement-suggestion)
file for tips on writing an effective enhancement suggestion.
- type: checkboxes
@@ -19,14 +19,14 @@ body:
options:
- label: >
I've searched the
- [Documentation](https://github.com/TaffarelJr/.github/tree/main/docs)
- and [Wiki](https://github.com/TaffarelJr/.github/wiki)
+ [Documentation](https://github.com/TaffarelJr/.template-NuGet/tree/main/docs)
+ and [Wiki](https://github.com/TaffarelJr/.template-NuGet/wiki)
for information on this topic,
and I'm sure it's not currently available.
required: true
- label: >
I've searched and/or posted in the
- [Discussions](https://github.com/TaffarelJr/.github/discussions)
+ [Discussions](https://github.com/TaffarelJr/.template-NuGet/discussions)
about this enhancement.
required: true
- label: >
@@ -36,7 +36,7 @@ body:
required: true
- label: >
I've searched the existing
- [Issues](https://github.com/TaffarelJr/.github/issues)
+ [Issues](https://github.com/TaffarelJr/.template-NuGet/issues)
and this enhancement has not been suggested yet.
required: true
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
deleted file mode 100644
index 37e8a76..0000000
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-blank_issues_enabled: true
-contact_links:
- - name: Community Discussions
- url: https://github.com/TaffarelJr/.github/discussions
- about: Please ask and answer questions here.
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 6dddb42..d0ecf55 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -7,6 +7,32 @@
version: 2
updates:
+ #─────────────────────────────────────────────────────────────────────────────
+ # Update .NET dependencies
+ #─────────────────────────────────────────────────────────────────────────────
+
+ - package-ecosystem: dotnet-sdk
+ directory: /
+ schedule:
+ interval: monthly
+ commit-message:
+ prefix: chore
+ labels: [dependencies, .NET SDK]
+ ignore:
+ - dependency-name: "*"
+ update-types: [version-update:semver-patch]
+
+ - package-ecosystem: nuget
+ directory: /
+ schedule:
+ interval: weekly
+ day: monday
+ commit-message:
+ prefix: chore
+ labels: [dependencies, NuGet]
+ allow:
+ - dependency-type: direct
+
#─────────────────────────────────────────────────────────────────────────────
# Update GitHub Actions workflows
#─────────────────────────────────────────────────────────────────────────────
diff --git a/.github/settings.yml b/.github/settings.yml
new file mode 100644
index 0000000..0336955
--- /dev/null
+++ b/.github/settings.yml
@@ -0,0 +1,89 @@
+_extends: .github
+
+repository:
+
+ #─────────────────────────────────────────────────────────────────────────────
+ # "About" section (on Home Page)
+ # https://github.com/repository-settings/app/blob/master/docs/plugins/repository.md
+ # https://docs.github.com/en/rest/repos/repos#update-a-repository
+ #─────────────────────────────────────────────────────────────────────────────
+
+ # A short description of the repo
+ # MUST BE A SINGLE LINE
+ description: Template repo for publishing NuGet packages
+
+ # A URL with more information about the repo
+ homepage:
+
+ # A comma-separated list of topics to set on the repo
+ # See https://github.com/topics
+ topics: dotnet, csharp, nuget, template-repo
+
+ #─────────────────────────────────────────────────────────────────────────────
+ # Settings → General
+ # https://github.com/repository-settings/app/blob/master/docs/plugins/repository.md
+ # https://docs.github.com/en/rest/repos/repos#update-a-repository
+ #─────────────────────────────────────────────────────────────────────────────
+
+ # The name of the repo
+ name: .template-NuGet
+
+#───────────────────────────────────────────────────────────────────────────────
+# Settings → Rules → Rulesets
+# https://github.com/repository-settings/app/blob/master/docs/plugins/rulesets.md
+# https://docs.github.com/en/rest/repos/rules#update-a-repository-ruleset
+# https://github.com/github/ruleset-recipes
+#───────────────────────────────────────────────────────────────────────────────
+rulesets:
+
+ - name: Status checks must pass
+ target: branch
+ enforcement: disabled
+ bypass_actors:
+ - actor_id: 5 # Repository admin
+ actor_type: RepositoryRole
+ bypass_mode: pull_request
+ conditions:
+ ref_name:
+ include: [~DEFAULT_BRANCH]
+ exclude: []
+ rules:
+ - type: required_status_checks
+ parameters:
+ strict_required_status_checks_policy: true
+ do_not_enforce_on_create: true
+ required_status_checks:
+ - context: Analyze (actions)
+ integration_id: 15368 # GitHub Actions
+ - context: Analyze (csharp)
+ integration_id: 15368 # GitHub Actions
+ - context: Build and Test
+ integration_id: 15368 # GitHub Actions
+ - context: codecov/patch
+ integration_id: 254 # Codecov
+ - context: codecov/project
+ integration_id: 254 # Codecov
+ - type: code_scanning
+ parameters:
+ code_scanning_tools:
+ - tool: CodeQL
+ security_alerts_threshold: high_or_higher
+ alerts_threshold: errors
+
+#───────────────────────────────────────────────────────────────────────────────
+# Issues → Labels
+# https://github.com/repository-settings/app/blob/master/docs/plugins/labels.md
+#───────────────────────────────────────────────────────────────────────────────
+labels:
+
+ # Dependabot Ecosystems
+ # https://docs.github.com/en/code-security/dependabot/ecosystems-supported-by-dependabot/supported-ecosystems-and-repositories
+ # (each uses its own marketing color)
+
+ - name: .NET SDK
+ color: "#522ed1"
+ description: Updates to the required .NET SDK
+
+ - name: NuGet
+ color: "#07497f"
+ description: Updates to NuGet packages
diff --git a/.github/workflows/template-sync.yml b/.github/workflows/template-sync.yml
new file mode 100644
index 0000000..cac08d1
--- /dev/null
+++ b/.github/workflows/template-sync.yml
@@ -0,0 +1,82 @@
+name: Template Sync
+
+on:
+ # Runs daily at midnight (https://crontab.guru/#0_0_1_*_*)
+ # schedule:
+ # - cron: "0 0 1 * *"
+
+ # Can be triggered manually
+ workflow_dispatch:
+
+env:
+ # Configurable parameters
+ GIT_USERNAME: github-actions
+ GIT_EMAIL: github-actions@github.com
+ TEMPLATE_REPO_URL: https://github.com/TaffarelJr/.github.git
+ TEMPLATE_REPO_NAME: template
+ TEMPLATE_REPO_BRANCH: main
+ BASE_BRANCH_NAME: main
+ SYNC_BRANCH_NAME: template-sync
+
+jobs:
+ template-sync:
+ name: Sync with Template Repo
+ runs-on: ubuntu-latest
+
+ # https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
+ permissions:
+ contents: write # Needed to push changes
+ pull-requests: write # Needed to create PRs
+
+ steps:
+ - name: Checkout repo
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0 # Ensure full history for merging
+
+ - name: Configure Git
+ run: |
+ git config user.name "${{ env.GIT_USERNAME }}"
+ git config user.email "${{ env.GIT_EMAIL }}"
+
+ - name: Get latest changes from template
+ run: |
+ git remote add ${{ env.TEMPLATE_REPO_NAME }} ${{ env.TEMPLATE_REPO_URL }} || true
+ git fetch ${{ env.TEMPLATE_REPO_NAME }}
+
+ - name: Check for changes to sync
+ id: check_changes
+ run: git diff --quiet origin/${{ env.BASE_BRANCH_NAME }} ${{ env.TEMPLATE_REPO_NAME }}/${{ env.TEMPLATE_REPO_BRANCH }} || echo "has_changes=true" >> $GITHUB_OUTPUT
+
+ - name: Switch to new branch
+ if: steps.check_changes.outputs.has_changes == 'true'
+ run: git checkout -B ${{ env.SYNC_BRANCH_NAME }} origin/${{ env.BASE_BRANCH_NAME }}
+
+ - name: Merge branches
+ if: steps.check_changes.outputs.has_changes == 'true'
+ id: merge
+ run: |
+ if git merge --no-edit ${{ env.TEMPLATE_REPO_NAME }}/${{ env.TEMPLATE_REPO_BRANCH }}; then
+ echo "conflict=false" >> $GITHUB_OUTPUT
+ else
+ echo "conflict=true" >> $GITHUB_OUTPUT
+ echo "Merge conflicts detected. These will need to be resolved manually."
+ fi
+
+ - name: Push changes
+ if: steps.check_changes.outputs.has_changes == 'true'
+ run: git push --force origin ${{ env.SYNC_BRANCH_NAME }}
+
+ - name: Create or update PR
+ if: steps.check_changes.outputs.has_changes == 'true'
+ uses: peter-evans/create-pull-request@v7
+ with:
+ branch: ${{ env.SYNC_BRANCH_NAME }}
+ base: ${{ env.BASE_BRANCH_NAME }}
+ title: "${{ steps.merge.outputs.conflict == 'true' && 'NEEDS RESOLUTION: ' || '' }}Merge changes from template repo"
+ body: >
+ Automated sync from template repo.
+
+ ${{ steps.merge.outputs.conflict == 'true' && '⚠️ **This PR contains merge conflicts that need to be resolved manually before merging.**' || '' }}
+ labels: "${{ steps.merge.outputs.conflict == 'true' && 'template sync,needs resolution' || 'template sync' }}"
+ delete-branch: true
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c88b1da
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,613 @@
+#───────────────────────────────────────────────────────────────────────────────
+# Diff
+# https://github.com/github/gitignore/blob/main/Global/Diff.gitignore
+#───────────────────────────────────────────────────────────────────────────────
+
+*.patch
+*.diff
+
+#───────────────────────────────────────────────────────────────────────────────
+# Dotnet
+# https://github.com/github/gitignore/blob/main/Dotnet.gitignore
+#───────────────────────────────────────────────────────────────────────────────
+
+# Superceded by Visual Studio (below)
+
+#───────────────────────────────────────────────────────────────────────────────
+# Dotnet Core
+# https://github.com/github/gitignore/blob/main/community/DotNet/core.gitignore
+#───────────────────────────────────────────────────────────────────────────────
+
+# Superceded by Visual Studio (below)
+
+#───────────────────────────────────────────────────────────────────────────────
+# JetBrains
+# https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+#───────────────────────────────────────────────────────────────────────────────
+
+# Covers JetBrains IDEs: IntelliJ, GoLand, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# AWS User-specific
+.idea/**/aws.xml
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/artifacts
+# .idea/compiler.xml
+# .idea/jarRepositories.xml
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# SonarLint plugin
+.idea/sonarlint/
+.idea/sonarlint.xml # see https://community.sonarsource.com/t/is-the-file-idea-idea-idea-sonarlint-xml-intended-to-be-under-source-control/121119
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based HTTP Client
+.idea/httpRequests
+http-client.private.env.json
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+# Apifox Helper cache
+.idea/.cache/.Apifox_Helper
+.idea/ApifoxUploaderProjectSetting.xml
+
+#───────────────────────────────────────────────────────────────────────────────
+# macOS
+# https://github.com/github/gitignore/blob/main/Global/macOS.gitignore
+#───────────────────────────────────────────────────────────────────────────────
+
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+Icon[]
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+#───────────────────────────────────────────────────────────────────────────────
+# TortoiseGit
+# https://github.com/github/gitignore/blob/main/Global/TortoiseGit.gitignore
+#───────────────────────────────────────────────────────────────────────────────
+
+# Project-level settings
+/.tgitconfig
+
+#───────────────────────────────────────────────────────────────────────────────
+# Visual Studio
+# https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
+#───────────────────────────────────────────────────────────────────────────────
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+*.env
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+[Aa][Rr][Mm]64[Ee][Cc]/
+bld/
+[Oo]bj/
+[Oo]ut/
+[Ll]og/
+[Ll]ogs/
+
+# Build results on 'Bin' directories
+**/[Bb]in/*
+# Uncomment if you have tasks that rely on *.refresh files to move binaries
+# (https://github.com/github/gitignore/pull/3736)
+#!**/[Bb]in/*.refresh
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+*.trx
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Approval Tests result files
+*.received.*
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.idb
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+# but not Directory.Build.rsp, as it configures directory-level build defaults
+!Directory.Build.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.tlog
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio 6 workspace and project file (working project files containing files to include in project)
+*.dsw
+*.dsp
+
+# Visual Studio 6 technical files
+*.ncb
+*.aps
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+**/.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+**/.fake/
+
+# CodeRush personal settings
+**/.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+**/__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+#tools/**
+#!tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+MSBuild_Logs/
+
+# AWS SAM Build and Temporary Artifacts folder
+.aws-sam
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+**/.mfractor/
+
+# Local History for Visual Studio
+**/.localhistory/
+
+# Visual Studio History (VSHistory) files
+.vshistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+**/.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
+
+# VS Code files for those working on multiple tools
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+!.vscode/*.code-snippets
+
+# Local History for Visual Studio Code
+.history/
+
+# Built Visual Studio Code Extensions
+*.vsix
+
+# Windows Installer files from build outputs
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+#───────────────────────────────────────────────────────────────────────────────
+# Visual Studio Code
+# https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
+#───────────────────────────────────────────────────────────────────────────────
+
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+!.vscode/*.code-snippets
+!*.code-workspace
+
+# Built Visual Studio Code Extensions
+*.vsix
+
+#───────────────────────────────────────────────────────────────────────────────
+# Windows
+# https://github.com/github/gitignore/blob/main/Global/Windows.gitignore
+#───────────────────────────────────────────────────────────────────────────────
+
+# Windows thumbnail cache files
+Thumbs.db
+Thumbs.db:encryptable
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
diff --git a/.vsconfig b/.vsconfig
new file mode 100644
index 0000000..2e7eee9
--- /dev/null
+++ b/.vsconfig
@@ -0,0 +1,30 @@
+{
+ "version": "1.0",
+ "components": [
+ // Workloads often contain components we don't need.
+ // For this reason, specify individual components
+ // and just group by workload.
+
+ // Microsoft.VisualStudio.Workload.CoreEditor
+ // https://learn.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-community?view=vs-2022#visual-studio-core-editor-included-with-visual-studio-community-2022
+ "Microsoft.VisualStudio.Component.CoreEditor",
+
+ // Microsoft.VisualStudio.Workload.ManagedDesktop
+ // https://learn.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-community?view=vs-2022#net-desktop-development
+ "Microsoft.Component.MSBuild",
+ "Microsoft.NetCore.Component.DevelopmentTools",
+ "Microsoft.NetCore.Component.Runtime.8.0",
+ "Microsoft.NetCore.Component.Runtime.9.0",
+ "Microsoft.NetCore.Component.SDK",
+ "Microsoft.VisualStudio.Component.Debugger.JustInTime",
+ "Microsoft.VisualStudio.Component.DiagnosticTools",
+ "Microsoft.VisualStudio.Component.IntelliCode",
+ "Microsoft.VisualStudio.Component.NuGet",
+ "Microsoft.VisualStudio.Component.Roslyn.Compiler",
+ "Microsoft.VisualStudio.Component.Roslyn.LanguageServices",
+ "Microsoft.VisualStudio.Component.TextTemplating"
+ ],
+ "extensions": [
+ "https://marketplace.visualstudio.com/items?itemName=PaulHarrington.EditorGuidelines"
+ ]
+}
diff --git a/Build.ps1 b/Build.ps1
new file mode 100644
index 0000000..086dd83
--- /dev/null
+++ b/Build.ps1
@@ -0,0 +1,66 @@
+<#
+.SYNOPSIS
+Build script for the NuGet package template.
+
+.DESCRIPTION
+This script handles various setup and build tasks for the NuGet package template.
+#>
+
+#───────────────────────────────────────────────────────────────────────────────
+# Function Definitions
+#───────────────────────────────────────────────────────────────────────────────
+
+# Writes informational messages
+function Write-HostInfo($message) {
+ Write-Host $message -ForegroundColor Blue
+}
+
+# Writes success messages
+function Write-HostSuccess($message) {
+ Write-Host $message -ForegroundColor Green
+}
+
+# Checks exit code and exits on failure
+function Assert-ExitCode($command) {
+ if ($LASTEXITCODE -ne 0) {
+ Write-Host "$command failed with exit code $LASTEXITCODE" -ForegroundColor Red
+ exit $LASTEXITCODE
+ }
+}
+
+#───────────────────────────────────────────────────────────────────────────────
+# Script Execution
+#───────────────────────────────────────────────────────────────────────────────
+
+# Configure git to use the existing .gitmessage template for this repo
+git config --local commit.template .gitmessage
+Write-HostSuccess 'Git commit message template configured'
+
+# Clean previous build artifacts
+Write-Host
+Write-HostInfo 'Cleaning previous build artifacts...'
+dotnet clean --nologo
+Get-ChildItem -Path $PSScriptRoot -Include 'TestResults' -Directory -Recurse `
+| ForEach-Object { Remove-Item -Path $_.FullName -Recurse -Force }
+Assert-ExitCode 'Clean'
+
+# Restore .NET tools
+Write-Host
+Write-HostInfo 'Restoring .NET tools...'
+dotnet tool restore
+Assert-ExitCode 'Tool Restore'
+
+# Restore NuGet packages
+Write-Host
+Write-HostInfo 'Restoring NuGet packages...'
+dotnet restore --nologo
+Assert-ExitCode 'Package Restore'
+
+# Build the solution
+Write-Host
+Write-HostInfo 'Building solution...'
+dotnet build --nologo --no-restore
+Assert-ExitCode 'Build'
+
+Write-Host
+Write-HostSuccess 'Build completed successfully.'
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
deleted file mode 100644
index 5ddf39d..0000000
--- a/CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1,153 +0,0 @@
-# Contributor Covenant Code of Conduct
-
-While these are my personal projects,
-I welcome contributors who share my passion for clean code and creative solutions.
-This Code of Conduct is here to ensure we maintain a
-respectful and positive environment for anyone who wants to join in.
-Think of it as the "house rules" that help us collaborate effectively
-and have fun while building cool stuff together.
-I've kept a standard format that's commonly used in other public repos (below);
-but essentially it says: treat others with respect,
-be constructive in your feedback,
-and remember we're all here because we love coding
-and want to make awesome things together!
-
-#### Table of Contents
-
-- [Our Pledge](#our-pledge)
-- [Our Standards](#our-standards)
-- [Enforcement Responsibilities](#enforcement-responsibilities)
-- [Scope](#scope)
-- [Enforcement](#enforcement)
-- [Enforcement Guidelines](#enforcement-guidelines)
- - [1. Correction](#1-correction)
- - [2. Warning](#2-warning)
- - [3. Temporary Ban](#3-temporary-ban)
- - [4. Permanent Ban](#4-permanent-ban)
-- [Attribution](#attribution)
-
-## Our Pledge
-
-We as members, contributors, and leaders pledge to make participation in our
-community a harassment-free experience for everyone, regardless of age, body
-size, visible or invisible disability, ethnicity, sex characteristics, gender
-identity and expression, level of experience, education, socio-economic status,
-nationality, personal appearance, race, caste, color, religion, or sexual
-identity and orientation.
-
-We pledge to act and interact in ways that contribute to an open, welcoming,
-diverse, inclusive, and healthy community.
-
-## Our Standards
-
-Examples of behavior that contributes to a positive environment for our
-community include:
-
-- Demonstrating empathy and kindness toward other people
-- Being respectful of differing opinions, viewpoints, and experiences
-- Giving and gracefully accepting constructive feedback
-- Accepting responsibility and apologizing to those affected by our mistakes,
- and learning from the experience
-- Focusing on what is best not just for us as individuals, but for the overall
- community
-
-Examples of unacceptable behavior include:
-
-- The use of sexualized language or imagery, and sexual attention or advances of
- any kind
-- Trolling, insulting or derogatory comments, and personal or political attacks
-- Public or private harassment
-- Publishing others' private information, such as a physical or email address,
- without their explicit permission
-- Other conduct which could reasonably be considered inappropriate in a
- professional setting
-
-## Enforcement Responsibilities
-
-Community leaders are responsible for clarifying and enforcing our standards of
-acceptable behavior and will take appropriate and fair corrective action in
-response to any behavior that they deem inappropriate, threatening, offensive,
-or harmful.
-
-Community leaders have the right and responsibility to remove, edit, or reject
-comments, commits, code, wiki edits, issues, and other contributions that are
-not aligned to this Code of Conduct, and will communicate reasons for moderation
-decisions when appropriate.
-
-## Scope
-
-This Code of Conduct applies within all community spaces, and also applies when
-an individual is officially representing the community in public spaces.
-Examples of representing our community include using an official email address,
-posting via an official social media account, or acting as an appointed
-representative at an online or offline event.
-
-## Enforcement
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported to the community leaders responsible for enforcement at
-[INSERT CONTACT METHOD].
-All complaints will be reviewed and investigated promptly and fairly.
-
-All community leaders are obligated to respect the privacy and security of the
-reporter of any incident.
-
-## Enforcement Guidelines
-
-Community leaders will follow these Community Impact Guidelines in determining
-the consequences for any action they deem in violation of this Code of Conduct:
-
-### 1. Correction
-
-**Community Impact**: Use of inappropriate language or other behavior deemed
-unprofessional or unwelcome in the community.
-
-**Consequence**: A private, written warning from community leaders, providing
-clarity around the nature of the violation and an explanation of why the
-behavior was inappropriate. A public apology may be requested.
-
-### 2. Warning
-
-**Community Impact**: A violation through a single incident or series of
-actions.
-
-**Consequence**: A warning with consequences for continued behavior. No
-interaction with the people involved, including unsolicited interaction with
-those enforcing the Code of Conduct, for a specified period of time. This
-includes avoiding interactions in community spaces as well as external channels
-like social media. Violating these terms may lead to a temporary or permanent
-ban.
-
-### 3. Temporary Ban
-
-**Community Impact**: A serious violation of community standards, including
-sustained inappropriate behavior.
-
-**Consequence**: A temporary ban from any sort of interaction or public
-communication with the community for a specified period of time. No public or
-private interaction with the people involved, including unsolicited interaction
-with those enforcing the Code of Conduct, is allowed during this period.
-Violating these terms may lead to a permanent ban.
-
-### 4. Permanent Ban
-
-**Community Impact**: Demonstrating a pattern of violation of community
-standards, including sustained inappropriate behavior, harassment of an
-individual, or aggression toward or disparagement of classes of individuals.
-
-**Consequence**: A permanent ban from any sort of public interaction within the
-community.
-
-## Attribution
-
-This Code of Conduct is adapted from the
-[Contributor Covenant](https://www.contributor-covenant.org/), version 2.1,
-available at
-.
-
-Community Impact Guidelines were inspired by
-[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/inclusion).
-
-For answers to common questions about this code of conduct, see the FAQ at
-. Translations are available at
-.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index d71e26d..99f9abe 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -269,12 +269,12 @@ This guide is based on the [contributing.md][contrib] website.
-[discussions]: https://github.com/TaffarelJr/.github/discussions
-[issues]: https://github.com/TaffarelJr/.github/issues
-[newBug]: https://github.com/TaffarelJr/.github/issues/new?template=01_bug_report.yml
-[newFeature]: https://github.com/TaffarelJr/.github/issues/new?template=03_feature_request.yml
-[newIssue]: https://github.com/TaffarelJr/.github/issues/new?template=02_performance_issue.yml
-[wiki]: https://github.com/TaffarelJr/.github/wiki
+[discussions]: https://github.com/TaffarelJr/.template-NuGet/discussions
+[issues]: https://github.com/TaffarelJr/.template-NuGet/issues
+[newBug]: https://github.com/TaffarelJr/.template-NuGet/issues/new?template=01_bug_report.yml
+[newFeature]: https://github.com/TaffarelJr/.template-NuGet/issues/new?template=03_feature_request.yml
+[newIssue]: https://github.com/TaffarelJr/.template-NuGet/issues/new?template=02_performance_issue.yml
+[wiki]: https://github.com/TaffarelJr/.template-NuGet/wiki
diff --git a/Common.props b/Common.props
new file mode 100644
index 0000000..e615950
--- /dev/null
+++ b/Common.props
@@ -0,0 +1,123 @@
+
+
+
+
+
+ enable
+
+
+
+ latest-all
+ true
+ false
+
+
+
+
+
+ 9.0
+
+
+
+ 9.0
+
+
+
+ 9.0
+
+
+
+ 9.0
+
+
+
+ 9.0
+
+
+
+ 9.0
+
+
+
+ 9.0
+
+
+
+ 9.0
+
+
+
+ 9.0
+
+
+
+
+
+
+ $(DefineConstants);CSHARP10
+ disable
+
+
+
+ $(DefineConstants);CSHARP10;CSHARP11
+ disable
+
+
+
+ $(DefineConstants);CSHARP10;CSHARP11;CSHARP12
+ disable
+
+
+
+ $(DefineConstants);CSHARP10;CSHARP11;CSHARP12;CSHARP13
+ disable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_AllProps>$(MSBuildAllProjects)
+
+
+
+ <_Props Include="@(Property)" />
+
+
+
+
+
+
+
+
diff --git a/Fake.sln b/Fake.sln
new file mode 100644
index 0000000..4505e28
--- /dev/null
+++ b/Fake.sln
@@ -0,0 +1,101 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.14.36221.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".config", ".config", "{8019375E-8EF8-4A58-9309-0A356DB0491D}"
+ ProjectSection(SolutionItems) = preProject
+ .config\dotnet-tools.json = .config\dotnet-tools.json
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{B50175D7-072F-45EB-8E70-8ACB81B55024}"
+ ProjectSection(SolutionItems) = preProject
+ .github\CODEOWNERS = .github\CODEOWNERS
+ .github\copilot-instructions.md = .github\copilot-instructions.md
+ .github\dependabot.yml = .github\dependabot.yml
+ .github\pull_request_template.md = .github\pull_request_template.md
+ .github\settings.yml = .github\settings.yml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ISSUE_TEMPLATE", "ISSUE_TEMPLATE", "{261C00A6-E9BA-4EFC-9992-C75061255EED}"
+ ProjectSection(SolutionItems) = preProject
+ .github\ISSUE_TEMPLATE\01_bug_report.yml = .github\ISSUE_TEMPLATE\01_bug_report.yml
+ .github\ISSUE_TEMPLATE\02_performance_issue.yml = .github\ISSUE_TEMPLATE\02_performance_issue.yml
+ .github\ISSUE_TEMPLATE\03_feature_request.yml = .github\ISSUE_TEMPLATE\03_feature_request.yml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{C7A64F19-DF59-4B16-A9C9-5D317FCF26CD}"
+ ProjectSection(SolutionItems) = preProject
+ .github\workflows\code-coverage.yml = .github\workflows\code-coverage.yml
+ .github\workflows\codecov.yml = .github\workflows\codecov.yml
+ .github\workflows\dotnet.yml = .github\workflows\dotnet.yml
+ .github\workflows\template-sync.yml = .github\workflows\template-sync.yml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ .gitattributes = .gitattributes
+ .gitignore = .gitignore
+ .gitmessage = .gitmessage
+ .vsconfig = .vsconfig
+ Build.ps1 = Build.ps1
+ build.sh = build.sh
+ Common.props = Common.props
+ CONTRIBUTING.md = CONTRIBUTING.md
+ GitReleaseManager.yml = GitReleaseManager.yml
+ GitVersion.yml = GitVersion.yml
+ global.json = global.json
+ LICENSE = LICENSE
+ nuget.config = nuget.config
+ README.md = README.md
+ SECURITY.md = SECURITY.md
+ StyleCop.json = StyleCop.json
+ SUPPORT.md = SUPPORT.md
+ Test.ps1 = Test.ps1
+ test.sh = test.sh
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
+ ProjectSection(SolutionItems) = preProject
+ src\Production.props = src\Production.props
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Fake", "src\Fake\Fake.csproj", "{480242FD-3FE7-4E71-9A1F-0FC446F1D20B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E5056391-64A9-4E23-B6F7-9596973E2D46}"
+ ProjectSection(SolutionItems) = preProject
+ test\.editorconfig = test\.editorconfig
+ test\Test.props = test\Test.props
+ test\Test.runsettings = test\Test.runsettings
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Fake.Tests", "test\Fake.Tests\Fake.Tests.csproj", "{0AEDD51E-D879-4F43-80F4-A3F6E9DF2B06}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {480242FD-3FE7-4E71-9A1F-0FC446F1D20B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {480242FD-3FE7-4E71-9A1F-0FC446F1D20B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {480242FD-3FE7-4E71-9A1F-0FC446F1D20B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {480242FD-3FE7-4E71-9A1F-0FC446F1D20B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0AEDD51E-D879-4F43-80F4-A3F6E9DF2B06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0AEDD51E-D879-4F43-80F4-A3F6E9DF2B06}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0AEDD51E-D879-4F43-80F4-A3F6E9DF2B06}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0AEDD51E-D879-4F43-80F4-A3F6E9DF2B06}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {261C00A6-E9BA-4EFC-9992-C75061255EED} = {B50175D7-072F-45EB-8E70-8ACB81B55024}
+ {C7A64F19-DF59-4B16-A9C9-5D317FCF26CD} = {B50175D7-072F-45EB-8E70-8ACB81B55024}
+ {480242FD-3FE7-4E71-9A1F-0FC446F1D20B} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
+ {0AEDD51E-D879-4F43-80F4-A3F6E9DF2B06} = {E5056391-64A9-4E23-B6F7-9596973E2D46}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {59A0E416-6964-4EC2-93F4-8B2EA777E49D}
+ EndGlobalSection
+EndGlobal
diff --git a/README.md b/README.md
index fe3dd20..cc632d0 100644
--- a/README.md
+++ b/README.md
@@ -75,6 +75,7 @@ flowchart TB
- [Description of Files in This Template Repo](#description-of-files-in-this-template-repo)
- [Community Health Files](#community-health-files)
- [GitHub Templates](#github-templates)
+ - [GitHub Workflows](#github-workflows)
- [Other Files](#other-files)
## Description of Files in This Template Repo
@@ -101,19 +102,28 @@ flowchart TB
| 📄[Issue template chooser][chooser] | ✅ | | |
| 📄[Pull request template][prs] | | ✅ | |
+### [GitHub Workflows][workflows]
+
+| Workflow | Exists onlyin this repo | Synced to
(and overridden in)
derived repos | Description |
+| :---------------------- | :--------------------------: | :-------------------------------------------------: | :------------------------------------------------------------------ |
+| 📄[Template Sync][sync] | | ✅ | Synchronizes changes
from a template repo
to a derived repo |
+
### Other Files
| File | Exists onlyin this repo | Synced to
(and overridden in)
derived repos | Purpose |
| :------------------------------------- | :--------------------------: | :-------------------------------------------------: | :------------------------------------------ |
| 📁[`.vscode/`][vsCode] | | ✅ | Contains VSCode settings |
| 📁[`docs/`][docs] | ✅ | | Contains documentation |
+| 📄[`_Checklist.md`][checklist] | | ✅ | New repo checklist |
| 📄[`.editorconfig`][editorConfig] | | ✅ | [Style guide rule definitions][styleGuides] |
| 📄[`.gitmessage`][message] | | ✅ | [Commit message template][messageGuide] |
| 📄[`copilot-instructions.md`][copilot] | | ✅ | [Copilot configuration][copilotDoc] |
| 📄[`dependabot.yml`][dependabot] | | ✅ | [Dependabot configuration][dependabotDoc] |
+| 📄[`settings.yml`][settings] | | ✅ | [Repo configuration][settingsDoc] |
+[checklist]: ./_Checklist.md
[chooser]: ./.github/ISSUE_TEMPLATE/config.yml
[coc]: ./CODE_OF_CONDUCT.md
[codeOwners]: ./.github/CODEOWNERS
@@ -129,8 +139,10 @@ flowchart TB
[messageGuide]: ./docs/StyleGuides.md#commit-messages
[prs]: ./.github/pull_request_template.md
[security]: ./SECURITY.md
+[settings]: ./.github/settings.yml
[styleGuides]: ./docs/StyleGuides.md
[support]: ./SUPPORT.md
+[sync]: ./.github/workflows/template-sync.yml
[vsCode]: ./.vscode/
@@ -139,5 +151,6 @@ flowchart TB
[dependabotDoc]: https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference
[freeCodeCamp]: https://www.freecodecamp.org/news/how-to-use-the-dot-github-repository
[health]: https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/creating-a-default-community-health-file
+[settingsDoc]: https://github.com/repository-settings/app
[templates]: https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository
[workflows]: https://docs.github.com/en/actions/how-tos/writing-workflows
diff --git a/SECURITY.md b/SECURITY.md
index a7e577d..cc1a791 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -12,4 +12,4 @@ and may ask for additional information or guidance.
-[advisories]: https://github.com/TaffarelJr/.github/security/advisories
+[advisories]: https://github.com/TaffarelJr/.template-NuGet/security/advisories
diff --git a/SUPPORT.md b/SUPPORT.md
index e39e2b6..d670553 100644
--- a/SUPPORT.md
+++ b/SUPPORT.md
@@ -40,6 +40,56 @@ Here are some tips:
See [`CONTRIBUTING.md`][contrib] on how to contribute.
+## Supported Platforms
+
+This project aims to support a wide range of .NET platforms for compatibility.
+To this end, we support platforms that implement .NET Standard 2.0 or higher.
+However, we **highly recommend** using _only_ the platforms that are
+officially supported by Microsoft.
+
+- 🟢 = Fully supported.
+- 🟡 = Still works, but upgrading is highly recommended.
+- 🔴 = Not supported. _(security vulnerabilities, lack of tool support, etc.)_
+
+| Platform | End of
Microsoft Support | .NET Standard
2.0 | .NET Standard
2.1 |
+| :------------------- | ---------------------------: | :-------------------: | :-------------------: |
+| .NET 9 _(STS)_ | May 12, 2026 | 🟢 | 🟢 |
+| .NET 8 _(LTS)_ | November 10, 2026 | 🟢 | 🟢 |
+| .NET 7 _(STS)_ | May 14, 2024 | 🟡 | 🟡 |
+| .NET 6 _(LTS)_ | November 12, 2024 | 🟡 | 🟡 |
+| .NET 5 _(STS)_ | May 10, 2022 | 🟡 | 🟡 |
+| .NET Core 3.1 | December 13, 2022 | 🟡 | 🟡 |
+| .NET Core 3.0 | March 3, 2020 | 🔴 | 🔴 |
+| .NET Core 2.2 | December 23, 2019 | 🔴 | — |
+| .NET Core 2.1 | August 21, 2021 | 🔴 | — |
+| .NET Core 2.0 | October 1, 2018 | 🔴 | — |
+| .NET Core 1.1 | June 27, 2019 | — | — |
+| .NET Core 1.0 | June 27, 2019 | — | — |
+| .NET Framework 4.8.1 | _\_ | 🟢 | — |
+| .NET Framework 4.8 | _\_ | 🟢 | — |
+| .NET Framework 4.7.2 | _\_ | 🟢 | — |
+| .NET Framework 4.7.1 | _\_ | 🟢 | — |
+| .NET Framework 4.7 | _\_ | 🟢 | — |
+| .NET Framework 4.6.2 | January 12, 2027 | 🟢 | — |
+| .NET Framework 4.6.1 | Apr 26, 2022 | 🔴 | — |
+| .NET Framework 4.6 | Apr 26, 2022 | — | — |
+| .NET Framework 4.5.2 | Apr 26, 2022 | — | — |
+| .NET Framework 4.5.1 | Jan 12, 2016 | — | — |
+| .NET Framework 4.5 | Jan 12, 2016 | — | — |
+
+> [!NOTE]
+> .NET Framework 4.6.2 and later are supported as long as they're on a supported
+> Windows OS.
+
+More information about supported platforms can be found here:
+
+- [.NET Core & .NET][netCore] support policies
+- [.NET Standard][netStandard] implementation
+- [.NET Framework][netFramework] support policies
+- [Microsoft Product & Service Lifecycle information][winLifecycle] (search page)
+ - [Windows 10 Home and Pro][winHomePro] release support
+ - [Windows Server][winServer] release support
+
## Attribution
This document was shamelessly stolen and modified
@@ -53,13 +103,19 @@ from the [Remark][remark] repo.
-[discussions]: https://github.com/TaffarelJr/.github/discussions
-[issues]: https://github.com/TaffarelJr/.github/issues
-[wiki]: https://github.com/TaffarelJr/.github/wiki
+[discussions]: https://github.com/TaffarelJr/.template-NuGet/discussions
+[issues]: https://github.com/TaffarelJr/.template-NuGet/issues
+[wiki]: https://github.com/TaffarelJr/.template-NuGet/wiki
+[netCore]: https://dotnet.microsoft.com/platform/support/policy/dotnet-core
+[netFramework]: https://docs.microsoft.com/en-us/lifecycle/products/microsoft-net-framework
+[netStandard]: https://docs.microsoft.com/en-us/dotnet/standard/net-standard
[remark]: https://github.com/remarkjs/.github/blob/main/support.md
[rubberduck]: https://rubberduckdebugging.com
[sandbox]: https://codesandbox.io
+[winHomePro]: https://docs.microsoft.com/en-us/lifecycle/products/windows-10-home-and-pro
+[winLifecycle]: https://docs.microsoft.com/en-us/lifecycle/products
+[winServer]: https://docs.microsoft.com/en-us/lifecycle/products/windows-server
[xy]: https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem/66378#66378
diff --git a/StyleCop.json b/StyleCop.json
new file mode 100644
index 0000000..52304c3
--- /dev/null
+++ b/StyleCop.json
@@ -0,0 +1,68 @@
+{
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/Configuration.md#documentation-rules
+ "documentationRules": {
+ "companyName": "RJ Hollberg",
+ "copyrightText": "Copyright © {companyName}. All rights reserved.\nLicensed under the {licenseName} license.\nSee the {licenseFile} file in the project root for full license information.",
+ "xmlHeader": true,
+ "variables": {
+ "licenseName": "MIT",
+ "licenseFile": "LICENSE"
+ },
+ "headerDecoration": "─────────────────────────────────────────────────────────────────────────────",
+ "documentInterfaces": true,
+ "documentExposedElements": true,
+ "documentInternalElements": true,
+ "documentPrivateElements": false,
+ "documentPrivateFields": false,
+ "documentationCulture": "en-US",
+ "fileNamingConvention": "stylecop",
+ "excludeFromPunctuationCheck": ["seealso"]
+ },
+
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/Configuration.md#indentation
+ "indentation": {
+ "indentationSize": 4,
+ "tabSize": 4,
+ "useTabs": false
+ },
+
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/Configuration.md#layout-rules
+ "layoutRules": {
+ "newlineAtEndOfFile": "require",
+ "allowConsecutiveUsings": true,
+ "allowDoWhileOnClosingBrace": false
+ },
+
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/Configuration.md#maintainability-rules
+ "maintainabilityRules": {
+ "topLevelTypes": ["class", "interface", "struct", "enum"]
+ },
+
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/Configuration.md#naming-rules
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [],
+ "allowedNamespaceComponents": [],
+ "includeInferredTupleElementNames": false,
+ "tupleElementNameCasing": "PascalCase"
+ },
+
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/Configuration.md#ordering-rules
+ "orderingRules": {
+ "elementOrder": ["kind", "accessibility", "constant", "static", "readonly"],
+ "systemUsingDirectivesFirst": true,
+ "usingDirectivesPlacement": "outsideNamespace",
+ "blankLinesBetweenUsingGroups": "allow"
+ },
+
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/Configuration.md#readability-rules
+ "readabilityRules": {
+ "allowBuiltInTypeAliases": false
+ },
+
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/Configuration.md#spacing-rules
+ "spacingRules": {}
+ }
+}
diff --git a/Test.ps1 b/Test.ps1
new file mode 100644
index 0000000..55eadd8
--- /dev/null
+++ b/Test.ps1
@@ -0,0 +1,71 @@
+<#
+.SYNOPSIS
+Test script for the NuGet package template.
+
+.DESCRIPTION
+This script runs tests with code coverage and generates a report.
+It calls the build script first to ensure everything is built correctly.
+#>
+
+#───────────────────────────────────────────────────────────────────────────────
+# Variable Definitions
+#───────────────────────────────────────────────────────────────────────────────
+
+$TestDir = Join-Path $PSScriptRoot 'test'
+$ResultsDir = Join-Path $TestDir 'TestResults'
+
+#───────────────────────────────────────────────────────────────────────────────
+# Prerequisites
+#───────────────────────────────────────────────────────────────────────────────
+
+# Import the build script and execute it
+. (Join-Path $PSScriptRoot 'build.ps1')
+
+#───────────────────────────────────────────────────────────────────────────────
+# Function Definitions
+#───────────────────────────────────────────────────────────────────────────────
+
+# Function to display the coverage summary
+function Show-CoverageSummary($file) {
+ Get-Content $file | ForEach-Object {
+ if ($_ -Match "Line coverage:|Branch coverage:|Method coverage:") {
+ Write-HostSuccess $_
+ }
+ else {
+ Write-Host $_
+ }
+ }
+}
+
+#───────────────────────────────────────────────────────────────────────────────
+# Script Execution
+#───────────────────────────────────────────────────────────────────────────────
+
+# Run the tests with code coverage
+Write-Host
+Write-HostInfo 'Running tests with code coverage...'
+dotnet test `
+ --nologo `
+ --no-restore `
+ --no-build `
+ --collect:'XPlat Code Coverage' `
+ --settings:"$(Join-Path $TestDir 'Test.runsettings')"
+Assert-ExitCode 'Tests'
+
+# Generate reports from the coverage results
+Write-Host
+Write-HostInfo 'Generating coverage report...'
+reportgenerator `
+ -reports:"$(Join-Path '**' 'coverage.cobertura.xml')" `
+ -reporttypes:'HtmlInline;TextSummary' `
+ -targetdir:"$ResultsDir"
+Assert-ExitCode 'Report Generation'
+
+# Display coverage results in the console
+Write-Host
+Show-CoverageSummary (Join-Path $ResultsDir 'Summary.txt')
+Write-Host
+Write-HostSuccess "Tests complete. Report generated in: $ResultsDir"
+
+# Open the HTML report
+Start-Process (Join-Path $ResultsDir 'index.html')
diff --git a/_Checklist.md b/_Checklist.md
new file mode 100644
index 0000000..b218dee
--- /dev/null
+++ b/_Checklist.md
@@ -0,0 +1,178 @@
+# Creating a New Template Repo
+
+Template repos use the [`.github`][template] repo
+as their base template.
+Follow these steps to create a new repo derived from it.
+
+#### Table of Contents
+
+- [1. Create the new template repo](#1-create-the-new-template-repo)
+- [2. Configure manual repo settings](#2-configure-manual-repo-settings)
+- [3. Clone the repo](#3-clone-the-repo)
+- [4. Customize template files](#4-customize-template-files)
+- [5. Customize root repo files](#5-customize-root-repo-files)
+- [6. Override repo settings](#6-override-repo-settings)
+- [7. Push the changes to GitHub](#7-push-the-changes-to-github)
+- [8. Run the template sync](#8-run-the-template-sync)
+
+## 1. Create the new template repo
+
+- DO NOT use a template in GitHub when creating the new repo;
+ we'll use Git-merge to get the necessary files instead.
+- The new repo name should use the format: `.template-`
+ - For example: `.template-NuGet`
+- Leave the description blank.
+- Don't add any files to the new repo, leave it empty.
+
+## 2. Configure manual repo settings
+
+Not all repo settings can be managed from the `settings.yml` file.
+The following settings must be configured manually:
+
+- Go to `Settings`
+ - Go to `General`
+ - Check `Limit how many branches and tags can be updated in a single push`
+ - Up to `2` branches and tags can be updated in a push
+ - Go to `Moderation options`
+ - Go to `Code review limits`
+ - Check `Limit to users explicitly granted read or higher access`
+ - Go to `Actions`
+ - Go to `General`
+ - Check `Allow GitHub Actions to create and approve pull requests`
+ - Click `Save`
+ - Go to `Advanced Security`
+ - Enable `Private vulnerability reporting`
+ - Enable `Dependency graph` _(if necessary)_
+ - Enable `Grouped security updates`
+ - Set up `CodeQL analysis` to use `Default` settings
+ - Go to `Secrets and variables`
+ - Go to `Actions`
+ - Add a repository secret for `CODECOV_TOKEN`
+ (global upload token value can be found on the Codecov website,
+ either in repo settings or profile settings)
+
+## 3. Clone the repo
+
+Clone the repo locally and open it in Visual Studio Code.
+The [`.github`][template] repo needs to be added as an upstream remote
+so the template sync can import the commits to the new repo
+with those in the [`.github`][template] repo.
+Execute the following commands:
+
+```bash
+# May need to configure SSH key
+git config remote.pushdefault origin
+git remote add template git@github.com:TaffarelJr/.github.git
+git fetch template
+git checkout -B main template/main
+git config commit.template .gitmessage
+```
+
+## 4. Customize template files
+
+Some files that were synced from the [`.github`][template] repo
+need to be customized for this new template repo.
+
+- Delete the following files that will
+ reside only in the [`.github`][template] repo:
+ - `.github/ISSUE_TEMPLATE/config.yml`
+ - `.github/FUNDING.yml`
+ - `CODE_OF_CONDUCT.md`
+- Find all instances of `TaffarelJr/.github` in the repo
+ - Replace them with `TaffarelJr/` in **ONLY** these files:
+ - `CONTRIBUTING.md`
+ - `SECURITY.md`
+ - `SUPPORT.md`
+ - `/ISSUE_TEMPLATE/01_bug_report.yml`
+ - `/ISSUE_TEMPLATE/02_performance_issue.yml`
+ - `/ISSUE_TEMPLATE/03_feature_request.yml`
+- Un-comment the cron schedule in the [`template-sync`][sync] workflow.
+- Make any additional changes to the template files as necessary.
+- Commit the changes with the message: `chore: customize template files`
+
+## 5. Customize root repo files
+
+Now we can add deeper customization to the root repo files
+to meet the needs of the new template:
+
+- Replace the contents of the `_Checklist.md` file
+ - Back up the previous file while you finish working through it
+- Modify `.editorconfig` as needed
+- Generate a `.gitattributes` file using https://github.com/gitattributes/gitattributes
+- Generate a `.gitignore` file using https://github.com/github/gitignore
+- Replace the contents of the `README.md` file
+- Add any additional ecosystems to `dependabot.yml`
+- Make any additional changes to the root files as necessary.
+- Commit the changes with the message: `chore: customize root files`
+
+## 6. Override repo settings
+
+Most of the settings in the `settings.yml` file
+are appropriate to inherit from the [`.github`][template] repo.
+Only a few of them need to be overridden in the new template repo.
+
+Replace the contents of the file with the following,
+filling in the values as indicated:
+
+```yaml
+_extends: .github
+
+repository:
+
+ #─────────────────────────────────────────────────────────────────────────────
+ # "About" section (on Home Page)
+ # https://github.com/repository-settings/app/blob/master/docs/plugins/repository.md
+ # https://docs.github.com/en/rest/repos/repos#update-a-repository
+ #─────────────────────────────────────────────────────────────────────────────
+
+ # A short description of the repo
+ # MUST BE A SINGLE LINE
+ description: <1-line description>.
+
+ # A URL with more information about the repo
+ homepage:
+
+ # A comma-separated list of topics to set on the repo
+ # See https://github.com/topics
+ topics: , , ...
+
+ #─────────────────────────────────────────────────────────────────────────────
+ # Settings → General
+ # https://github.com/repository-settings/app/blob/master/docs/plugins/repository.md
+ # https://docs.github.com/en/rest/repos/repos#update-a-repository
+ #─────────────────────────────────────────────────────────────────────────────
+
+ # The name of the repo
+ name:
+
+ # Whether to allow merging pull requests with a merge commit
+ allow_merge_commit: false
+```
+
+Make any additional changes as needed.
+Commit the changes with the message: `chore: customize repo settings`
+
+## 7. Push the changes to GitHub
+
+Push the branch to GitHub:
+
+```bash
+git push
+```
+
+The settings should take effect almost immediately;
+verify that the repo description and tags appear on the home page.
+
+## 8. Run the template sync
+
+Finally, validate the template sync.
+To do this, go to `Actions` → `Template Sync` → `Run workflow` → `main`
+and click `Run workflow`. The process should complete with no changes.
+
+
+
+[sync]: .github/workflows/template-sync.yml
+
+
+
+[template]: https://github.com/TaffarelJr/.github
diff --git a/build.sh b/build.sh
new file mode 100644
index 0000000..2410d79
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,63 @@
+#!/usr/bin/env bash
+#
+# Build script for the NuGet package template.
+#
+# This script handles various setup and build tasks for the NuGet package template.
+
+#───────────────────────────────────────────────────────────────────────────────
+# Function Definitions
+#───────────────────────────────────────────────────────────────────────────────
+
+# Writes informational messages
+echo_info() {
+ echo -e "\e[34m$1\e[0m"
+}
+
+# Writes success messages
+echo_success() {
+ echo -e "\e[32m$1\e[0m"
+}
+
+# Checks exit code and exits on failure
+assert_exit_code() {
+ if [ $? -ne 0 ]; then
+ echo -e "\e[31m$1 failed with exit code $?\e[0m"
+ exit $?
+ fi
+}
+
+#───────────────────────────────────────────────────────────────────────────────
+# Script Execution
+#───────────────────────────────────────────────────────────────────────────────
+
+# Configure git to use the existing .gitmessage template for this repo
+git config --local commit.template .gitmessage
+echo_success 'Git commit message template configured'
+
+# Clean previous build artifacts
+echo
+echo_info 'Cleaning previous build artifacts...'
+dotnet clean --nologo
+find "$(dirname "$0")" -name 'TestResults' -type d -exec rm -rf {} +
+assert_exit_code 'Clean'
+
+# Restore .NET tools
+echo
+echo_info 'Restoring .NET tools...'
+dotnet tool restore
+assert_exit_code 'Tool Restore'
+
+# Restore NuGet packages
+echo
+echo_info 'Restoring NuGet packages...'
+dotnet restore --nologo
+assert_exit_code 'Package Restore'
+
+# Build the solution
+echo
+echo_info 'Building solution...'
+dotnet build --nologo --no-restore
+assert_exit_code 'Build'
+
+echo
+echo_success 'Build completed successfully.'
diff --git a/global.json b/global.json
new file mode 100644
index 0000000..cdbb589
--- /dev/null
+++ b/global.json
@@ -0,0 +1,6 @@
+{
+ "sdk": {
+ "version": "9.0.100",
+ "rollForward": "latestFeature"
+ }
+}
diff --git a/nuget.config b/nuget.config
new file mode 100644
index 0000000..51bf47b
--- /dev/null
+++ b/nuget.config
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Fake/Class1.cs b/src/Fake/Class1.cs
new file mode 100644
index 0000000..19c80f6
--- /dev/null
+++ b/src/Fake/Class1.cs
@@ -0,0 +1,22 @@
+namespace Fake
+{
+ ///
+ /// Represents a class with no specific functionality.
+ ///
+ public static class Class1
+ {
+ ///
+ /// Performs a calculation on the provided value.
+ ///
+ /// The input value.
+ /// The calculated result.
+ public static int Calculate(int value)
+ {
+#if NETSTANDARD2_0
+ return value * 2;
+#elif NET9_0
+ return value * 3;
+#endif
+ }
+ }
+}
diff --git a/src/Fake/Fake.csproj b/src/Fake/Fake.csproj
new file mode 100644
index 0000000..dda7a56
--- /dev/null
+++ b/src/Fake/Fake.csproj
@@ -0,0 +1,29 @@
+
+
+
+
+
+ netstandard2.0;net9.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Fake/PublicAPI.Shipped.txt b/src/Fake/PublicAPI.Shipped.txt
new file mode 100644
index 0000000..e69de29
diff --git a/src/Fake/PublicAPI.Unshipped.txt b/src/Fake/PublicAPI.Unshipped.txt
new file mode 100644
index 0000000..e69de29
diff --git a/src/Production.props b/src/Production.props
new file mode 100644
index 0000000..d369728
--- /dev/null
+++ b/src/Production.props
@@ -0,0 +1,73 @@
+
+
+
+
+
+ true
+ true
+
+
+
+ RJ Hollberg
+ Copyright © $([System.DateTime]::Now.Year) RJ Hollberg. All rights reserved.
+
+ true
+ Icon.png
+ LICENSE
+ README.md
+ $(PackageTags)
+ false
+ false
+
+
+
+ true
+ git
+
+
+
+ $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
+ true
+ portable
+ true
+ true
+ snupkg
+
+
+
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test.sh b/test.sh
new file mode 100644
index 0000000..a5ee49b
--- /dev/null
+++ b/test.sh
@@ -0,0 +1,88 @@
+#!/usr/bin/env bash
+#
+# Test script for the NuGet package template.
+#
+# This script runs tests with code coverage and generates a report.
+# It calls the build script first to ensure everything is built correctly.
+
+#───────────────────────────────────────────────────────────────────────────────
+# Variable Definitions
+#───────────────────────────────────────────────────────────────────────────────
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+TEST_DIR="$SCRIPT_DIR/test"
+RESULTS_DIR="$TEST_DIR/TestResults"
+HTML_FILE="$RESULTS_DIR/index.html"
+
+#───────────────────────────────────────────────────────────────────────────────
+# Prerequisites
+#───────────────────────────────────────────────────────────────────────────────
+
+# Import the build script and execute it
+. "$SCRIPT_DIR/build.sh"
+
+#───────────────────────────────────────────────────────────────────────────────
+# Function Definitions
+#───────────────────────────────────────────────────────────────────────────────
+
+# Function to display the coverage summary
+show_coverage_summary() {
+ while IFS= read -r line; do
+ if [[ $line =~ (Line coverage:|Branch coverage:|Method coverage:) ]]; then
+ echo_success "$line"
+ else
+ echo "$line"
+ fi
+ done < "$1"
+}
+
+#───────────────────────────────────────────────────────────────────────────────
+# Script Execution
+#───────────────────────────────────────────────────────────────────────────────
+
+# Run the tests with code coverage
+echo
+echo_info 'Running tests with code coverage...'
+dotnet test \
+ --nologo \
+ --no-restore \
+ --no-build \
+ --collect:'XPlat Code Coverage' \
+ --settings:"$TEST_DIR/Test.runsettings"
+assert_exit_code 'Tests'
+
+# Generate reports from the coverage results
+echo
+echo_info 'Generating coverage report...'
+reportgenerator \
+ -reports:'**/coverage.cobertura.xml' \
+ -reporttypes:'HtmlInline;TextSummary' \
+ -targetdir:"$RESULTS_DIR"
+assert_exit_code 'Report Generation'
+
+# Display coverage results in the console
+echo
+show_coverage_summary "$RESULTS_DIR/Summary.txt"
+echo
+echo_success "Tests complete. Report generated in: $RESULTS_DIR"
+
+# Open the HTML report
+if [[ "$OSTYPE" == "darwin"* ]]; then # macOS
+ open "$HTML_FILE"
+elif [[ "$OSTYPE" == "linux-gnu"* ]]; then # Linux
+ if command -v xdg-open > /dev/null; then
+ xdg-open "$HTML_FILE"
+ elif command -v gnome-open > /dev/null; then
+ gnome-open "$HTML_FILE"
+ fi
+elif [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "win32" ]]; then # Windows
+ start "$HTML_FILE"
+elif [[ -n "$(uname -r | grep -i microsoft)" ]]; then # Windows Subsystem for Linux (WSL)
+ if command -v wslview > /dev/null; then
+ wslview "$HTML_FILE"
+ elif command -v powershell.exe > /dev/null; then
+ powershell.exe -Command "Start-Process '$(wslpath -w "$HTML_FILE")'"
+ elif command -v cmd.exe > /dev/null; then
+ cmd.exe /c start "$(wslpath -w "$HTML_FILE")"
+ fi
+fi
diff --git a/test/.editorconfig b/test/.editorconfig
new file mode 100644
index 0000000..bd95fde
--- /dev/null
+++ b/test/.editorconfig
@@ -0,0 +1,36 @@
+#───────────────────────────────────────────────────────────────────────────────
+# These rules are unnecessary for test code:
+#───────────────────────────────────────────────────────────────────────────────
+
+[*.cs]
+
+# CodeAnalysis rules
+# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/
+dotnet_diagnostic.CA1054.severity = none # URI-like parameters should not be strings
+dotnet_diagnostic.CA1063.severity = none # Implement IDisposable Correctly
+dotnet_diagnostic.CA1303.severity = none # Do not pass literals as localized parameters
+dotnet_diagnostic.CA1304.severity = none # Specify CultureInfo
+dotnet_diagnostic.CA1305.severity = none # Specify IFormatProvider
+dotnet_diagnostic.CA1307.severity = none # Specify StringComparison for clarity
+dotnet_diagnostic.CA1308.severity = none # Normalize strings to uppercase
+dotnet_diagnostic.CA1707.severity = none # Identifiers should not contain underscores
+dotnet_diagnostic.CA1816.severity = none # Dispose methods should call SuppressFinalize
+dotnet_diagnostic.CA1822.severity = none # Mark members as static
+dotnet_diagnostic.CA2263.severity = none # Prefer generic overload when type is known
+dotnet_diagnostic.CA5394.severity = none # Do not use insecure randomness
+
+# Compiler warnings
+# https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/
+dotnet_diagnostic.CS1591.severity = none # Missing XML comment for publicly visible type or member
+dotnet_diagnostic.CS8002.severity = none # Referenced assembly does not have a strong name
+
+# StyleCop rules
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/tree/master/documentation
+dotnet_diagnostic.SA0001.severity = none # XML comment analysis disabled
+dotnet_diagnostic.SA1124.severity = none # Do not use regions
+dotnet_diagnostic.SA1600.severity = none # Elements should be documented
+dotnet_diagnostic.SA1601.severity = none # Partial elements should be documented
+dotnet_diagnostic.SA1604.severity = none # Element documentation should have summary
+dotnet_diagnostic.SA1605.severity = none # Partial element documentation should have summary
+dotnet_diagnostic.SA1611.severity = none # Element parameters should be documented
+dotnet_diagnostic.SA1619.severity = none # Generic type parameters should be documented partial class
diff --git a/test/Fake.Tests/Class1Tests.cs b/test/Fake.Tests/Class1Tests.cs
new file mode 100644
index 0000000..e52f12c
--- /dev/null
+++ b/test/Fake.Tests/Class1Tests.cs
@@ -0,0 +1,56 @@
+using Xunit;
+
+namespace Fake
+{
+ public class Class1Tests
+ {
+ [Theory]
+#if NET9_0
+ [InlineData(1, 3)]
+ [InlineData(2, 6)]
+ [InlineData(3, 9)]
+#else
+ [InlineData(1, 2)]
+ [InlineData(2, 4)]
+ [InlineData(3, 6)]
+#endif
+ public void TestCompilerSwitches_OnAttributes(int given, int expected)
+ {
+ // Act
+ var result = Class1.Calculate(given);
+
+ // Assert
+ Assert.Equal(expected, result);
+ }
+
+ [Fact]
+ public void TestCompilerSwitches_OnCode()
+ {
+#if NET462
+ Assert.Equal(2, Class1.Calculate(1));
+#elif NET47
+ Assert.Equal(2, Class1.Calculate(1));
+#elif NET471
+ Assert.Equal(2, Class1.Calculate(1));
+#elif NET472
+ Assert.Equal(2, Class1.Calculate(1));
+#elif NET48
+ Assert.Equal(2, Class1.Calculate(1));
+#elif NET481
+ Assert.Equal(2, Class1.Calculate(1));
+#elif NETCOREAPP3_1
+ Assert.Equal(2, Class1.Calculate(1));
+#elif NET5_0
+ Assert.Equal(2, Class1.Calculate(1));
+#elif NET6_0
+ Assert.Equal(2, Class1.Calculate(1));
+#elif NET7_0
+ Assert.Equal(2, Class1.Calculate(1));
+#elif NET8_0
+ Assert.Equal(2, Class1.Calculate(1));
+#elif NET9_0
+ Assert.Equal(3, Class1.Calculate(1));
+#endif
+ }
+ }
+}
diff --git a/test/Fake.Tests/Fake.Tests.csproj b/test/Fake.Tests/Fake.Tests.csproj
new file mode 100644
index 0000000..8eae12a
--- /dev/null
+++ b/test/Fake.Tests/Fake.Tests.csproj
@@ -0,0 +1,39 @@
+
+
+
+
+
+ net462;net47;net471;net472;net48;net481;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0
+ Fake
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Test.props b/test/Test.props
new file mode 100644
index 0000000..1676153
--- /dev/null
+++ b/test/Test.props
@@ -0,0 +1,67 @@
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Test.runsettings b/test/Test.runsettings
new file mode 100644
index 0000000..b74fdcf
--- /dev/null
+++ b/test/Test.runsettings
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ cobertura
+
+ Obsolete,GeneratedCode,CompilerGenerated
+
+
+
+ false
+ false
+ false
+ true
+
+ true
+ MissingAll
+
+
+
+
+