{"ArticleId":null,"Name":"Contributing","Content":"\u003Cp\u003EGrandNode is open source under the GPL-3.0 licence and developed in the open on GitHub at \u003Ca href=\u0022https://github.com/grandnode/grandnode2\u0022\u003Egithub.com/grandnode/grandnode2\u003C/a\u003E. Bug reports, feature ideas, documentation fixes and pull requests are all welcome. This article describes how a contribution travels from an idea to a merged pull request.\u003C/p\u003E\n\n\u003Ch2 id=\u0022issues\u0022\u003EReporting bugs and requesting features\u003C/h2\u003E\n\u003Cul\u003E\n\u003Cli\u003ESearch the \u003Ca href=\u0022https://github.com/grandnode/grandnode2/issues\u0022\u003Eissues\u003C/a\u003E first; add details to an existing report rather than opening a duplicate.\u003C/li\u003E\n\u003Cli\u003EFor a bug, state the GrandNode version or commit, the steps to reproduce, what you expected and what happened, and the error and stack trace from the application log.\u003C/li\u003E\n\u003Cli\u003ESecurity problems should not be reported in a public issue. Contact the maintainers privately first.\u003C/li\u003E\n\u003C/ul\u003E\n\n\u003Ch2 id=\u0022branches\u0022\u003EBranches\u003C/h2\u003E\n\u003Ctable\u003E\n\u003Cthead\u003E\u003Ctr\u003E\u003Cth\u003EBranch\u003C/th\u003E\u003Cth\u003EPurpose\u003C/th\u003E\u003C/tr\u003E\u003C/thead\u003E\n\u003Ctbody\u003E\n\u003Ctr\u003E\u003Ctd\u003E\u003Ccode\u003Emain\u003C/code\u003E\u003C/td\u003E\u003Ctd\u003EReleased code.\u003C/td\u003E\u003C/tr\u003E\n\u003Ctr\u003E\u003Ctd\u003E\u003Ccode\u003Edevelop\u003C/code\u003E\u003C/td\u003E\u003Ctd\u003EThe integration branch. Contributions target \u003Ccode\u003Edevelop\u003C/code\u003E unless a maintainer says otherwise.\u003C/td\u003E\u003C/tr\u003E\n\u003Ctr\u003E\u003Ctd\u003E\u003Ccode\u003E2.0.x\u003C/code\u003E, \u003Ccode\u003E2.1.x\u003C/code\u003E, ...\u003C/td\u003E\u003Ctd\u003EMaintenance branches of released versions.\u003C/td\u003E\u003C/tr\u003E\n\u003Ctr\u003E\u003Ctd\u003E\u003Ccode\u003Efeature/...\u003C/code\u003E, \u003Ccode\u003Efix/...\u003C/code\u003E\u003C/td\u003E\u003Ctd\u003EYour work, in your fork.\u003C/td\u003E\u003C/tr\u003E\n\u003C/tbody\u003E\n\u003C/table\u003E\n\n\u003Ch2 id=\u0022workflow\u0022\u003EWorkflow\u003C/h2\u003E\n\u003Col\u003E\n\u003Cli\u003EFork the repository to your GitHub account and clone your fork.\u003C/li\u003E\n\u003Cli\u003ECreate a branch from \u003Ccode\u003Edevelop\u003C/code\u003E:\n\u003Cpre\u003E\u003Ccode\u003Egit checkout develop\ngit pull\ngit checkout -b fix/cart-rounding\u003C/code\u003E\u003C/pre\u003E\u003C/li\u003E\n\u003Cli\u003EMake the change, following the conventions in \u003Ccode\u003E.ai/standards/\u003C/code\u003E (naming, C# style, Razor, dependencies). Formatting rules are in \u003Ccode\u003E.editorconfig\u003C/code\u003E.\u003C/li\u003E\n\u003Cli\u003EBuild and run the tests closest to your change, then the solution:\n\u003Cpre\u003E\u003Ccode\u003Edotnet build GrandNode.slnx\ndotnet test src/Tests/Grand.Business.Checkout.Tests\u003C/code\u003E\u003C/pre\u003E\u003C/li\u003E\n\u003Cli\u003ECommit and push to your fork, then open a pull request against \u003Ccode\u003Egrandnode/grandnode2:develop\u003C/code\u003E.\u003C/li\u003E\n\u003Cli\u003EAnswer the review. A maintainer will approve the change or suggest improvements; push further commits to the same branch.\u003C/li\u003E\n\u003C/ol\u003E\n\n\u003Ch2 id=\u0022commits\u0022\u003ECommits\u003C/h2\u003E\n\u003Cul\u003E\n\u003Cli\u003EOne logical change per commit; keep refactoring and behaviour changes in separate commits.\u003C/li\u003E\n\u003Cli\u003EAn imperative subject line under about 72 characters that states the effect, for example \u003Ccode\u003EAdd store scope to payment restrictions\u003C/code\u003E. The body explains why.\u003C/li\u003E\n\u003Cli\u003EDo not commit \u003Ccode\u003Ebin/\u003C/code\u003E, \u003Ccode\u003Eobj/\u003C/code\u003E, \u003Ccode\u003ETestResults/\u003C/code\u003E or IDE folders. Generated frontend bundles \u003Cstrong\u003Eare\u003C/strong\u003E committed, together with the source that produced them.\u003C/li\u003E\n\u003C/ul\u003E\n\n\u003Ch2 id=\u0022pull-request\u0022\u003EThe pull request\u003C/h2\u003E\n\u003Cp\u003EFill in every section of the repository\u0027s pull request template:\u003C/p\u003E\n\u003Cpre\u003E\u003Ccode\u003EResolves #issueNumber\nType: **feature|bugfix**\n\n## Issue\nWhat the problem is, why it happens and how to reproduce it.\n\n## Solution\nA short summary of the change.\n\n## Breaking changes\nList them, or write none.\n\n## Testing\nNumbered steps someone else can follow.\u003C/code\u003E\u003C/pre\u003E\n\u003Cp\u003E\u0022Breaking changes: none\u0022 is a claim reviewers check. Changing a view model, removing a widget zone, renaming a plugin system name or changing a public interface breaks themes and plugins built on GrandNode.\u003C/p\u003E\n\n\u003Ch2 id=\u0022checklist\u0022\u003EBefore you open it\u003C/h2\u003E\n\u003Cul\u003E\n\u003Cli\u003EThe solution builds and the affected test project passes. GitHub Actions builds the solution and runs the tests against a MongoDB service for every pull request to \u003Ccode\u003Edevelop\u003C/code\u003E or \u003Ccode\u003Emain\u003C/code\u003E, together with CodeQL analysis and a Docker image build.\u003C/li\u003E\n\u003Cli\u003ENew user-facing texts exist as localization resources, with an upgrade migration \u2014 see \u003Ca href=\u0022/developers-upgrade-migrations\u0022\u003EUpgrade migrations\u003C/a\u003E.\u003C/li\u003E\n\u003Cli\u003ENew settings default to the previous behaviour; new permissions have a migration.\u003C/li\u003E\n\u003Cli\u003EAdmin changes were checked in all three panels where they apply: administrator, store manager and vendor.\u003C/li\u003E\n\u003Cli\u003EFrontend bundles were rebuilt if frontend source changed.\u003C/li\u003E\n\u003Cli\u003EThe diff contains only what the pull request is about.\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003EIf you work with an AI coding agent, ask it to run \u003Ccode\u003E.ai/prompts/review-change.md\u003C/code\u003E and \u003Ccode\u003E.ai/checklists/definition-of-done.md\u003C/code\u003E against your diff before you open the pull request \u2014 see \u003Ca href=\u0022/developers-ai-agent-kit\u0022\u003EThe AI Agent Kit\u003C/a\u003E.\u003C/p\u003E\n\n\u003Ch2 id=\u0022review\u0022\u003EWhat reviewers look at\u003C/h2\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Cstrong\u003ELayering.\u003C/strong\u003E Business logic in services or mediator handlers, not in controllers or views; data access through \u003Ccode\u003EIRepository\u0026lt;T\u0026gt;\u003C/code\u003E; registrations in an \u003Ccode\u003EIStartupApplication\u003C/code\u003E.\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EScope.\u003C/strong\u003E Store, vendor and customer group boundaries respected, cache keys that include the store and language where the data depends on them, and permission checks on every admin action.\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EVocabulary.\u003C/strong\u003E Types and texts that use GrandNode\u0027s terms \u2014 Brand, Page, Customer group, Merchandise return, Loyalty points.\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EDependencies.\u003C/strong\u003E No new package for something the repository already does, and package versions only in \u003Ccode\u003EDirectory.Packages.props\u003C/code\u003E.\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003ETests.\u003C/strong\u003E New behaviour covered by a test in the matching project under \u003Ccode\u003Esrc/Tests\u003C/code\u003E.\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003ESmall, focused pull requests are reviewed faster than large ones. If you plan a bigger change, open an issue first and agree on the approach.\u003C/p\u003E\n\n\u003Ch2 id=\u0022other-ways\u0022\u003EOther ways to help\u003C/h2\u003E\n\u003Cul\u003E\n\u003Cli\u003EStar the project on GitHub and share it.\u003C/li\u003E\n\u003Cli\u003ETranslate the resource files into your language.\u003C/li\u003E\n\u003Cli\u003EAnswer questions from other users and improve this documentation.\u003C/li\u003E\n\u003Cli\u003ESponsor the project through Open Collective.\u003C/li\u003E\n\u003C/ul\u003E\n\n\u003Ch2 id=\u0022related\u0022\u003ERelated\u003C/h2\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\u0022/developers-development-setup\u0022\u003EDevelopment setup\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\u0022/developers-architecture-overview\u0022\u003EArchitecture overview\u003C/a\u003E\u003C/li\u003E\n\u003C/ul\u003E","ParentCategoryId":"6abdec6d83d2816248229f65","SeName":"developers-contributing","MetaKeywords":null,"MetaDescription":"How to contribute to GrandNode on GitHub: issues, forks and branches, commits, the pull request template, tests and what reviewers check.","MetaTitle":null,"AllowComments":false,"Captcha":{"ReCaptchaChallengeField":null,"ReCaptchaResponseField":null,"ReCaptchaResponseValue":null,"ReCaptchaResponse":null},"RelatedArticles":[],"CategoryBreadcrumb":[{"Name":"For developers","Description":null,"IsCurrent":false,"Children":null,"Parent":null,"SeName":"docs-developers","Id":"6abdec6d83d2816248229f65","UserFields":[]}],"AddNewComment":{"CommentText":null,"DisplayCaptcha":false,"Id":null,"UserFields":[]},"Comments":[],"Id":"6abdec6d83d2816248229f77","UserFields":[]}