diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 0000000..622db8e --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,69 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-format": { + "version": "5.1.250801", + "commands": [ + "dotnet-format" + ], + "rollForward": false + }, + "dotnet-stryker": { + "version": "4.0.6", + "commands": [ + "dotnet-stryker" + ], + "rollForward": false + }, + "winsharpfuzz.commandline": { + "version": "1.0.0", + "commands": [ + "winsharpfuzz" + ], + "rollForward": false + }, + "winsharpfuzz.instrument": { + "version": "1.0.0", + "commands": [ + "winsharpfuzz-instrument" + ], + "rollForward": false + }, + "sharpfuzz.commandline": { + "version": "2.1.1", + "commands": [ + "sharpfuzz" + ], + "rollForward": false + }, + "dotnet-reportgenerator-globaltool": { + "version": "5.3.7", + "commands": [ + "reportgenerator" + ], + "rollForward": false + }, + "microsoft.sbom.dotnettool": { + "version": "2.2.6", + "commands": [ + "sbom-tool" + ], + "rollForward": false + }, + "husky": { + "version": "0.7.0", + "commands": [ + "husky" + ], + "rollForward": false + }, + "dotnet-validate": { + "version": "0.0.1-preview.304", + "commands": [ + "dotnet-validate" + ], + "rollForward": false + } + } +} \ No newline at end of file diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a4ac02a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,307 @@ +# Remove the line below if you want to inherit .editorconfig settings from higher directories +root = true + +# C# files +[*.cs] + +# Spell checker +[*] +spelling_languages = en-US +spelling_checkable_types = strings,identifiers,comments +spelling_error_severity = information +spelling_exclusion_path = ./spellcheckerexclusion.dic +spelling_use_default_exclusion_dictionary = true + + +#### Core EditorConfig Options #### + +# Indentation and spacing +indent_size = 4 +indent_style = space +tab_width = 4 + +# New line preferences +end_of_line = crlf +insert_final_newline = false + +#### .NET Coding Conventions #### + +# Organize usings +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = false +file_header_template = unset + +# Warning and severity. +dotnet_diagnostic.CA1416.severity = error + +# Code analyzers. +dotnet_diagnostic.CA1307.severity = error +dotnet_diagnostic.CA1309.severity = error +dotnet_diagnostic.CA1311.severity = error +dotnet_diagnostic.CA1815.severity = error +dotnet_diagnostic.CA1825.severity = error + +# nullability checks. +dotnet_diagnostic.IDE0029.severity = error +dotnet_diagnostic.IDE0031.severity = error +dotnet_diagnostic.IDE0041.severity = error + +# this. and Me. preferences +dotnet_style_qualification_for_event = false +dotnet_style_qualification_for_field = false +dotnet_style_qualification_for_method = false +dotnet_style_qualification_for_property = false + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true +dotnet_style_predefined_type_for_member_access = true + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_operators = never_if_unnecessary +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members + +# Expression-level preferences +dotnet_style_coalesce_expression = true +dotnet_style_collection_initializer = true +dotnet_style_explicit_tuple_names = true +dotnet_style_namespace_match_folder = true +dotnet_style_null_propagation = true +dotnet_style_object_initializer = true +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_prefer_auto_properties = true +dotnet_style_prefer_compound_assignment = true +dotnet_style_prefer_conditional_expression_over_assignment = true +dotnet_style_prefer_conditional_expression_over_return = true +dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed +dotnet_style_prefer_inferred_anonymous_type_member_names = true +dotnet_style_prefer_inferred_tuple_names = true +dotnet_style_prefer_is_null_check_over_reference_equality_method = true +dotnet_style_prefer_simplified_boolean_expressions = true +dotnet_style_prefer_simplified_interpolation = true + +# Field preferences +dotnet_style_readonly_field = true + +# Parameter preferences +dotnet_code_quality_unused_parameters = all + +# Suppression preferences +dotnet_remove_unnecessary_suppression_exclusions = none + +# New line preferences +dotnet_style_allow_multiple_blank_lines_experimental = true +dotnet_style_allow_statement_immediately_after_block_experimental = true + +#### C# Coding Conventions #### + +# var preferences +csharp_style_var_for_built_in_types = false:suggestion +csharp_style_var_when_type_is_apparent = false:none +csharp_style_var_elsewhere = false:suggestion +dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion +dotnet_style_predefined_type_for_member_access = true:suggestion + +# 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_extended_property_pattern = true +csharp_style_prefer_not_pattern = true +csharp_style_prefer_pattern_matching = true +csharp_style_prefer_switch_expression = true + +# Null-checking preferences +csharp_style_conditional_delegate_call = true + +# Modifier preferences +csharp_prefer_static_local_function = true +csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async:suggestion + +# Code-block preferences +csharp_prefer_braces = true:silent +csharp_prefer_simple_using_statement = false:suggestion +csharp_style_namespace_declarations = block_scoped:silent +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_top_level_statements = true:silent + +# Expression-level preferences +csharp_prefer_simple_default_expression = true +csharp_style_deconstructed_variable_declaration = true +csharp_style_implicit_object_creation_when_type_is_apparent = true +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_prefer_index_operator = true +csharp_style_prefer_local_over_anonymous_function = true +csharp_style_prefer_null_check_over_type_check = true +csharp_style_prefer_range_operator = true +csharp_style_prefer_tuple_swap = true +csharp_style_prefer_utf8_string_literals = true +csharp_style_throw_expression = true +csharp_style_unused_value_assignment_preference = discard_variable +csharp_style_unused_value_expression_statement_preference = discard_variable:suggestion + +# 'using' directive preferences +csharp_using_directive_placement = outside_namespace:silent + +# New line preferences +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true +csharp_style_allow_embedded_statements_on_same_line_experimental = true + +#### 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 = false +csharp_indent_labels = flush_left +csharp_indent_switch_labels = true + +# Space preferences +csharp_space_after_cast = false +csharp_space_before_attribute_colon = false +csharp_space_after_attribute_colon = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_before_type_parameter_constraint_colon = false +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = false +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 = false +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 +csharp_style_prefer_primary_constructors = true:suggestion + +# C++ Files +[*.{cpp,h,in}] +curly_bracket_next_line = true +indent_brace_style = Allman + +# Xml project files +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}] +indent_size = 2 + +[*.{csproj,vbproj,proj,nativeproj,locproj}] +charset = utf-8 + +# Xml build files +[*.builds] +indent_size = 2 + +# Xml files +[*.{xml,stylecop,resx,ruleset}] +indent_size = 2 + +# Xml config files +[*.{props,targets,config,nuspec}] +indent_size = 2 + +# YAML config files +[*.{yml,yaml}] +indent_size = 2 + +# Shell scripts +[*.sh] +end_of_line = lf +[*.{cmd,bat}] +end_of_line = crlf + +[*.{cs,vb}] +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_operator_placement_when_wrapping = beginning_of_line +tab_width = 4 +indent_size = 4 +end_of_line = crlf +dotnet_style_prefer_collection_expression = true:suggestion \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..a57a77c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,54 @@ +# Auto detect text files +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.vb diff=csharp +*.fs diff=csharp +*.fsi diff=csharp +*.fsx diff=csharp + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain + +# LFS +*.png binary +*.jpg binary +*.tga binary +*.psd binary +*.gif binary +*.docx binary +*.pptx binary +*.bin binary +*.exe binary +test/Verifiable.FuzzTests/libfuzzer-dotnet-ubuntu binary +*.gz filter=lfs diff=lfs merge=lfs -text +*.jffs2 filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.a filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.exe filter=lfs diff=lfs merge=lfs -text +*.apk filter=lfs diff=lfs merge=lfs -text +*.avi filter=lfs diff=lfs merge=lfs -text +*.chm filter=lfs diff=lfs merge=lfs -text +*.mp4 filter=lfs diff=lfs merge=lfs -text +*.wma filter=lfs diff=lfs merge=lfs -text +*.ldf filter=lfs diff=lfs merge=lfs -text +*.mdf filter=lfs diff=lfs merge=lfs -text +*.mp4 filter=lfs diff=lfs merge=lfs -text +*.mp3 filter=lfs diff=lfs merge=lfs -text +*.wav filter=lfs diff=lfs merge=lfs -text +*.myo filter=lfs diff=lfs merge=lfs -text +*.vsmdi filter=lfs diff=lfs merge=lfs -text +*.vsmdi filter=lfs diff=lfs merge=lfs -text + + diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..7ca1035 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,11 @@ +# https://help.github.com/articles/about-codeowners/ + +# These owners will be the default owners for everything in +# the repo. Unless a later match takes precedence, they will +# be requested for review when someone opens a PR. +* @veikkoeeva + +# Order is important; the last matching pattern takes the most +# precedence. When someone opens a PR that only modifies +# .yml files, only the following people and NOT the global +# owner(s) will be requested for a review. \ No newline at end of file diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..d7ade82 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,84 @@ + +# Contributor Covenant Code of Conduct + +## 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 e-mail 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][homepage], version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..d386b79 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,192 @@ +# Contributing Guidelines + +*Issues, pull requests, bug reports, stars and all other forms of contribution are welcomed and much appreciated!* + +### Contents + +- [Code of Conduct](#book-code-of-conduct) +- [Asking Questions](#bulb-asking-questions) +- [Opening an Issue](#inbox_tray-opening-an-issue) +- [Feature Requests](#love_letter-feature-requests) +- [Triaging Issues](#mag-triaging-issues) +- [Submitting Pull Requests](#repeat-submitting-pull-requests) +- [Writing Commit Messages](#memo-writing-commit-messages) +- [Code Review](#white_check_mark-code-review) +- [Coding Style](#nail_care-coding-style) +- [Certificate of Origin](#medal_sports-certificate-of-origin) +- [Credits](#pray-credits) + +> **This guide sets expectations for everyone involved with this project. This way we can improve it together while also creating a welcoming space for everyone to participate. Following these guidelines will help ensure a positive experience for contributors and maintainers. If you come up with improvement, like a more positive tone or point of view, please do open an issue and do tell.** + +## :book: Code of Conduct + +Please review our [Code of Conduct](CODE_OF_CONDUCT.md). It is in effect at all times. We expect it to be honored by everyone who contributes to this project. + +## :bulb: Asking Questions + +See our [Support Guide](SUPPORT.md). + +## :inbox_tray: Opening an Issue + +Before [creating an issue](https://help.github.com/en/github/managing-your-work-on-github/creating-an-issue), check if you are using the latest version of the project. If you are not up-to-date, see if updating fixes your issue first. Also note this software is still in alpha phase. + +### :lock: Reporting Security Issues + +Review our [Security Policy](SECURITY.md). + +### :beetle: Bug Reports and Other Issues + +A great way to contribute to the project is to send a detailed issue when you encounter a problem. We always appreciate a well-written, thorough bug report. :v: + +If you are a developer, **provide a ticket that you would like to receive**. + +- **Review the documentation and [Support Guide](SUPPORT.md)** before opening a new issue. + +- **Do not open a duplicate issue!** Please, search existing issues to see if your issue has previously been reported. If your issue exists, comment with any additional information you have. You may simply note "I have this problem too", which helps prioritize the most common problems and requests. + +- **Prefer using [reactions](https://github.blog/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/)**, not comments (e.g. no "+1" comments). + +- **Fully complete the provided issue template.** The bug report template requests all the information we need to quickly and efficiently address your issue. Be clear, concise, and descriptive. Provide as much information as you can, including steps to reproduce, stack traces, compiler errors, library versions, OS versions, and screenshots (if applicable). + +- **Use [GitHub-flavored Markdown](https://help.github.com/en/github/writing-on-github/basic-writing-and-formatting-syntax).** Especially put code blocks and console outputs in backticks (```). + +## :love_letter: Feature Requests + +Feature requests are apprciated and welcome! While we will consider all requests, we cannot guarantee your request will be accepted. We want to avoid [feature creep](https://en.wikipedia.org/wiki/Feature_creep). Your idea may be great, but also out-of-scope for the project. If accepted, we cannot make any commitments regarding the timeline for implementation and release. However, you are welcome to submit a pull request to help! + +- **Do not open a duplicate feature request.** Search for existing feature requests first. If you find your feature (or one very similar) previously requested, comment on that issue. + +- **Fully complete the provided issue template.** The feature request template asks for all necessary information for us to begin a productive conversation. + +- Be precise about the proposed outcome of the feature and how it relates to existing features. Include implementation details if possible. + +## :mag: Triaging Issues + +You can triage issues which may include reproducing bug reports or asking for additional information, such as version numbers or reproduction instructions. Any help you can provide to quickly resolve an issue is much appreciated! + +## :repeat: Submitting Pull Requests + +We **love** pull requests! Before [forking the repo](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) and [creating a pull request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/proposing-changes-to-your-work-with-pull-requests) for non-trivial changes, it is usually best to first open an issue to discuss the changes, or discuss your intended approach for solving the problem in the comments for an existing issue. + +For most contributions, after your first pull request is accepted and merged, you will be [invited to the project](https://help.github.com/en/github/setting-up-and-managing-your-github-user-account/inviting-collaborators-to-a-personal-repository) and given **push access**. :tada: + +*Note: All contributions will be licensed under the project's license.* + +- **Smaller is better.** Submit **one** pull request per bug fix or feature. A pull request should contain isolated changes pertaining to a single bug fix or feature implementation. **Do not** refactor or reformat code that is unrelated to your change. It is better to **submit many small pull requests** rather than a single large one. Enormous pull requests will take enormous amounts of time to review, or may be rejected altogether. + +- **Coordinate bigger changes.** For large and non-trivial changes, open an issue to discuss a strategy with the maintainers. Otherwise, you risk doing a lot of work for nothing! + +- **Prioritize understanding over cleverness.** Source code usually gets written once and read often. The purpose and logic should be obvious to a reasonably skilled developer, otherwise you should add a comment that explains it. It is all right and encouraged to add comments to code based on review and other discussions. + +- **Follow existing coding style and conventions.** Keep your code consistent with the style, formatting, and conventions in the rest of the code base. When possible, these will be enforced with a linter. Consistency makes it easier to review and modify in the future. + +- **Include test coverage.** Add unit tests or UI tests when possible. Follow existing patterns for implementing tests. + +- **Update the example project** if one exists to exercise any new functionality you have added. + +- **Add documentation.** Document your changes with code doc comments or in existing guides. + +- **Update the CHANGELOG** for all enhancements and bug fixes. Include the corresponding issue number if one exists, and your GitHub username. (example: "- Fixed crash in profile view. #123 @jessesquires") + +- **Use the repo's default branch.** Branch from and [submit your pull request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork) to the repo's default branch (`main`). + +- **[Resolve any merge conflicts](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github)** that occur. + +- **Address CI failures**. If your pull request fails to build or pass tests, please push another commit to fix it. It is OK if it takes a while to do so or requires some team work. + +- When writing comments, use properly constructed sentences, including punctuation. + + +## :memo: Writing Commit Messages + +Please [write a great commit message](https://chris.beams.io/posts/git-commit/). + +1. Separate subject from body with a blank line +2. Limit the subject line to 50 characters +3. Capitalize the subject line +4. Do not end the subject line with a period +5. Use the imperative mood in the subject line (example: "Fix networking issue") +6. Wrap the body at about 72 characters +7. Use the body to explain **why**, *not what and how* (the code shows that!) +8. If applicable, prefix the title with the relevant component name. (examples: "[Docs] Fix typo", "[Profile] Fix missing avatar") + +``` +[TAG] Short summary of changes in 50 chars or less + +Add a more detailed explanation here, if necessary. Possibly give +some background about the issue being fixed, etc. The body of the +commit message can be several paragraphs. Further paragraphs come +after blank lines and please do proper word-wrap. + +Wrap it to about 72 characters or so. In some contexts, +the first line is treated as the subject of the commit and the +rest of the text as the body. The blank line separating the summary +from the body is critical (unless you omit the body entirely); +various tools like `log`, `shortlog` and `rebase` can get confused +if you run the two together. + +Explain the problem that this commit is solving. Focus on why you +are making this change as opposed to how or what. The code explains +how or what. Reviewers and your future self can read the patch, +but might not understand why a particular solution was implemented. +Are there side effects or other unintuitive consequences of this +change? Here's the place to explain them. + + - Bullet points are okay, too + + - A hyphen or asterisk should be used for the bullet, preceded + by a single space, with blank lines in between + +Note the fixed or relevant GitHub issues at the end: + +Resolves: #123 +See also: #456, #789 +``` + +## :white_check_mark: Code Review + +- **Review the code, not the author.** Look for and suggest improvements without disparaging or insulting the author. Provide actionable feedback and explain your reasoning. + +- **You are not your code.** When your code is critiqued, questioned, or constructively criticized, remember that you are not your code. Do not take code review personally. + +- **Make at least for a reasonably good effort.** No one writes bugs on purpose. Good effort should be enough nobody's at their best all the time). + +- Kindly note any violations to the guidelines specified in this document. + +## :nail_care: Coding Style + +Please, follow the existing style, formatting, and naming conventions of the file you are modifying and of the overall project. If you are new to .NET, [C# Coding Conventions](https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions) and linters helps here. This can also be fixed in review and even after merge. This way reviewing is easier and can focus more on improving its functionality and performance. + +For example, if all private properties are prefixed with an underscore `_`, then new ones you add should be prefixed in the same way. Or, if methods are named using camelcase, like `thisIsMyNewMethod`, then do not diverge from that by writing `this_is_my_new_method`. You get the idea. If in doubt, please ask or search the codebase for something similar. + +When possible, style and format will be enforced with a linter. + +## :medal_sports: Certificate of Origin + +*Developer's Certificate of Origin 1.1* + +By making a contribution to this project, I certify that: + +> 1. The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or +> 2. The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or +> 3. The contribution was provided directly to me by some other person who certified (1), (2) or (3) and I have not modified it. +> 4. I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. + +## [No Brown M&M's](https://en.wikipedia.org/wiki/Van_Halen#Contract_riders) + +If you are reading this, bravo dear user and (hopefully) contributor for making it this far! You are awesome. :100: + +## :pray: Credits + +This considers [GitHub Minimum Viable Governance](https://github.com/github/MVG) and is adapted from [@jessesquires](https://github.com/jessesquires), who in turn writes: + +> **Please feel free to adopt this guide in your own projects. Fork it wholesale or remix it for your needs.** +> +> *Many of the ideas and prose for the statements in this document were based on or inspired by work from the following communities:* +> +> - [Alamofire](https://github.com/Alamofire/Alamofire/blob/master/CONTRIBUTING.md) +> - [CocoaPods](https://github.com/CocoaPods/CocoaPods/blob/master/CONTRIBUTING.md) +> - [Docker](https://github.com/moby/moby/blob/master/CONTRIBUTING.md) +> - [Linux](https://elinux.org/Developer_Certificate_Of_Origin) +> +> *We commend them for their efforts to facilitate collaboration in their projects.* \ No newline at end of file diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..51f48b9 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,15 @@ +# Security Policy + +If you discover a security issue, please open an issue about it. + +## Reporting a Vulnerability + +This project is still in pre-alpha. + +## Supported Versions + +There are currently no supported versions. + +## Useful security standards + +[NIST: Recommended Minimum Standard for Vendor or Developer Verification of Code](https://www.nist.gov/itl/executive-order-improving-nations-cybersecurity/recommended-minimum-standard-vendor-or-developer). \ No newline at end of file diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md new file mode 100644 index 0000000..c76bd5b --- /dev/null +++ b/.github/SUPPORT.md @@ -0,0 +1,31 @@ +# Support and Help + +This project is still in alpha phase. + +## How to get help + +We do not use GitHub as a support forum general questions or questions specific to your particular project. Asking on [Stack Overflow](https://stackoverflow.com) or other forums, such as [TPM.DEV](https://developers.tpm.dev/), are better for these questions. By doing so, you are more likely to quickly solve your problem, and you will allow anyone else with the same question to find the answer. This also allows maintainers to focus on improving the project for others. + +Please seek support in the following ways: + +1. :book: **Read the documentation and other guides** for the project to see if you can figure it out on your own. These should be located in a root `docs/` directory. If there is an example project, explore that to learn how it works to see if you can answer your question. + +1. :bulb: **Search for answers and ask questions on [Stack Overflow](https://stackoverflow.com).** This is the most appropriate place for debugging issues specific to your use of the project, or figuring out how to use the project in a specific way. + +1. :memo: As a **last resort**, you may open an issue on GitHub to ask for help. However, please clearly explain what you are trying to do, and list what you have already attempted to solve the problem. Provide code samples, but **do not** attach your entire project for someone else to debug. Review our [contributing guidelines](CONTRIBUTING.md). + +## What NOT to do + +Please **do not** do any the following: + +1. :x: Do not reach out to authors or contributors on Twitter (or other social media) by tweeting or sending a direct message. + +1. :x: Do not email the authors or contributors. + +1. :x: Do not open duplicate issues or litter an existing issue with +1's. + +These are not appropriate avenues for seeking help or support with an open-source project. Please follow the guidelines in the previous section. Public questions get public answers, which benefits everyone in the community. ✌️ + +## Customer Support + +There is no any sort of customer support for this project on behalf of Lumoin currently. Consulting is possible. One place to contact for hardware specific consultation could be [TPM.DEV](https://developers.tpm.dev/). \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..be0b86f --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,30 @@ +# See more at +# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: nuget + directory: '/' + schedule: + interval: daily + time: '05:00' + timezone: Etc/GMT + labels: + - dependencies + commit-message: + prefix: ci + prefix-development: chore + include: scope + + - package-ecosystem: github-actions + directory: '/' + schedule: + interval: daily + time: '05:00' + timezone: Etc/GMT + labels: + - dependencies + commit-message: + prefix: ci + prefix-development: chore + include: scope \ No newline at end of file diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..07a9d62 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,55 @@ +name: "CoreLoop CodeQL analysis" + +on: + workflow_dispatch: + push: + branches: + - main + - develop + # pull_request: + # branches: + # - main + # paths-ignore: + # - "**.md" + schedule: + # A daily build to check all is still functioning. + - cron: "0 0 * * *" + +jobs: + analyze: + name: CodeQL Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + os: [ ubuntu-latest, windows-latest, macos-latest ] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: 'csharp' + build-mode: none + queries: security-and-quality + + - uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 + with: + global-json-file: global.json + + - name: Autobuild + if: ${{ github.actor != 'dependabot[bot]' }} + uses: github/codeql-action/autobuild@v3 + + - name: CodeQL Analysis + if: ${{ github.actor != 'dependabot[bot]' }} + uses: github/codeql-action/analyze@v3 + timeout-minutes: 100 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..0573468 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,346 @@ +name: CoreLoop .NET build + +on: + workflow_dispatch: + push: + branches: + - main + pull_request: + paths-ignore: + - "**.md" + release: + types: + - published + + schedule: + # A daily build to check all is still functioning. + - cron: "0 0 * * *" + +env: + # This environment variable is checked in tests. + # For TPM either a Windows simulator or a platform TPM is used. + # Tests check that platform TPM tests must be run on Windows or Linux, + # MacOS tests are skipped. + USE_PLATFORM_TPM: true + + DOTNET_ENVIRONMENT: CI + BUILD_CONFIGURATION: Release + DOTNET_CLI_TELEMETRY_OPTOUT: true + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + DOTNET_NOLOGO: true + NUGET_XMLDOC_MODE: skip + NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages + NUGET_FEED: https://api.nuget.org/v3/index.json + GITHUB_USER: ${{ github.repository_owner }} + GITHUB_FEED: https://nuget.pkg.github.com/lumoin/ + + # These are the Nuget packages that will be packed and uploaded. + CORELOOP_UNTP: CoreLoop.Untp + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ ubuntu-latest, windows-latest, macos-latest ] + + steps: + + - name: Harden Runner + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde + with: + disable-sudo: true + egress-policy: block + allowed-endpoints: > + dotnetbuilds.azureedge.net:443 + aka.ms:443 + api.github.com:443 + api.nuget.org:443 + pkgs.dev.azure.com:443 + dashboard.stryker-mutator.io:443 + dotnetcli.azureedge.net:443 + github.com:443 + nuget.pkg.github.com:443 + api.clearlydefined.io:443 + cacerts.digicert.com:80 + ts-crl.ws.symantec.com:80 + crl3.digicert.com:80 + crl4.digicert.com:80 + s.symcb.com:80 + ocsp.digicert.com:80 + + # Windows builds may have insufficient resource limits, so they're increased. + - name: Configure Windows Pagefile + if: ${{ matrix.os == 'windows-latest' }} + uses: al-cheb/configure-pagefile-action@a3b6ebd6b634da88790d9c58d4b37a7f4a7b8708 + with: + minimum-size: 8GB + maximum-size: 32GB + disk-root: "D:" + + - name: Checkout code + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + with: + fetch-depth: 0 + fetch-tags: true + + - name: Cache Nuget packages '${{ matrix.os }}' + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 + with: + path: ${{ env.NUGET_PACKAGES }} + key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }} + restore-keys: | + ${{runner.os}}-nuget- + + - name: Setup .NET SDK + uses: actions/setup-dotnet@6bd8b7f7774af54e05809fcc5431931b3eb1ddee + with: + global-json-file: global.json + + - name: Install dependencies + run: dotnet restore --locked-mode + + - name: Restore local .NET tools + run: dotnet tool restore + + - name: Add Problem Matcher for dotnet-format + uses: xt0rted/dotnet-format-problem-matcher@b90c4f18e3daa4f8fd266e41eba4f351b2e00b75 + + # - name: Run dotnet format + # run: dotnet format --check + + # The version numbers are determined and set here so it can be set appropriately to code and NuGet packages. + # See explanation at https://dusted.codes/github-actions-for-dotnet-core-nuget-packages. + - name: Set NuGet packages and suffix version + run: | + # Bash script to determine the version and version suffix for CI/CD + # Use git to find the latest tag; if none are found, default to "0.0.1". + latestTag=$(git describe --tags --abbrev=0 2>/dev/null || echo 0.0.1) + + # Case 1: A release is being created. + # Extract the version from the tag and add a suffix with the short SHA. + if [[ $GITHUB_EVENT_NAME == 'release' ]]; then + # Extract the version number from the release tag and remove any 'v' prefix. + arrTag=(${GITHUB_REF//\// }) + VERSION="${arrTag[2]}" + VERSION="${VERSION//v}" + # Set PACKAGE_VERSION and VERSION, and add a VERSION_SUFFIX for clarity in identifying the release and commit. + echo "PACKAGE_VERSION=${VERSION}+${GITHUB_SHA::7}" >> "$GITHUB_ENV" + echo "VERSION=${VERSION}" >> "$GITHUB_ENV" + echo "TAG_VERSION=${VERSION}" >> "$GITHUB_ENV" + + # Case 2: The 'develop' branch. + # Use the latestTag as the base version and add a suffix with "develop", the run_id, and the short SHA. + elif [[ $GITHUB_REF == 'refs/heads/develop' ]]; then + # Set PACKAGE_VERSION and PACKAGE, and add a VERSION_SUFFIX for clarity in identifying the development build, run, and commit. + echo "PACKAGE_VERSION=${latestTag//v}-develop.${GITHUB_RUN_ID}+${GITHUB_SHA::7}" >> "$GITHUB_ENV" + echo "VERSION=${latestTag//v}-develop.${GITHUB_RUN_ID}+${GITHUB_SHA::7}" >> "$GITHUB_ENV" + echo "TAG_VERSION=${latestTag//v}" >> "$GITHUB_ENV" + + # Case 3: Any other build (e.g., feature branches). + # Use the latestTag as the base version and add a suffix with "build", the run_id, and the short SHA. + else + # Set PACKAGE_VERSION and VERSION, and add a VERSION_SUFFIX for clarity in identifying the build, run, and commit. + echo "PACKAGE_VERSION=${latestTag//v}-build.${GITHUB_RUN_ID}+${GITHUB_SHA::7}" >> "$GITHUB_ENV" + echo "VERSION=${latestTag//v}-build.${GITHUB_RUN_ID}+${GITHUB_SHA::7}" >> "$GITHUB_ENV" + echo "TAG_VERSION=${latestTag//v}" >> "$GITHUB_ENV" + fi + shell: bash + + - name: Build + # At the moment CoreLoop.Tests cannot be built with -isolate alone due to Coverlet. + run: dotnet build --binaryLogger --tl --graphBuild -isolate:MessageUponIsolationViolation --configuration ${{ env.BUILD_CONFIGURATION }} --no-restore --property:ContinuousIntegrationBuild=true --property:Version=${{ env.VERSION }} --property:InformationalVersion=${{ env.PACKAGE_VERSION }} --property:AssemblyVersion=${{ env.TAG_VERSION }} --property:FileVersion=${{ env.TAG_VERSION }} + timeout-minutes: 5 + + # - name: Set PR markdown title name + # run: | + # echo "title=Test Run (${{ github.run_number }})" >> $GITHUB_ENV + # echo "file_name=TestReport.${{ github.run_number }}.md" >> $GITHUB_ENV + # shell: bash + + - name: Test + # See the difference on drivers and paths at https://github.com/microsoft/vstest/issues/2378 and further + # here on generating the reports. + # run: dotnet test --verbosity normal --no-restore --no-build --configuration ${{ env.BUILD_CONFIGURATION }} --property:CollectCoverage=true --property:CoverletOutputFormat=cobertura --property:DeterministicSourcePaths=true --property:IncludeTestAssembly=true --property:CoverletOutput='${{ github.workspace }}/reports/coverage/' + run: dotnet test --collect:"XPlat Code Coverage" --verbosity normal --no-restore --no-build --configuration ${{ env.BUILD_CONFIGURATION }} --logger JUnit -property:DeterministicSourcePaths=true -property:IncludeTestAssembly=true --results-directory '${{ github.workspace }}/reports/coverage/' + timeout-minutes: 5 + + # Mutation tests skipped for now due to CI limits and temporarily reduced test coverage... + # This either requires cd to test directory or --solution-path CoreLoop.sln (which may not work). + # - name: Stryker.NET mutation Tests for CoreLoop.Untp.csproj + # if: ${{ matrix.os == 'ubuntu-latest' }} + # run: dotnet stryker --config-file stryker-config.json --reporter progress --reporter html --reporter dashboard --dashboard-api-key ${{ secrets.STRYKER_API_KEY }} --project CoreLoop.UNTransparencyProtocol.csproj + # timeout-minutes: 15 + + #- name: Upload Stryker output artefacts + # if: ${{ matrix.os == 'ubuntu-latest' }} + # uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a + # with: + # name: 'Stryker output artefacts' + # path: ${{ github.workspace }}/StrykerOutput/ + + # - name: Publish + # run: dotnet publish -c Release --verbosity normal -o ./publish/ + + # - name: Archive publish results + # uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a + # with: + # name: CoreLoop.Benchmarks + # path: ./publish/* + + # - name: Run Benchmarks + # run: dotnet "./publish/CoreLoop.Benchmarks.dll" -f "CoreLoop.Benchmarks.*" + + # - name: Upload benchmark results + # uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a + # with: + # name: Benchmark_Results + # path: ./BenchmarkDotNet.Artifacts/results/* + + # This step is run always (e.g. also for non-PRs) so the results can be inspected on the command line too. + # - name: ReportGenerator + # if: ${{ matrix.os == 'ubuntu-latest' }} + + # If not using MSBuild driver but the VSTest one, the files need to be explicitly found due to randomized path segmenets. + # See more at https://github.com/microsoft/vstest/issues/2378. + # run: dotnet reportgenerator -assemblyfilters:'-xunit*' -reports:'${{ github.workspace }}/reports/coverage/coverage.cobertura.xml' -targetdir:'${{ github.workspace }}/reports/coverage/' -reporttypes:'HtmlInline;Cobertura;MarkdownSummary' + # run: dotnet reportgenerator -assemblyfilters:'-xunit*' -reports:`find ${{ github.workspace }}/reports/coverage/ -name coverage.cobertura.xml` -targetdir:'${{ github.workspace }}/reports/coverage/' -reporttypes:'HtmlInline;Cobertura;MarkdownSummary' + + # - name: Publish coverage report + # if: ${{ matrix.os == 'ubuntu-latest' }} + # uses: 5monkeys/cobertura-action@master + # with: + # path: '${{ github.workspace }}/reports/coverage/Cobertura.xml' + # repo_token: ${{ secrets.GITHUB_TOKEN }} + # minimum_coverage: 75 + + - name: Publish coverage summary + if: ${{ matrix.os == 'ubuntu-latest' && github.event_name == 'pull_request' && github.actor != 'dependabot[bot]' }} + uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31 + with: + header: Report + path: '${{ github.workspace }}/reports/coverage/Summary.md' + recreate: true + + - name: Create test summary + if: ${{ matrix.os == 'ubuntu-latest' && github.event_name == 'pull_request' && github.actor != 'dependabot[bot]' }} + uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 + with: + paths: '${{ github.workspace }}/reports/coverage/TestResults.xml' + # output: '${{ github.workspace }}/${{ env.file_name }}' + + # - name: Comment PR with the generated test Markdown + # if: ${{ matrix.os == 'ubuntu-latest' && github.event_name == 'pull_request' && github.actor != 'dependabot[bot]' }} + # uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31 + # with: + # path: ${{ env.file_name }} + + # - name: Upload PR build information artefact + # if: ${{ matrix.os == 'ubuntu-latest' && github.event_name == 'pull_request' && github.actor != 'dependabot[bot]' }} + # uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a + # with: + # name: 'Test Run' + # path: ${{ github.workspace }}/${{ env.file_name }} + + # - name: Comment PR with the generated test Markdown + # if: ${{ matrix.os == 'ubuntu-latest' }} + # uses: machine-learning-apps/pr-comment@78e77cd435e0f9706512ea294d846058ae46f7ff + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # with: + # path: ${{ env.file_name }} + + # - name: The sbom-tool does not generate the output directory and fails if it not present. + - name: Create SBOM output directory + run: mkdir -p "${{ github.workspace }}/${{ matrix.os }}/sbom/" + + # There may a difference in libraries between platforms, so the tool is being run on all platforms. + - name: Run BOM analysis + run: dotnet tool run sbom-tool generate -DeleteManifestDirIfPresent true -BuildDropPath "${{ github.workspace }}/${{ matrix.os }}/sbom/" -FetchLicenseInformation true -EnablePackageMetadataParsing true -BuildComponentPath . -PackageName "CoreLoop" -PackageSupplier "Lumoin" -NamespaceUriBase "https://lumoin.com/coreloop" -PackageVersion ${{ env.PACKAGE_VERSION }} -Verbosity Verbose + + - name: Pack NuGet files + if: ${{ matrix.os == 'ubuntu-latest' }} + run: | + dotnet pack --verbosity normal --configuration ${{ env.BUILD_CONFIGURATION }} --no-build --output nupkgs --property:PackageVersion=$PACKAGE_VERSION src/$CORELOOP_UNTP/$CORELOOP_UNTP.*proj + + # Note that on Windows this would be simply "dotnet dotnet-validate package local ./snupkgs/*.nupkg", the handling of an array of paths works directly. + - name: Validate generated NuGet files + if: ${{ matrix.os == 'ubuntu-latest' }} + run: | + for file in ./nupkgs/*.nupkg; do + dotnet dotnet-validate package local "$file" + done + + - name: Upload CoreLoop NuGet packages + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a + with: + name: nupkg + path: ./nupkgs/*.* + + # The release idea is inspired by https://dusted.codes/github-actions-for-dotnet-core-nuget-packages. + prerelease: + permissions: + # For setup-dotnet to create package. + packages: write + needs: build + if: ${{ github.ref == 'refs/heads/develop' && github.repository_owner == 'lumoin' }} + runs-on: ubuntu-latest + steps: + - name: Harden Runner + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde + with: + disable-sudo: true + egress-policy: block + allowed-endpoints: > + aka.ms:443 + api.github.com:443 + api.nuget.org:443 + dashboard.stryker-mutator.io:443 + dotnetcli.azureedge.net:443 + github.com:443 + nuget.pkg.github.com:443 + api.clearlydefined.io:443 + + - name: Download NuGet artifacts + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 + with: + name: nupkg + + - name: Push to GitHub developer feed + run: dotnet nuget push "**/*.nupkg" --source $GITHUB_FEED --api-key ${{ secrets.GITHUB_TOKEN }} --skip-duplicate + + deploy: + permissions: + # For setup-dotnet to create package. + packages: write + needs: build + if: ${{ github.event_name == 'release' && github.repository_owner == 'lumoin' }} + runs-on: ubuntu-latest + steps: + - name: Harden Runner + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde + with: + disable-sudo: true + egress-policy: audit + allowed-endpoints: > + aka.ms:443 + api.github.com:443 + api.nuget.org:443 + dashboard.stryker-mutator.io:443 + dotnetcli.azureedge.net:443 + github.com:443 + nuget.pkg.github.com:443 + + - name: Download NuGet artifacts + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 + with: + name: nupkg + + - name: Push to GitHub developer feed + run: dotnet nuget push "**/*.nupkg" --source $GITHUB_FEED --api-key ${{ secrets.GITHUB_TOKEN }} --skip-duplicate + + - name: Push to NuGet feed + run: dotnet nuget push "**/*.nupkg" --source $NUGET_FEED --api-key ${{ secrets.NUGET_API_KEY }} --skip-duplicate diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6ac59f5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,370 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# 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/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Script result directories +sbom/ +generated-reports/ +generated-nugets/ + +# 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.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# Stryker test results +StrykerOutput/ + +# .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 +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.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_* +.*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 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 + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# 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 \ No newline at end of file diff --git a/BannedSymbols.txt b/BannedSymbols.txt new file mode 100644 index 0000000..b34f220 --- /dev/null +++ b/BannedSymbols.txt @@ -0,0 +1,2 @@ +P:System.DateTime.Now;Use System.DateTime.UtcNow instead. +M:System.IO.File.GetCreationTime(System.String);Use GetCreationTimeUtc instead. \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e8adc60 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,20 @@ +# Change Log + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/) +and this project adheres to [Semantic Versioning](http://semver.org/). + + + +## [Unreleased] + +## [0.0.0.0] - 2024-09-01 + diff --git a/CoreLoop.sln b/CoreLoop.sln new file mode 100644 index 0000000..d0db63c --- /dev/null +++ b/CoreLoop.sln @@ -0,0 +1,81 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35209.166 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoreLoop.Untp", "src\CoreLoop.Untp\CoreLoop.Untp.csproj", "{797BE3F2-DF9D-4186-BFE1-E05475FAD5B3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{19BA6154-3246-4F4B-94DA-F11D1E9E7FD6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{22E2F94D-0070-4D47-8E5A-DF82B3579678}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoreLoop.Tests", "test\CoreLoop.Tests\CoreLoop.Tests.csproj", "{16F6E4DA-18F2-46CE-8806-1F85598D3936}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{ECFBA01C-5FE9-46E8-8CCF-AC458C56F7DB}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + .gitattributes = .gitattributes + .gitignore = .gitignore + BannedSymbols.txt = BannedSymbols.txt + CHANGELOG.md = CHANGELOG.md + create-nugets.ps1 = create-nugets.ps1 + Directory.Build.props = Directory.Build.props + Directory.Packages.props = Directory.Packages.props + generate-sbom.ps1 = generate-sbom.ps1 + global.json = global.json + LICENSE = LICENSE + NuGet.config = NuGet.config + README.md = README.md + spellcheckerexclusion.dic = spellcheckerexclusion.dic + stryker-config.json = stryker-config.json + stryker-tests-dev.ps1 = stryker-tests-dev.ps1 + tests-with-reportgenerator.ps1 = tests-with-reportgenerator.ps1 + update-dotnet-tools.ps1 = update-dotnet-tools.ps1 + verify-packages.ps1 = verify-packages.ps1 + verify-packages.sh = verify-packages.sh + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{054F4985-1C55-407D-AC57-96A79366CA41}" + ProjectSection(SolutionItems) = preProject + .github\CODEOWNERS = .github\CODEOWNERS + .github\CODE_OF_CONDUCT.md = .github\CODE_OF_CONDUCT.md + .github\CONTRIBUTING.md = .github\CONTRIBUTING.md + .github\dependabot.yml = .github\dependabot.yml + .github\SECURITY.md = .github\SECURITY.md + .github\SUPPORT.md = .github\SUPPORT.md + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{A245F1E1-7ECF-4664-BFC2-4EB1094F0E09}" + ProjectSection(SolutionItems) = preProject + .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml + .github\workflows\main.yml = .github\workflows\main.yml + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {797BE3F2-DF9D-4186-BFE1-E05475FAD5B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {797BE3F2-DF9D-4186-BFE1-E05475FAD5B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {797BE3F2-DF9D-4186-BFE1-E05475FAD5B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {797BE3F2-DF9D-4186-BFE1-E05475FAD5B3}.Release|Any CPU.Build.0 = Release|Any CPU + {16F6E4DA-18F2-46CE-8806-1F85598D3936}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {16F6E4DA-18F2-46CE-8806-1F85598D3936}.Debug|Any CPU.Build.0 = Debug|Any CPU + {16F6E4DA-18F2-46CE-8806-1F85598D3936}.Release|Any CPU.ActiveCfg = Release|Any CPU + {16F6E4DA-18F2-46CE-8806-1F85598D3936}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {797BE3F2-DF9D-4186-BFE1-E05475FAD5B3} = {19BA6154-3246-4F4B-94DA-F11D1E9E7FD6} + {16F6E4DA-18F2-46CE-8806-1F85598D3936} = {22E2F94D-0070-4D47-8E5A-DF82B3579678} + {054F4985-1C55-407D-AC57-96A79366CA41} = {ECFBA01C-5FE9-46E8-8CCF-AC458C56F7DB} + {A245F1E1-7ECF-4664-BFC2-4EB1094F0E09} = {054F4985-1C55-407D-AC57-96A79366CA41} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7B04A0D7-B0EF-438C-89BC-66A7A96BD1C2} + EndGlobalSection +EndGlobal diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..9b2f5ec --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,105 @@ + + + + net9.0 + preview + disable + true + true + true + low + all + $(NoWarn);1591 + true + true + true + + + + + + + + $(AssemblyName) + Lumoin and contributors + CoreLoop + Apache-2.0 + false + Lumoin + resources/coreloop-nuget-logo.png + https://github.com/Lumoin/CoreLoop + Lumoin + true + https://github.com/Lumoin/CoreLoop + git + true + snupkg + + + 0.0.0 + 0.0.0 + 0.0.0 + 0.0.0 + 0.0.0 + en-US + + + + + ../../CHANGELOG.md + + + + + + + + + + + + + + + + + + + True + /resources + + + + diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 0000000..844d5d0 --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,22 @@ + + + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..dc24dac --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2014 Sedat Kapanoglu + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/NuGet.config b/NuGet.config new file mode 100644 index 0000000..f39add3 --- /dev/null +++ b/NuGet.config @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + AnthonyLloyd;pshkarin;Microsoft;9ee1;commandlineparser;DotLiquid;roastedamoeba;NightOwl888;FlorianRappl;wtfsck;zzzprojects;SharpDevelop;jedisct1;xoofx;ApacheLuceneNet;tssdotmsr;Microsoft;xunit;Coverlet;xUnit.net;dotnetfoundation;albi05;jd.cain.jr;joelhulen;aarnott;AndreyAkinshin;dotnetrdf;kurt;codito;kurtmkurtm;nsec;clairernovotny;Metalnem;sil-lsdev;sedatk;spectresystems;winsharpfuzz; + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..fbe6a95 --- /dev/null +++ b/README.md @@ -0,0 +1,82 @@ +CoreLoop project logo: Two green spirals interleaving and the empty space in the middle forming a human head like shape. There is an artistic eye with sun yellow upper eye-lashed and green-yellow lower eyelashes looking from the logo. It's the loop of energy, materials and vision and accountability. + +#### Data elements and functionality for various protocols and systems, sometimes used with [Verifiable](https://github.com/Lumoin/Verifiable) for digital signature and other protocols. + +![Main build workflow](https://github.com/Lumoin/CoreLoop/actions/workflows/main.yml/badge.svg) + +[![Mutation testing badge](https://img.shields.io/endpoint?style=for-the-badge&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2FLumoin%2FCoreLoop%2Fmain)](https://dashboard.stryker-mutator.io/reports/github.com/Lumoin/CoreLoop/main) + +
+ +## Features + +- Implements [United Nations Transparency Protocol (UNTP)](https://uncefact.github.io/spec-untp/) + +| Library | NuGet | +|---------------- | :------:| +| CoreLoop.UNTransparencyProtocol | [![NuGet](https://img.shields.io/nuget/v/CoreLoop.svg?style=flat)](https://www.nuget.org/packages/CoreLoop.UNTransparencyProtocol/) + + +
+ +### Quickly about practicalities + +Please, open an issue if you have a suggestion, improvement (e.g. even fixing a typo) or something in mind that could be useful and worth considering. + +Pressing **.** on keyboard on this repository page or when viewing any file to open this codebase in VS Code web editor is also a good way to get a feel of the code. + +Otherwise the usual things about forking and sending pull requests work too. :) + +#### This is an early version under development. All will be breaking. + + +
+ +CoreLoop's primary goal is to define and map data entities from various protocols, sustainability frameworks, and regulatory standards into workable code. This enables the development of dependable software systems that empower businesses and individuals to co-create sustainable, resilient, and accountable systems for a better future. + +Examples of these data entities and protocols include the [United Nations Transparency Protocol (UNTP)](https://uncefact.github.io/spec-untp/) and potentially frameworks such as the EU CSRS, both modeled within CoreLoop to facilitate transparent and responsible pathways for supply chain management and project finance. + +CoreLoop is designed to work with [Verifiable](https://github.com/Lumoin/Verifiable). + + +#### Quick links + +- [United Nations Transparency Protocol (UNTP)](https://uncefact.github.io/spec-untp/) +- [Verifiable](https://github.com/Lumoin/Verifiable/) + +
+ +## The design principles + +- **Agnostic to serialization and deserialization library.** The design principles for the data entities do not rely on specific deserialization and serialization (e.g. no library specific attributes on types) libraries. +- **Data oriented programming**. Or leaning towards it. The code is structured around the idea of parameters going in functions and results from return values. Or in more length: code is separate from (immutable) data, leaning generic data structures and general-purpose functions (extension methods and static methods). +- **Developer experience**. Writing against an evolving specification or some specific specifications can be difficult. It takes time to learn. So code should link in comments to W3C and RFCs where appropriate (see code for examples). +- **Tests and tests that use real data**. There should be as much tests as possible. Also tests that use as test vectors data from other implementations to cross-check.> + +## Vulnerability disclosure + +If you find a vulnerability in this project please let us know as soon as possibly. For secure disclosure, please see the [security policy](.github/SECURITY.md). + +## Contributing + +Please, read [contribution guidelines](.github/contributing.md) for technicalities. + +For development, the code and project should run on Windows, Linux and MacOS. Some hardware specific elements may work on only some operating systems. + +Taking something from contribution guide and adding specific ideas. + +### The usual things :) + +:eyes: Please, do write issues. + +:raised_hands: By all means, do create pull requests (see [contribution guidelines](.github/contributing.md)). + +:star: Stars are always nice. :) + +### The code things + +:white_check_mark: Adding tests is really good, of course. + +:thought_balloon: Issue templates and other improvements to project. + +:rocket: improve continuous integration automation is always good! diff --git a/create-nugets.ps1 b/create-nugets.ps1 new file mode 100644 index 0000000..5999b83 --- /dev/null +++ b/create-nugets.ps1 @@ -0,0 +1 @@ +dotnet pack --verbosity normal --configuration Release --output './generated-nugets' --include-symbols --include-source -property:PackageVersion=0.0.1 './src/CoreLoop.UNTransparencyProtocol/CoreLoop.UNTransparencyProtocol.csproj' \ No newline at end of file diff --git a/generate-sbom.ps1 b/generate-sbom.ps1 new file mode 100644 index 0000000..8e3bd0f --- /dev/null +++ b/generate-sbom.ps1 @@ -0,0 +1,3 @@ +Remove-Item "./sbom" -Recurse -Force -ErrorAction SilentlyContinue +New-Item -ItemType Directory -Force -Path "./sbom" +dotnet tool run sbom-tool generate -DeleteManifestDirIfPresent true -BuildDropPath "./sbom" -FetchLicenseInformation true -EnablePackageMetadataParsing true -BuildComponentPath . -PackageName "CoreLoop" -PackageSupplier "Lumoin" -NamespaceUriBase "https://lumoin.com/coreloop" -PackageVersion 1.0.0 -Verbosity Verbose \ No newline at end of file diff --git a/global.json b/global.json new file mode 100644 index 0000000..4e7602c --- /dev/null +++ b/global.json @@ -0,0 +1,9 @@ +{ + "sdk": { + "allowPrerelease": true, + "version": "9.0.100-rc.1.24452.12" + }, + "msbuild-sdks": { + "MSTest.Sdk": "3.5.2" + } +} \ No newline at end of file diff --git a/resources/coreloop-github-logo.svg b/resources/coreloop-github-logo.svg new file mode 100644 index 0000000..000d340 --- /dev/null +++ b/resources/coreloop-github-logo.svg @@ -0,0 +1,762 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/coreloop-nuget-logo.png b/resources/coreloop-nuget-logo.png new file mode 100644 index 0000000..4362f1a Binary files /dev/null and b/resources/coreloop-nuget-logo.png differ diff --git a/spellcheckerexclusion.dic b/spellcheckerexclusion.dic new file mode 100644 index 0000000..9effc72 --- /dev/null +++ b/spellcheckerexclusion.dic @@ -0,0 +1 @@ +Multicodec \ No newline at end of file diff --git a/src/CoreLoop.Untp/CoreLoop.Untp.csproj b/src/CoreLoop.Untp/CoreLoop.Untp.csproj new file mode 100644 index 0000000..08c3b1f --- /dev/null +++ b/src/CoreLoop.Untp/CoreLoop.Untp.csproj @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/CoreLoop.Untp/packages.lock.json b/src/CoreLoop.Untp/packages.lock.json new file mode 100644 index 0000000..8239964 --- /dev/null +++ b/src/CoreLoop.Untp/packages.lock.json @@ -0,0 +1,21 @@ +{ + "version": 2, + "dependencies": { + "net9.0": { + "SIL.ReleaseTasks": { + "type": "Direct", + "requested": "[2.6.0-beta0030, )", + "resolved": "2.6.0-beta0030", + "contentHash": "iytkRVZ7tEBY00kzB55Qs0/TyfYBJ0GyvRnDPKw2AfakBWrBBTkTCdBSAGmCFoL4Wf6asRFOrenRJ6VGGhCuUQ==", + "dependencies": { + "Markdig.Signed": "0.30.2" + } + }, + "Markdig.Signed": { + "type": "Transitive", + "resolved": "0.30.2", + "contentHash": "nQlUtPbp9pQFoArFSp/CZb699W6pqBG/DSpnWHgKbIuQjAu3KNjTZHaIir2vSCPJZuSMGii7tbI6K+nalh4X7w==" + } + } + } +} \ No newline at end of file diff --git a/stryker-config.json b/stryker-config.json new file mode 100644 index 0000000..d9ec6cc --- /dev/null +++ b/stryker-config.json @@ -0,0 +1,13 @@ +{ + "stryker-config": + { + "language-version": "preview", + "test-projects": ["test/CoreLoop.Tests/CoreLoop.Tests.csproj"], + "mutation-level": "Standard", + "ignore-methods": [ + "*Log*", + "ToString", + "*HashCode*" + ] + } +} \ No newline at end of file diff --git a/stryker-tests-dev.ps1 b/stryker-tests-dev.ps1 new file mode 100644 index 0000000..a995a11 --- /dev/null +++ b/stryker-tests-dev.ps1 @@ -0,0 +1 @@ +dotnet stryker --config-file stryker-config.json --reporter progress --reporter html --project CoreLoop.UNTransparencyProtocol.csproj \ No newline at end of file diff --git a/test/CoreLoop.Tests/CoreLoop.Tests.csproj b/test/CoreLoop.Tests/CoreLoop.Tests.csproj new file mode 100644 index 0000000..2823504 --- /dev/null +++ b/test/CoreLoop.Tests/CoreLoop.Tests.csproj @@ -0,0 +1,11 @@ + + + + + true + + + diff --git a/test/CoreLoop.Tests/UNTransparencyProtocolTests.cs b/test/CoreLoop.Tests/UNTransparencyProtocolTests.cs new file mode 100644 index 0000000..bebb763 --- /dev/null +++ b/test/CoreLoop.Tests/UNTransparencyProtocolTests.cs @@ -0,0 +1,14 @@ + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace CoreLoop.Tests +{ + [TestClass] + public class UNTransparencyProtocolTests + { + [TestMethod] + public void TestMethod1() + { + } + } +} diff --git a/test/CoreLoop.Tests/packages.lock.json b/test/CoreLoop.Tests/packages.lock.json new file mode 100644 index 0000000..e374f23 --- /dev/null +++ b/test/CoreLoop.Tests/packages.lock.json @@ -0,0 +1,223 @@ +{ + "version": 2, + "dependencies": { + "net9.0": { + "Microsoft.NET.Test.Sdk": { + "type": "Direct", + "requested": "[17.10.0, )", + "resolved": "17.10.0", + "contentHash": "0/2HeACkaHEYU3wc83YlcD2Fi4LMtECJjqrtvw0lPi9DCEa35zSPt1j4fuvM8NagjDqJuh1Ja35WcRtn1Um6/A==", + "dependencies": { + "Microsoft.CodeCoverage": "17.10.0", + "Microsoft.TestPlatform.TestHost": "17.10.0" + } + }, + "Microsoft.Testing.Extensions.CodeCoverage": { + "type": "Direct", + "requested": "[17.11.5, )", + "resolved": "17.11.5", + "contentHash": "YnYCianuMWuAZvYsQwvnfODw/uF9oMZrRcqPKpmYLJNL59zUA1MjNNgzfbiQ7mPazuVTxIVYej2Mod7V0LeITw==", + "dependencies": { + "Microsoft.DiaSymReader": "2.0.0", + "Microsoft.Extensions.DependencyModel": "6.0.0", + "Microsoft.Testing.Platform": "1.2.1", + "System.Reflection.Metadata": "6.0.1" + } + }, + "Microsoft.Testing.Extensions.TrxReport": { + "type": "Direct", + "requested": "[1.3.2, )", + "resolved": "1.3.2", + "contentHash": "0J6UfSnG3juySbQZgVUJCUlSrFEMKfgW2gq82VTR3F68RF9qogP2vdLFyLuw8XvIvrg+UZERDXjJgZxrd+1JWQ==", + "dependencies": { + "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.3.2", + "Microsoft.Testing.Platform": "1.3.2" + } + }, + "MSTest.Analyzers": { + "type": "Direct", + "requested": "[3.5.2, )", + "resolved": "3.5.2", + "contentHash": "03T/0UPMmkGHpYy0alpExoho6sRM6441P6sFTG3HrWhN+tfxWTkOddv3VUrtKOULgb2g22IJRk7mtD7l6tZpkg==" + }, + "MSTest.TestAdapter": { + "type": "Direct", + "requested": "[3.5.2, )", + "resolved": "3.5.2", + "contentHash": "jEgtMo1/Ih/h0/s+cp+o1prVPBWp/SIh1jfYQH8pK/kQlHMGbwjhnbj0E7kqx3Bn+tGzB6pgq8Im4rgXoLJETA==", + "dependencies": { + "Microsoft.Testing.Extensions.VSTestBridge": "1.3.2", + "Microsoft.Testing.Platform.MSBuild": "1.3.2" + } + }, + "MSTest.TestFramework": { + "type": "Direct", + "requested": "[3.5.2, )", + "resolved": "3.5.2", + "contentHash": "XDPIPvPWcbnyte0Oj0EzxMV38RIE925C0EtZCWXUfsho+QYqIv3LNjIZstG/JpamlhPHOQlfdrzc/FRF9lW5Ag==" + }, + "SIL.ReleaseTasks": { + "type": "Direct", + "requested": "[2.6.0-beta0030, )", + "resolved": "2.6.0-beta0030", + "contentHash": "iytkRVZ7tEBY00kzB55Qs0/TyfYBJ0GyvRnDPKw2AfakBWrBBTkTCdBSAGmCFoL4Wf6asRFOrenRJ6VGGhCuUQ==", + "dependencies": { + "Markdig.Signed": "0.30.2" + } + }, + "Markdig.Signed": { + "type": "Transitive", + "resolved": "0.30.2", + "contentHash": "nQlUtPbp9pQFoArFSp/CZb699W6pqBG/DSpnWHgKbIuQjAu3KNjTZHaIir2vSCPJZuSMGii7tbI6K+nalh4X7w==" + }, + "Microsoft.ApplicationInsights": { + "type": "Transitive", + "resolved": "2.22.0", + "contentHash": "3AOM9bZtku7RQwHyMEY3tQMrHIgjcfRDa6YQpd/QG2LDGvMydSlL9Di+8LLMt7J2RDdfJ7/2jdYv6yHcMJAnNw==", + "dependencies": { + "System.Diagnostics.DiagnosticSource": "5.0.0" + } + }, + "Microsoft.DiaSymReader": { + "type": "Transitive", + "resolved": "2.0.0", + "contentHash": "QcZrCETsBJqy/vQpFtJc+jSXQ0K5sucQ6NUFbTNVHD4vfZZOwjZ/3sBzczkC4DityhD3AVO/+K/+9ioLs1AgRA==" + }, + "Microsoft.Extensions.DependencyModel": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "TD5QHg98m3+QhgEV1YVoNMl5KtBw/4rjfxLHO0e/YV9bPUBDKntApP4xdrVtGgCeQZHVfC2EXIGsdpRNrr87Pg==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Encodings.Web": "6.0.0", + "System.Text.Json": "6.0.0" + } + }, + "Microsoft.Testing.Extensions.Telemetry": { + "type": "Transitive", + "resolved": "1.3.2", + "contentHash": "4LTMPKH6yPv6/3Khdr7rLkzDQZWZdD1om0LKF8KDe/dPYHtS49kmAEcqQCzirWxx2n2ZNNOjm6OwRTRgyWa/Dg==", + "dependencies": { + "Microsoft.ApplicationInsights": "2.22.0", + "Microsoft.Testing.Platform": "1.3.2" + } + }, + "Microsoft.Testing.Extensions.TrxReport.Abstractions": { + "type": "Transitive", + "resolved": "1.3.2", + "contentHash": "E1FFHRIDOOnEuTIQ6eLA+GvJsfqVW2PWpvfa5oxu5fzXtVi7QyOf8IWs5KFfTxOjnuENmJfb08t5quKvc1n6zg==", + "dependencies": { + "Microsoft.Testing.Platform": "1.3.2" + } + }, + "Microsoft.Testing.Extensions.VSTestBridge": { + "type": "Transitive", + "resolved": "1.3.2", + "contentHash": "MZzVIN5mocMHQyL4j8SGr2gnV01awTMi2Z+c001TARgLfBwI97WPONsHjxm9+fA4Fw6+8vJckksEHMe9gcF5tQ==", + "dependencies": { + "Microsoft.ApplicationInsights": "2.22.0", + "Microsoft.TestPlatform.ObjectModel": "17.10.0", + "Microsoft.Testing.Extensions.Telemetry": "1.3.2", + "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.3.2", + "Microsoft.Testing.Platform": "1.3.2" + } + }, + "Microsoft.Testing.Platform": { + "type": "Transitive", + "resolved": "1.3.2", + "contentHash": "zCBH5GDrHdZJpOFBEZHG2TBkoDpmcL05kv+rdIPGjQ5Ny+JeqWIjuGNu0IOtvxw9Xl0+lKbH1LSoXPG4hzQMnA==" + }, + "Microsoft.Testing.Platform.MSBuild": { + "type": "Transitive", + "resolved": "1.3.2", + "contentHash": "ZIws1LkCsgMkMD9zUa6fy4X8tBuwY25y30rcc/myUipiKL3HfJzEwto1vMtkcguCoVgkQfJTXQDIxEPJy8c+xg==", + "dependencies": { + "Microsoft.Testing.Platform": "1.3.2" + } + }, + "Microsoft.TestPlatform.ObjectModel": { + "type": "Transitive", + "resolved": "17.10.0", + "contentHash": "KkwhjQevuDj0aBRoPLY6OLAhGqbPUEBuKLbaCs0kUVw29qiOYncdORd4mLVJbn9vGZ7/iFGQ/+AoJl0Tu5Umdg==", + "dependencies": { + "System.Reflection.Metadata": "1.6.0" + } + }, + "Microsoft.TestPlatform.TestHost": { + "type": "Transitive", + "resolved": "17.10.0", + "contentHash": "LWpMdfqhHvcUkeMCvNYJO8QlPLlYz9XPPb+ZbaXIKhdmjAV0wqTSrTiW5FLaf7RRZT50AQADDOYMOe0HxDxNgA==", + "dependencies": { + "Microsoft.TestPlatform.ObjectModel": "17.10.0", + "Newtonsoft.Json": "13.0.1" + } + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.1", + "contentHash": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==" + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Collections.Immutable": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "l4zZJ1WU2hqpQQHXz1rvC3etVZN+2DLmQMO79FhOTZHMn8tDRr+WU287sbomD0BETlmKDn0ygUgVy9k5xkkJdA==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "tCQTzPsGZh/A9LhhA6zrqCRV4hOHsK90/G7q3Khxmn6tnB1PuNU0cRaKANP2AWcF9bn0zsuOoZOSrHuJk6oNBA==" + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==" + }, + "System.Reflection.Metadata": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "III/lNMSn0ZRBuM9m5Cgbiho5j81u0FAEagFX5ta2DKbljZ3T0IpD8j+BIiHQPeKqJppWS9bGEp6JnKnWKze0g==", + "dependencies": { + "System.Collections.Immutable": "6.0.0" + } + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==" + }, + "coreloop.untp": { + "type": "Project" + }, + "Microsoft.CodeCoverage": { + "type": "CentralTransitive", + "requested": "[17.10.0, )", + "resolved": "17.10.0", + "contentHash": "yC7oSlnR54XO5kOuHlVOKtxomNNN1BWXX8lK1G2jaPXT9sUok7kCOoA4Pgs0qyFaCtMrNsprztYMeoEGqCm4uA==" + }, + "System.Text.Json": { + "type": "CentralTransitive", + "requested": "[8.0.4, )", + "resolved": "8.0.4", + "contentHash": "bAkhgDJ88XTsqczoxEMliSrpijKZHhbJQldhAmObj/RbrN3sU5dcokuXmWJWsdQAhiMJ9bTayWsL1C9fbbCRhw==", + "dependencies": { + "System.Text.Encodings.Web": "8.0.0" + } + } + } + } +} \ No newline at end of file diff --git a/tests-with-reportgenerator.ps1 b/tests-with-reportgenerator.ps1 new file mode 100644 index 0000000..1da033e --- /dev/null +++ b/tests-with-reportgenerator.ps1 @@ -0,0 +1,3 @@ +$TestOutput = dotnet test --configuration Release --verbosity normal --collect:"XPlat Code Coverage" -property:CollectCoverage=true -property:DeterministicSourcePaths=true -property:IncludeTestAssembly=true -property:CoverletOutputFormat=cobertura /p:CoverletOutput='./generated-reports/coverage/' +$TestReports = $TestOutput | Select-String coverage.cobertura.xml | ForEach-Object { $_.Line.Trim() } | Join-String -Separator ';' +dotnet reportgenerator -assemblyfilters:'-xunit*' -reports:'$TestReports' -targetdir:'./generated-reports/coverage/' -reporttypes:'HtmlInline;Cobertura;MarkdownSummary' \ No newline at end of file diff --git a/update-dotnet-tools.ps1 b/update-dotnet-tools.ps1 new file mode 100644 index 0000000..c0da445 --- /dev/null +++ b/update-dotnet-tools.ps1 @@ -0,0 +1 @@ +dotnet tool list | Select-Object -Skip 2 | ForEach-Object { $_.Split()[0] } | ForEach-Object { dotnet tool update $_ } \ No newline at end of file diff --git a/verify-packages.ps1 b/verify-packages.ps1 new file mode 100644 index 0000000..b1fd087 --- /dev/null +++ b/verify-packages.ps1 @@ -0,0 +1,47 @@ +# Path to Directory.Packages.props +$packagesPropsPath = "./Directory.Packages.props" + +Write-Host "Package props path: $packagesPropsPath" + +# Read and parse the Directory.Packages.props file +[xml]$packagesProps = Get-Content $packagesPropsPath + +# Initialize a flag to track if any verification fails +$verificationFailed = $false + +foreach ($package in $packagesProps.Project.ItemGroup.PackageVersion) { + $packageName = $package.Include + $packageVersion = $package.Version + + # Construct the package path + $packagePath = "$env:USERPROFILE\.nuget\packages\$packageName\$packageVersion\$packageName.$packageVersion.nupkg" + + # Print the package being verified + Write-Output "Verifying package: $packageName, Version: $packageVersion" + + # Verification command string + $command = "dotnet nuget verify --all --verbosity normal `"$packagePath`" --configfile NuGet.config" + + # Execute the command and capture the output + try { + Write-Output "Executing: $command" + & dotnet nuget verify --all --verbosity normal "$packagePath" --configfile NuGet.config + } catch { + Write-Output "ERROR: Verification failed for $packageName, Version: $packageVersion" + $verificationFailed = $true + } + + # Also check the exit code explicitly if needed + if ($LASTEXITCODE -ne 0) { + Write-Host "ERROR: Verification failed for $packageName, Version: $packageVersion (Exit Code: $LASTEXITCODE)" -ForegroundColor Red + $verificationFailed = $true + } +} + +# Check if any verifications failed +if ($verificationFailed) { + Write-Host "One or more package verifications failed." -ForegroundColor Red + exit 1 +} else { + Write-Host "All package verifications succeeded." -ForegroundColor Green +} diff --git a/verify-packages.sh b/verify-packages.sh new file mode 100644 index 0000000..eeb4330 --- /dev/null +++ b/verify-packages.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +packagesPropsPath="./Directory.Packages.props" + +echo "Package props path: $packagesPropsPath" + +# Prepare an XPath expression to extract PackageVersion attributes +xpathExpression="//Project/ItemGroup/PackageVersion" + +# Read and parse each PackageVersion node from Directory.Packages.props +xmllint --xpath "${xpathExpression}" $packagesPropsPath 2>/dev/null | \ +grep -oP 'Include="\K[^"]+' | \ +while read packageName; do + packageVersion=$(xmllint --xpath "string(//Project/ItemGroup/PackageVersion[@Include='$packageName']/@Version)" $packagesPropsPath 2>/dev/null) + + packagePath="$HOME/.nuget/packages/$packageName/$packageVersion/$packageName.$packageVersion.nupkg" + echo "Verifying package: $packageName, Version: $packageVersion" + command="dotnet nuget verify --all --verbosity normal '$packagePath' --configfile NuGet.config" + echo "Executing: $command" + if ! eval $command; then + echo "ERROR: Verification failed for $packageName, Version: $packageVersion" + verificationFailed=true + fi +done + +if [ "$verificationFailed" = true ]; then + echo "One or more package verifications failed." + exit 1 +else + echo "All package verifications succeeded." +fi