|
| 1 | +# Contributing to GamerGuardian |
| 2 | + |
| 3 | +Thanks for your interest. This document describes how to set up, contribute, and what reviewers look for. |
| 4 | + |
| 5 | +## Quick start for contributors |
| 6 | + |
| 7 | +```powershell |
| 8 | +git clone https://github.com/carterscode/GamerGuardian.git |
| 9 | +cd GamerGuardian |
| 10 | +dotnet build |
| 11 | +dotnet test |
| 12 | +src\GamerGuardian\bin\Debug\net8.0-windows10.0.22000.0\GamerGuardian.exe --show-settings |
| 13 | +``` |
| 14 | + |
| 15 | +For the installer build and CI workflow details, see [docs/wiki/Build-from-source.md](https://github.com/carterscode/GamerGuardian/blob/main/docs/wiki/Build-from-source.md). |
| 16 | + |
| 17 | +## Branching and pull requests |
| 18 | + |
| 19 | +`main` is protected — you cannot push to it directly. The flow: |
| 20 | + |
| 21 | +1. Branch off `main`: `git checkout -b feat/something-descriptive`. Use `feat/`, `fix/`, `chore/`, `ci/`, `docs/` prefixes. |
| 22 | +2. Commit your changes with descriptive messages (see *Commit messages* below). |
| 23 | +3. Push the branch: `git push -u origin feat/something-descriptive`. |
| 24 | +4. Open a pull request: `gh pr create --base main`. |
| 25 | +5. CI runs automatically — `build`, `Analyze (csharp)`, `Analyze (actions)`. All three must pass before merge. |
| 26 | +6. Self-merge once green: `gh pr merge --merge --delete-branch` (no required approvals for the solo-dev workflow). |
| 27 | + |
| 28 | +## Commit messages |
| 29 | + |
| 30 | +Conventional Commits format. The first line is `<type>: <imperative summary>` under 72 chars. |
| 31 | + |
| 32 | +Common types: |
| 33 | +- `feat:` — new functionality (new monitor, UI feature, CLI flag) |
| 34 | +- `fix:` — bug fix |
| 35 | +- `chore:` — maintenance, refactors with no behavior change |
| 36 | +- `ci:` — workflow / build pipeline changes |
| 37 | +- `docs:` — wiki, README, comments |
| 38 | +- `perf:` — performance improvements |
| 39 | +- `ui:` — UI/UX changes |
| 40 | + |
| 41 | +Multi-line bodies are encouraged for non-trivial changes — explain *why*, not *what*. Example: |
| 42 | + |
| 43 | +``` |
| 44 | +fix(services): stop UAC spam when Windows reverts a service change |
| 45 | +
|
| 46 | +Symptom: enabling auto-apply on a service Windows refuses to actually |
| 47 | +disable (DoSvc / Delivery Optimization is the trigger case) caused a |
| 48 | +UAC prompt every 30 s forever. |
| 49 | +
|
| 50 | +MonitorService now backs off auto-apply for a setting whose verify |
| 51 | +failed for 15 minutes. Drift still surfaces as a notification. |
| 52 | +``` |
| 53 | + |
| 54 | +## Code style |
| 55 | + |
| 56 | +- Follow the existing patterns. The codebase is small and consistent. |
| 57 | +- `<Nullable>enable</Nullable>` is on. Don't introduce `?` types if you can avoid them. |
| 58 | +- `<TreatWarningsAsErrors>true</TreatWarningsAsErrors>` is on. Build warnings break CI. |
| 59 | +- Default to no comments. Only comment the *why* when the *what* is obvious from the code. See examples in `Monitors/HagsMonitor.cs` for the conventional level of commenting. |
| 60 | +- C# expression-bodied members and pattern-matching are encouraged where they read naturally. |
| 61 | +- Don't introduce abstractions speculatively. Three similar lines is better than a premature framework. |
| 62 | + |
| 63 | +## Adding a new monitor |
| 64 | + |
| 65 | +The canonical example is `src/GamerGuardian/Monitors/HagsMonitor.cs` — about 30 lines. |
| 66 | + |
| 67 | +A new monitor needs: |
| 68 | + |
| 69 | +1. A class implementing `IMonitoredSetting` in `src/GamerGuardian/Monitors/`. |
| 70 | +2. Registration in `App.xaml.cs` in the `_allMonitors` array. |
| 71 | +3. A row in `SettingsWindow.xaml.cs` `LoadGlobals` (or the equivalent for your tab). |
| 72 | +4. A `MechanismFor` and `VerifyCommandFor` entry in `src/GamerGuardian/Services/SettingDocs.cs`. |
| 73 | +5. **A test** in `tests/GamerGuardian.Tests/` (see *Tests* below). |
| 74 | + |
| 75 | +If the new monitor writes to `HKLM`, route it through `ElevatedRegistry` so it shares the existing UAC-prompt behavior. |
| 76 | + |
| 77 | +## Adding a new Windows service to the catalog |
| 78 | + |
| 79 | +For the `Windows services` tab, just append to `ServiceCatalog.All` in `src/GamerGuardian/Services/ServiceCatalog.cs`. No code change required elsewhere — `WindowsServiceMonitor` is registered once per catalog entry by `App.xaml.cs`. |
| 80 | + |
| 81 | +If the service is one Windows actively protects (re-enables via `WaaSMedicSvc` etc.), set `RecommendedTarget: ServiceTargetState.Manual` rather than `Disabled`, or omit it from the catalog entirely. See `docs/wiki/Architecture-rationale.md` for the WU-protection background. |
| 82 | + |
| 83 | +## Tests |
| 84 | + |
| 85 | +We use xUnit. The test project lives at `tests/GamerGuardian.Tests/`. |
| 86 | + |
| 87 | +Run all tests: |
| 88 | + |
| 89 | +```powershell |
| 90 | +dotnet test |
| 91 | +``` |
| 92 | + |
| 93 | +CI runs the same on every PR. |
| 94 | + |
| 95 | +### Test policy |
| 96 | + |
| 97 | +When you add or change behavior: |
| 98 | + |
| 99 | +- **Pure logic** (catalogs, mappings, parsers, lookup tables) — add a unit test covering the new behavior. |
| 100 | +- **Native API wrappers** (anything in `Native/` or `WindowsServiceController`) — add a "doesn't throw on bad input" test if practical. Full coverage isn't expected since these wrap Windows APIs that aren't easily mockable. |
| 101 | +- **UI** — manual verification on a dev-build artifact is the current standard. UI test automation is on the roadmap. |
| 102 | +- **Bug fixes** — add a regression test if the bug is reproducible from a unit test. |
| 103 | + |
| 104 | +The general rule: it's fine to merge without a test if the change can't be reasonably unit-tested (a UI tweak, a workflow change, a doc update). It's not fine to merge without a test if the change touches a class that *is* unit-tested already. |
| 105 | + |
| 106 | +## Reporting issues and requesting features |
| 107 | + |
| 108 | +- **Bug reports / feature requests:** [GitHub Issues](https://github.com/carterscode/GamerGuardian/issues). Search first; include `--test` output and your `changes.log` if relevant. |
| 109 | +- **Security vulnerabilities:** see [SECURITY.md](SECURITY.md). **Do not** open a public issue. |
| 110 | +- **Questions:** also fine in Issues; tag with `question`. |
| 111 | + |
| 112 | +## What reviewers look for |
| 113 | + |
| 114 | +- The change is scoped to one concern. |
| 115 | +- New behavior has a test if reasonably testable. |
| 116 | +- No new compiler warnings. |
| 117 | +- Commit messages explain *why*. |
| 118 | +- No secrets in the diff (GitHub push protection will catch most, but double-check). |
| 119 | +- Touched files have consistent style with the surrounding code. |
| 120 | +- For new dependencies: justified, well-maintained, license-compatible (MIT-friendly). |
| 121 | + |
| 122 | +## License |
| 123 | + |
| 124 | +By contributing you agree your contributions are licensed under the [MIT License](LICENSE), the same license the project uses. |
0 commit comments