Skip to content

Add listmonk hosting integration#1457

Open
axies20 wants to merge 14 commits into
CommunityToolkit:mainfrom
axies20:Listmonk
Open

Add listmonk hosting integration#1457
axies20 wants to merge 14 commits into
CommunityToolkit:mainfrom
axies20:Listmonk

Conversation

@axies20

@axies20 axies20 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Adds a new listmonk hosting integration for Aspire.

This PR adds:

  • CommunityToolkit.Aspire.Hosting.Listmonk
  • C# and TypeScript AppHost examples
  • PostgreSQL configuration support
  • listmonk container configuration APIs for supported environment variables
  • upload volume and bind mount helpers
  • model, public API, C# AppHost, and TypeScript AppHost tests
  • README documentation for the integration

The integration runs the official listmonk/listmonk container, configures it to use PostgreSQL, runs install and upgrade on startup, exposes HTTP connection properties, and supports the documented listmonk environment configuration surface.

PR Checklist

  • Created a feature/dev branch in your fork (vs. submitting directly from a commit on main)
  • Based off latest main branch of toolkit
  • PR doesn't include merge commits (always rebase on top of our main, if needed)
  • New integration
    • Docs are written
    • Added description of major feature to project description for NuGet package (4000 total character limit, so don't push entire description over that)
  • Tests for the changes have been added (for bug fixes / features) (if applicable)
  • Contains NO breaking changes
  • Every new API (including internal ones) has full XML docs
  • Code follows all style conventions

Other information

Validation performed:

  • dotnet build tests/CommunityToolkit.Aspire.Hosting.Listmonk.Tests/CommunityToolkit.Aspire.Hosting.Listmonk.Tests.csproj
  • dotnet test tests/CommunityToolkit.Aspire.Hosting.Listmonk.Tests/CommunityToolkit.Aspire.Hosting.Listmonk.Tests.csproj --no-build
  • Docker smoke started Postgres + listmonk and received HTTP 200 from listmonk
  • aspire restore --apphost apphost.mts
  • npx.cmd tsc --noEmit
  • bash eng/testing/generate-test-list-for-workflow.sh --plain

CI has also run Hosting.Listmonk.Tests on Ubuntu and Windows.

axies20 added 2 commits July 7, 2026 20:11
- Implemented `CommunityToolkit.Aspire.Hosting.Listmonk` for Listmonk container integration.
- Introduced extension methods for configuring Listmonk containers, environment variables, volumes, and annotations.
- Added test projects for validating Listmonk configurations and functionalities.
- Created example projects under `examples/listmonk` to demonstrate integration and usage.
- Updated solution and centralized package references to include the new Listmonk project.
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/CommunityToolkit/Aspire/main/eng/scripts/dogfood-pr.sh | bash -s -- 1457

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/CommunityToolkit/Aspire/main/eng/scripts/dogfood-pr.ps1) } 1457"

@axies20 axies20 changed the title Adds a new listmonk hosting integration for Aspire. Add listmonk hosting integration Jul 7, 2026
axies20 added 4 commits July 7, 2026 22:45
- Introduced new parameters `postgresName` and `databaseName` to simplify PostgreSQL integration.
- Removed `WithPostgreSQL` method and replaced it with an internal `ConfigurePostgreSQL` implementation.
- Updated XML documentation and examples to reflect the new configuration approach.

@aaronpowell aaronpowell left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a design request change on how PostgreSQL is handled, and the implications of that would also require some test updates (I didn't annotate those though).

Comment on lines +86 to +90
var postgres = builder.AddPostgres(postgresName ?? $"{name}-postgres")
.WithParentRelationship(listmonk.Resource);
var database = postgres.AddDatabase(databaseName ?? $"{name}-db");

return listmonk.ConfigurePostgreSQL(database);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is a good idea. While I get the desire for simplicity, just adding listmock and everything is configured, you lose the flexibility of database control. What if I have a Postgres server for other parts of my setup that I want to reuse? This design means that I can't do that.

Instead, we should expose a WithReference that takes the Postgres database and runs the ConfigurePostgreSQL stuff against it.

using Aspire.Hosting.ApplicationModel;
using CommunityToolkit.Aspire.Hosting.Listmonk;

#pragma warning disable ASPIREATS001 // AspireExport is experimental

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't needed anymore (should get around to cleaning up the rest of the integrations too)

/// <param name="groupId">The value for <c>PGID</c>.</param>
/// <returns>The <see cref="IResourceBuilder{T}"/>.</returns>
[AspireExport]
public static IResourceBuilder<ListmonkResource> WithUserAndGroupId(this IResourceBuilder<ListmonkResource> builder, int userId, int groupId)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's drop this method, it's not really providing anything that we don't have other methods for.

/// <summary>listmonk/listmonk</summary>
public const string Image = "listmonk/listmonk";
/// <summary>latest</summary>
public const string Tag = "latest";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public const string Tag = "latest";
public const string Tag = "v6.2.0";

We don't want to pin to latest but to explicit versions

/// Initializes a new instance of the <see cref="ListmonkResource"/> class.
/// </summary>
/// <param name="name">The name of the resource.</param>
public ListmonkResource([ResourceName] string name) : base(name)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a primary constructor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants