Add MailDev and MailKit custom integration sample - #1891
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new Aspire sample (samples/maildev-mailkit) demonstrating a custom MailDev hosting integration exported via the Aspire Type System (ATS) and a MailKit client integration consumed by a newsletter API, with both TypeScript and C# AppHost options.
Changes:
- Introduces MailDev hosting integration (
AddMailDev,MailDevResource) and a MailKit client integration with health checks, tracing, and metrics. - Adds a runnable TypeScript AppHost plus a compile-validated C# AppHost equivalent, along with sample newsletter endpoints.
- Adds focused unit tests for the hosting/client integrations and documents setup/run/test steps.
Reviewed changes
Copilot reviewed 29 out of 30 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| samples/maildev-mailkit/tsconfig.apphost.json | TypeScript compiler config for the sample AppHost build output. |
| samples/maildev-mailkit/ServiceDefaults/ServiceDefaults.csproj | New ServiceDefaults project to share health check + OpenTelemetry wiring. |
| samples/maildev-mailkit/ServiceDefaults/Extensions.cs | Implements ServiceDefaults extensions and endpoint mapping. |
| samples/maildev-mailkit/README.md | Documentation for ATS exports, credentials flow, running and testing the sample. |
| samples/maildev-mailkit/package.json | Node package scripts/deps for building and linting the TypeScript AppHost. |
| samples/maildev-mailkit/package-lock.json | Locks Node dependencies for reproducible installs. |
| samples/maildev-mailkit/NewsletterService/Properties/launchSettings.json | Local run profiles for the newsletter API. |
| samples/maildev-mailkit/NewsletterService/Program.cs | Newsletter subscribe/unsubscribe endpoints sending SMTP mail via MailKit integration. |
| samples/maildev-mailkit/NewsletterService/NewsletterService.csproj | Newsletter API project wiring (OpenAPI/Scalar + project references). |
| samples/maildev-mailkit/MailKit.Client/Properties/AssemblyInfo.cs | Exposes internals to MailKit client tests. |
| samples/maildev-mailkit/MailKit.Client/MailKitHealthCheck.cs | Health check that validates SMTP connectivity via the factory. |
| samples/maildev-mailkit/MailKit.Client/MailKitExtensions.cs | Builder extensions registering MailKit factory + OTel + health checks. |
| samples/maildev-mailkit/MailKit.Client/MailKitClientSettings.cs | Connection string parsing and configuration settings for SMTP. |
| samples/maildev-mailkit/MailKit.Client/MailKitClientFactory.cs | Scoped SMTP client factory with connection caching per scope. |
| samples/maildev-mailkit/MailKit.Client/MailKit.Client.csproj | MailKit client integration package references/TFM. |
| samples/maildev-mailkit/MailKit.Client.Tests/MailKitExtensionsTests.cs | Unit tests for registration behavior (scoped/keyed/validation). |
| samples/maildev-mailkit/MailKit.Client.Tests/MailKitClientSettingsTests.cs | Unit tests for connection string parsing behavior. |
| samples/maildev-mailkit/MailKit.Client.Tests/MailKit.Client.Tests.csproj | Test project setup for MailKit client integration. |
| samples/maildev-mailkit/MailDev.Hosting/MailDevResourceBuilderExtensions.cs | Adds the MailDev container resource and exports it for ATS. |
| samples/maildev-mailkit/MailDev.Hosting/MailDevResource.cs | Defines MailDev resource model + deferred connection string expression. |
| samples/maildev-mailkit/MailDev.Hosting/MailDev.Hosting.csproj | Hosting integration project for MailDev (Aspire.Hosting dependency). |
| samples/maildev-mailkit/MailDev.Hosting.Tests/MailDevResourceTests.cs | Unit tests validating container config, ATS exports, and connection string expression. |
| samples/maildev-mailkit/MailDev.Hosting.Tests/MailDev.Hosting.Tests.csproj | Test project setup for MailDev hosting integration. |
| samples/maildev-mailkit/eslint.config.mjs | ESLint configuration for the TypeScript AppHost file. |
| samples/maildev-mailkit/CSharpAppHost/Program.cs | C# equivalent AppHost wiring MailDev + newsletter service. |
| samples/maildev-mailkit/CSharpAppHost/CSharpAppHost.csproj | C# AppHost project setup referencing Aspire.Hosting + MailDev.Hosting. |
| samples/maildev-mailkit/aspire.config.json | Configures the TypeScript AppHost and ATS package export for restore. |
| samples/maildev-mailkit/apphost.mts | Runnable TypeScript AppHost consuming ATS-generated APIs. |
| samples/maildev-mailkit/.gitignore | Ignores .aspire/ and build outputs for the sample. |
| README.md | Adds the new sample entry to the repository’s samples table. |
Files not reviewed (1)
- samples/maildev-mailkit/package-lock.json: Generated file
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
6a6bbcd to
ad93e11
Compare
ad93e11 to
f42053e
Compare
Adam Ratzman (adamint)
left a comment
There was a problem hiding this comment.
Reviewed pinned head 7ff86d2d6fd5ba479889cfa5a789f641ba434596. The overall shape is sound and these are fixable in place, so I am approving. I think the must-fix items are keeping MailDev run-only, adding real readiness, making repo CI compile/test the .NET projects, and returning Unhealthy instead of an unhandled 500 for missing MailKit configuration. I also left comments on request validation, connection properties, and ATS docs.
The PR head advanced while this review ran; this decision is intentionally attached to the requested pinned commit.
Adam Ratzman (adamint)
left a comment
There was a problem hiding this comment.
Incremental review of f42053e: the MailKit naming fix is incomplete, so I reopened that thread with a failing focused test. Ubuntu is failing in the unrelated Angular sample (typescript@7.0.2 vs @angular-devkit/build-angular requiring <6.1), which #1866 already fixed on main. This head is still conflicting with main and red, so I’m leaving a comment rather than approving. Please merge main, address the MailKit thread, and rerun CI.
Adam Ratzman (adamint)
left a comment
There was a problem hiding this comment.
Approving this as the remaining issue is fixable in place. The health-check thread is still must-fix before merge, and this branch needs updating from main to clear the unrelated Angular failure and workflow conflict.
…ilkit-sample # Conflicts: # .github/workflows/ci.yml
- MailDev.Hosting: exclude the resource from the manifest, add an HTTP readiness health check (/healthz), and implement GetConnectionProperties (Host, Port, Username, Password, Uri) for structured/polyglot consumers - MailDev.Hosting: enable GenerateDocumentationFile so XML docs flow into the generated ATS SDK JSDoc; document the primary constructor parameters - MailKit.Client: bind each health check to its own connection settings so multiple registrations probe distinct endpoints, and construct the factory without throwing so a missing endpoint reports Unhealthy instead of a 500 - NewsletterService: validate the recipient with MailboxAddress.TryParse and return 400 for missing/invalid email instead of an unhandled 500 - ServiceDefaults: only map health endpoints in Development, with a note on the security implications, matching the repo convention - Add MailDevMailKit.slnx so CI compiles and tests all sample projects - Add tests for manifest exclusion, the readiness health check, structured connection properties, per-connection health-check binding, and the Unhealthy-on-missing-endpoint path Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Thanks for the detailed review Adam Ratzman (@adamint)! Pushed
On the Copilot package-lock note: the internal |
The repo CI pins the Aspire CLI to 13.4.6, but the sample pinned the Aspire SDK to 13.5.0 (staging), causing `aspire restore` to fail with a version mismatch on every CI run. Downgrade the sample to the stable 13.4.0 release so it restores and builds under CI: - aspire.config.json: SDK 13.5.0 -> 13.4.0; drop the staging channel. - CSharpAppHost / MailDev.Hosting: Aspire.Hosting 13.5.0 -> 13.4.0. - MailDev.Hosting: opt in to ASPIREATS001; the Aspire Type System export attribute is an evaluation feature in 13.4.x. - Remove the sample-local NuGet.Config; the staging feed is no longer needed and the repo-root NuGet.Config (nuget.org) suffices. Verified: solution builds clean, 18/18 tests pass, `aspire restore` regenerates the ATS bindings (JSDoc intact), tsc + eslint clean. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
CI is green now ✅ The pipeline was red on every run because the sample pinned the Aspire SDK to 13.5.0 (staging) while the repo CI installs the Aspire CLI at 13.4.6 — Rather than bump CI, I aligned the sample with the stable release the repo already targets:
Verified locally and in CI: solution builds clean, 18/18 tests pass, |
Summary
Validation