|
| 1 | +# Contributing to CloudEngAgent |
| 2 | + |
| 3 | +Welcome! 👋 This guide will get you from a fresh clone to a green build, your |
| 4 | +first passing test, and an opened pull request. If anything here is wrong or |
| 5 | +unclear, please open an issue or PR — onboarding fixes are always welcome. |
| 6 | + |
| 7 | +> **TL;DR** |
| 8 | +> |
| 9 | +> ```bash |
| 10 | +> git clone https://github.com/razeone/CloudEngAgent.git |
| 11 | +> cd CloudEngAgent |
| 12 | +> dotnet restore |
| 13 | +> dotnet build |
| 14 | +> dotnet test |
| 15 | +> dotnet run --project src/CloudEngAgent.Api |
| 16 | +> ``` |
| 17 | +> |
| 18 | +> Then open `http://localhost:<port>/openapi/v1.json` (port logged on startup). |
| 19 | +
|
| 20 | +--- |
| 21 | +
|
| 22 | +## Table of contents |
| 23 | +
|
| 24 | +1. [Prerequisites](#prerequisites) |
| 25 | +2. [Getting the code](#getting-the-code) |
| 26 | +3. [First build & test](#first-build--test) |
| 27 | +4. [Running the services locally](#running-the-services-locally) |
| 28 | +5. [Project layout at a glance](#project-layout-at-a-glance) |
| 29 | +6. [Development workflow](#development-workflow) |
| 30 | +7. [Coding conventions](#coding-conventions) |
| 31 | +8. [Testing](#testing) |
| 32 | +9. [Submitting a pull request](#submitting-a-pull-request) |
| 33 | +10. [Where to go next](#where-to-go-next) |
| 34 | +
|
| 35 | +--- |
| 36 | +
|
| 37 | +## Prerequisites |
| 38 | +
|
| 39 | +| Tool | Version | Purpose | |
| 40 | +| ------------------- | ---------------------- | ------------------------------------------ | |
| 41 | +| [.NET SDK] | **10.0 (preview)** | Build & run all projects | |
| 42 | +| Git | any recent | Source control | |
| 43 | +| Docker | recent | SQL Server container, integration tests | |
| 44 | +| An IDE | VS 2022+, VS Code, Rider | Editing & debugging C# 13 | |
| 45 | +| (optional) `dotnet-ef` | latest | EF Core migrations (`dotnet tool install --global dotnet-ef`) | |
| 46 | +
|
| 47 | +[.NET SDK]: https://dotnet.microsoft.com/download/dotnet/10.0 |
| 48 | +
|
| 49 | +The CI pipeline pins `dotnet-version: 10.0.x` with `dotnet-quality: preview` |
| 50 | +(see [`.github/workflows/ci.yml`](.github/workflows/ci.yml)). Use the same |
| 51 | +channel locally to avoid restore mismatches. |
| 52 | +
|
| 53 | +> **Why .NET 10 preview?** The solution targets `net10.0` and uses the latest |
| 54 | +> language version and analysis level (see `Directory.Build.props`). |
| 55 | +> `TreatWarningsAsErrors` is on for non-test projects. |
| 56 | +
|
| 57 | +## Getting the code |
| 58 | +
|
| 59 | +```bash |
| 60 | +git clone https://github.com/razeone/CloudEngAgent.git |
| 61 | +cd CloudEngAgent |
| 62 | +``` |
| 63 | +
|
| 64 | +The repo is a single .NET solution (`CloudEngAgent.slnx`) with central package |
| 65 | +management (`Directory.Packages.props`) — never pin a version inside an |
| 66 | +individual `.csproj`. |
| 67 | +
|
| 68 | +## First build & test |
| 69 | +
|
| 70 | +```bash |
| 71 | +dotnet restore |
| 72 | +dotnet build --configuration Release -warnaserror |
| 73 | +dotnet test |
| 74 | +``` |
| 75 | +
|
| 76 | +Mirror the CI commands when you want a faithful local run: |
| 77 | +
|
| 78 | +```bash |
| 79 | +dotnet test tests/CloudEngAgent.Domain.Tests --configuration Release --no-build |
| 80 | +dotnet test tests/CloudEngAgent.Api.Tests --configuration Release --no-build |
| 81 | +dotnet test tests/CloudEngAgent.Mcp.Server.Tests --configuration Release --no-build |
| 82 | +# Integration tests require Docker (Testcontainers spins up SQL Server): |
| 83 | +dotnet test tests/CloudEngAgent.Infrastructure.Tests --configuration Release --no-build |
| 84 | +``` |
| 85 | +
|
| 86 | +If Docker isn't available, the integration tests skip with a clear reason |
| 87 | +rather than failing — see [`MsSqlContainerFixture.cs`](tests/CloudEngAgent.Infrastructure.Tests/MsSqlContainerFixture.cs). |
| 88 | +
|
| 89 | +## Running the services locally |
| 90 | +
|
| 91 | +The two runnable hosts are the API and the MCP server. |
| 92 | +
|
| 93 | +```bash |
| 94 | +# API (AG-UI streaming + workflow runs) |
| 95 | +dotnet run --project src/CloudEngAgent.Api |
| 96 | +
|
| 97 | +# MCP server (read-only SQL introspection tools) |
| 98 | +dotnet run --project src/CloudEngAgent.Mcp.Server |
| 99 | +``` |
| 100 | +
|
| 101 | +Both bind to a Kestrel-assigned port (printed on startup). Useful endpoints: |
| 102 | +
|
| 103 | +- `GET /healthz` — liveness |
| 104 | +- `GET /readyz` — readiness (Api only; checks the database) |
| 105 | +- `GET /openapi/v1.json` — OpenAPI document (Development only) |
| 106 | +- `GET /v1/personas`, `GET /v1/workflows`, `POST /v1/runs` — see |
| 107 | + [`README.md`](README.md#api-surface-v1) for the full list. |
| 108 | +
|
| 109 | +By default the API runs in **Stub** workflow mode (no LLM key required) and |
| 110 | +falls back to an in-memory run store if `ConnectionStrings:Runs` is empty. |
| 111 | +That means a fresh clone runs end-to-end with **zero configuration**. To wire |
| 112 | +real backends, see the LLM, persona, and MCP sections of the main `README.md`. |
| 113 | +
|
| 114 | +## Project layout at a glance |
| 115 | +
|
| 116 | +``` |
| 117 | +src/ |
| 118 | + CloudEngAgent.Domain/ Pure domain types (no I/O) |
| 119 | + CloudEngAgent.Application/ Use cases, abstractions, handlers |
| 120 | + CloudEngAgent.Infrastructure/ Adapters (EF Core, MCP HTTP client, secrets, persona repo) |
| 121 | + CloudEngAgent.Api/ ASP.NET Core minimal API + AG-UI SSE writer |
| 122 | + CloudEngAgent.Mcp.Server/ Read-only SQL introspection MCP server |
| 123 | +tests/ |
| 124 | + CloudEngAgent.Domain.Tests/ |
| 125 | + CloudEngAgent.Api.Tests/ |
| 126 | + CloudEngAgent.Mcp.Server.Tests/ |
| 127 | + CloudEngAgent.Infrastructure.Tests/ Integration (needs Docker) |
| 128 | +personas/ YAML persona definitions (hot-reloaded) |
| 129 | +docs/ Onboarding & contributor docs (you are here ↗) |
| 130 | +``` |
| 131 | +
|
| 132 | +The architecture follows a classic ports-and-adapters pattern: `Domain` and |
| 133 | +`Application` have no I/O; `Infrastructure` and `Api` plug in adapters via DI |
| 134 | +in [`ServiceCollectionExtensions.cs`](src/CloudEngAgent.Infrastructure/ServiceCollectionExtensions.cs). |
| 135 | +
|
| 136 | +For a deeper tour see [`docs/architecture.md`](docs/architecture.md). |
| 137 | +
|
| 138 | +## Development workflow |
| 139 | +
|
| 140 | +1. **Create a branch** off `main`: |
| 141 | + `git checkout -b feature/<short-topic>` or `fix/<short-topic>`. |
| 142 | +2. **Make focused changes.** Keep PRs small and reviewable. |
| 143 | +3. **Build with warnings-as-errors** before pushing: |
| 144 | + `dotnet build --configuration Release -warnaserror`. |
| 145 | +4. **Run the relevant tests** (unit + any integration touched). |
| 146 | +5. **Open a draft PR early** if you want feedback; mark ready when green. |
| 147 | +
|
| 148 | +Common day-to-day tasks (adding a persona, a backend, an MCP tool, an API |
| 149 | +endpoint) are documented step-by-step in |
| 150 | +[`docs/development.md`](docs/development.md). |
| 151 | +
|
| 152 | +## Coding conventions |
| 153 | +
|
| 154 | +These are enforced by [`.editorconfig`](.editorconfig) and the analyzers |
| 155 | +configured in `Directory.Build.props`. Highlights: |
| 156 | +
|
| 157 | +- **C# style** |
| 158 | + - File-scoped namespaces (`namespace Foo;`). |
| 159 | + - `var` is preferred for built-in types and when the type is apparent. |
| 160 | + - Braces required (`csharp_prefer_braces = true:warning`). |
| 161 | + - Async methods **must** end in `Async` (naming rule). |
| 162 | +- **Nullability**: `<Nullable>enable</Nullable>`. `CS8600/02/03/25` are warnings. |
| 163 | + Don't suppress them — fix the root cause. |
| 164 | +- **Warnings as errors**: All non-test projects fail on warnings. Tests are |
| 165 | + exempt so test-only warnings don't block development. |
| 166 | +- **Centrally managed packages**: Add new package versions in |
| 167 | + `Directory.Packages.props`, then reference by name only in the `.csproj`. |
| 168 | +- **Indentation**: 4 spaces in C#, 2 spaces in JSON / YAML. |
| 169 | +- **No secrets in source**: use `dotnet user-secrets`, env vars, or Key Vault |
| 170 | + (see the README's "Secret resolution order" section). |
| 171 | +
|
| 172 | +## Testing |
| 173 | +
|
| 174 | +| Project | Kind | Notes | |
| 175 | +| ---------------------------------------- | ------------ | ------------------------------------------- | |
| 176 | +| `CloudEngAgent.Domain.Tests` | Unit | Pure domain logic; runs anywhere. | |
| 177 | +| `CloudEngAgent.Api.Tests` | Unit / WAF | `WebApplicationFactory` in-memory. | |
| 178 | +| `CloudEngAgent.Mcp.Server.Tests` | Unit | MCP tool input validation & SQL guards. | |
| 179 | +| `CloudEngAgent.Infrastructure.Tests` | Integration | Spins up SQL Server via Testcontainers. | |
| 180 | +
|
| 181 | +Run a single test class or method: |
| 182 | +
|
| 183 | +```bash |
| 184 | +dotnet test tests/CloudEngAgent.Api.Tests --filter "FullyQualifiedName~Runs" |
| 185 | +``` |
| 186 | +
|
| 187 | +More details and tips: [`docs/testing.md`](docs/testing.md). |
| 188 | +
|
| 189 | +## Submitting a pull request |
| 190 | +
|
| 191 | +Before requesting review, please confirm: |
| 192 | +
|
| 193 | +- [ ] Code builds with `-warnaserror` locally. |
| 194 | +- [ ] All affected tests pass; new behavior is covered by tests. |
| 195 | +- [ ] No secrets, connection strings, or PATs are committed. |
| 196 | +- [ ] Public APIs, configuration keys, or persona schemas have docs/README updates. |
| 197 | +- [ ] The PR description explains *what* changed and *why*, and links any issue. |
| 198 | +
|
| 199 | +CI will re-run `restore → build → unit tests → integration tests` on every |
| 200 | +push. A green CI is required before merge. |
| 201 | +
|
| 202 | +## Where to go next |
| 203 | +
|
| 204 | +- 🚀 [`docs/onboarding.md`](docs/onboarding.md) — a guided first-day walkthrough. |
| 205 | +- 🏛️ [`docs/architecture.md`](docs/architecture.md) — how the layers fit together. |
| 206 | +- 🛠️ [`docs/development.md`](docs/development.md) — recipes for common changes. |
| 207 | +- 🧪 [`docs/testing.md`](docs/testing.md) — test strategy and tips. |
| 208 | +- 📖 [`README.md`](README.md) — the full operator/user reference. |
| 209 | +
|
| 210 | +Happy hacking! 💙 |
0 commit comments