Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,15 @@ jobs:
run: dotnet test -c Release --no-build --no-restore --verbosity minimal
env:
TINYEVENTS_RUN_SQLSERVER_TESTS: true
TINYEVENTS_RUN_POSTGRESQL_TESTS: true

- name: Pack (Release)
run: |
dotnet pack src/TinyEvents/TinyEvents.csproj -c Release --no-build -o ./artifacts
dotnet pack src/TinyEvents.SqlServer.AdoNet/TinyEvents.SqlServer.AdoNet.csproj -c Release --no-build -o ./artifacts
dotnet pack src/TinyEvents.SqlServer.EntityFrameworkCore/TinyEvents.SqlServer.EntityFrameworkCore.csproj -c Release --no-build -o ./artifacts
dotnet pack src/TinyEvents.PostgreSql.AdoNet/TinyEvents.PostgreSql.AdoNet.csproj -c Release --no-build -o ./artifacts
dotnet pack src/TinyEvents.PostgreSql.EntityFrameworkCore/TinyEvents.PostgreSql.EntityFrameworkCore.csproj -c Release --no-build -o ./artifacts
dotnet pack src/TinyEvents.Worker/TinyEvents.Worker.csproj -c Release --no-build -o ./artifacts

- name: Upload NuGet packages
Expand Down
110 changes: 110 additions & 0 deletions .github/workflows/release-package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
name: Release Package

on:
workflow_dispatch:
inputs:
package:
description: "Package to publish"
required: true
type: choice
options:
- TinyEvents
- TinyEvents.Worker
- TinyEvents.SqlServer.AdoNet
- TinyEvents.SqlServer.EntityFrameworkCore
- TinyEvents.PostgreSql.AdoNet
- TinyEvents.PostgreSql.EntityFrameworkCore
version:
description: "Package version to publish"
required: true
type: string

permissions:
contents: read

jobs:
publish:
runs-on: ubuntu-latest
environment: nuget-prod

env:
DOTNET_NOLOGO: true
PACKAGE_ID: ${{ inputs.package }}
PACKAGE_VERSION: ${{ inputs.version }}

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
8.0.x
10.0.x

- name: Resolve package project
shell: bash
run: |
case "$PACKAGE_ID" in
TinyEvents)
PROJECT="src/TinyEvents/TinyEvents.csproj"
;;
TinyEvents.Worker)
PROJECT="src/TinyEvents.Worker/TinyEvents.Worker.csproj"
;;
TinyEvents.SqlServer.AdoNet)
PROJECT="src/TinyEvents.SqlServer.AdoNet/TinyEvents.SqlServer.AdoNet.csproj"
;;
TinyEvents.SqlServer.EntityFrameworkCore)
PROJECT="src/TinyEvents.SqlServer.EntityFrameworkCore/TinyEvents.SqlServer.EntityFrameworkCore.csproj"
;;
TinyEvents.PostgreSql.AdoNet)
PROJECT="src/TinyEvents.PostgreSql.AdoNet/TinyEvents.PostgreSql.AdoNet.csproj"
;;
TinyEvents.PostgreSql.EntityFrameworkCore)
PROJECT="src/TinyEvents.PostgreSql.EntityFrameworkCore/TinyEvents.PostgreSql.EntityFrameworkCore.csproj"
;;
*)
echo "Unsupported package: $PACKAGE_ID"
exit 1
;;
esac

echo "PROJECT=$PROJECT" >> "$GITHUB_ENV"

- name: Restore
run: dotnet restore

- name: Build (Release)
run: dotnet build -c Release --no-restore

- name: Test (Release)
run: dotnet test -c Release --no-build --no-restore
env:
TINYEVENTS_RUN_SQLSERVER_TESTS: true
TINYEVENTS_RUN_POSTGRESQL_TESTS: true

- name: Pack selected package
run: dotnet pack "$PROJECT" -c Release --no-build -o ./artifacts /p:PackageVersion="$PACKAGE_VERSION" /p:Version="$PACKAGE_VERSION"

- name: Verify selected package
shell: bash
run: |
PACKAGE="./artifacts/${PACKAGE_ID}.${PACKAGE_VERSION}.nupkg"

if [ ! -f "$PACKAGE" ]; then
echo "ERROR: Expected $PACKAGE but it was not found."
exit 1
fi

- name: Publish selected package to NuGet
run: dotnet nuget push "./artifacts/${PACKAGE_ID}.${PACKAGE_VERSION}.nupkg" --api-key "${{ secrets.NUGET_API_KEY }}" --source "https://api.nuget.org/v3/index.json" --skip-duplicate

- name: Upload selected package
uses: actions/upload-artifact@v4
with:
name: nupkg
path: ./artifacts/*.nupkg
5 changes: 4 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ jobs:
run: dotnet test -c Release --no-build --no-restore
env:
TINYEVENTS_RUN_SQLSERVER_TESTS: true
TINYEVENTS_RUN_POSTGRESQL_TESTS: true

- name: Pack (Release)
shell: bash
Expand All @@ -45,6 +46,8 @@ jobs:
dotnet pack src/TinyEvents/TinyEvents.csproj -c Release --no-build -o ./artifacts /p:PackageVersion="$TAG" /p:Version="$TAG"
dotnet pack src/TinyEvents.SqlServer.AdoNet/TinyEvents.SqlServer.AdoNet.csproj -c Release --no-build -o ./artifacts /p:PackageVersion="$TAG" /p:Version="$TAG"
dotnet pack src/TinyEvents.SqlServer.EntityFrameworkCore/TinyEvents.SqlServer.EntityFrameworkCore.csproj -c Release --no-build -o ./artifacts /p:PackageVersion="$TAG" /p:Version="$TAG"
dotnet pack src/TinyEvents.PostgreSql.AdoNet/TinyEvents.PostgreSql.AdoNet.csproj -c Release --no-build -o ./artifacts /p:PackageVersion="$TAG" /p:Version="$TAG"
dotnet pack src/TinyEvents.PostgreSql.EntityFrameworkCore/TinyEvents.PostgreSql.EntityFrameworkCore.csproj -c Release --no-build -o ./artifacts /p:PackageVersion="$TAG" /p:Version="$TAG"
dotnet pack src/TinyEvents.Worker/TinyEvents.Worker.csproj -c Release --no-build -o ./artifacts /p:PackageVersion="$TAG" /p:Version="$TAG"

- name: Verify package version matches tag
Expand All @@ -55,7 +58,7 @@ jobs:
echo "Artifacts:"
ls -la ./artifacts

for PACKAGE_ID in TinyEvents TinyEvents.SqlServer.AdoNet TinyEvents.SqlServer.EntityFrameworkCore TinyEvents.Worker; do
for PACKAGE_ID in TinyEvents TinyEvents.SqlServer.AdoNet TinyEvents.SqlServer.EntityFrameworkCore TinyEvents.PostgreSql.AdoNet TinyEvents.PostgreSql.EntityFrameworkCore TinyEvents.Worker; do
if [ ! -f "./artifacts/${PACKAGE_ID}.${TAG}.nupkg" ]; then
echo "ERROR: Expected ./artifacts/${PACKAGE_ID}.${TAG}.nupkg but it was not found."
exit 1
Expand Down
60 changes: 44 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ dotnet add package TinyEvents.SqlServer.EntityFrameworkCore --version 0.1.0-alph
dotnet add package TinyEvents.Worker --version 0.1.0-alpha.1
```

Register TinyEvents and the EF Core provider:
Provider packages are database-specific. Use `TinyEvents.SqlServer.*` for SQL Server or `TinyEvents.PostgreSql.*` for PostgreSQL.

Register TinyEvents and the SQL Server EF Core provider:

```csharp
using Microsoft.EntityFrameworkCore;
Expand Down Expand Up @@ -144,15 +146,15 @@ No runtime assembly scanning is required, and normal consumers do not need manua

## Providers

TinyEvents core is provider-agnostic. The current alpha includes SQL Server provider packages:
TinyEvents core is provider-agnostic. The current alpha includes SQL Server and PostgreSQL provider packages:

- `TinyEvents.SqlServer.EntityFrameworkCore`
- `TinyEvents.SqlServer.AdoNet`
- `TinyEvents.PostgreSql.EntityFrameworkCore`
- `TinyEvents.PostgreSql.AdoNet`
- `TinyEvents.Worker`

Other databases may be supported later through separate providers.

The SQL Server providers use SQL Server-specific claiming semantics, including SQL Server locking hints and atomic claim statements.
Each database family has its own provider package. SQL Server providers use SQL Server locking hints and atomic update/output statements. PostgreSQL providers use PostgreSQL claiming semantics, including `FOR UPDATE SKIP LOCKED` with update/returning statements.

EF Core publishing adds the outbox message to the caller's scoped `DbContext`. The caller commits business data and outbox messages with `SaveChangesAsync`.

Expand All @@ -178,29 +180,38 @@ TinyEvents owns the outbox schema definition. Applications own migration executi

EF Core applications should call `modelBuilder.UseTinyEventsOutbox()` and create normal EF migrations.

ADO.NET applications should use the provided SQL Server script:
ADO.NET applications should use the script helper for their database provider.

SQL Server:

```csharp
var sql = TinySqlServerAdoNetSchema.CreateOutboxSql();
```

The package also includes the default SQL script as package content:
PostgreSQL:

```csharp
var sql = TinyPostgreSqlAdoNetSchema.CreateOutboxSql();
```

The ADO.NET packages also include default SQL scripts as package content:

```text
schema/sqlserver/001_CreateTinyOutbox.sql
schema/postgresql/001_CreateTinyOutbox.sql
```

TinyEvents does not run migrations automatically.

## Run the samples

First start SQL Server with Docker:
Start the sample database containers with Docker:

```bash
docker compose up -d sqlserver
docker compose up -d sqlserver postgresql
```

Then run the EF Core sample:
Then run the SQL Server EF Core sample:

```bash
dotnet run --project samples/TinyEvents.Sample.EfCore
Expand All @@ -212,7 +223,19 @@ Or run the ADO.NET sample:
dotnet run --project samples/TinyEvents.Sample.AdoNet
```

The samples default to `TINYEVENTS_SAMPLE_SQLSERVER` or a command-line connection string. See [Samples](samples/README.md) for the full runbook and the package smoke sample.
Or run the PostgreSQL EF Core sample:

```bash
dotnet run --project samples/TinyEvents.Sample.PostgreSql.EfCore
```

Or run the PostgreSQL ADO.NET sample:

```bash
dotnet run --project samples/TinyEvents.Sample.PostgreSql.AdoNet
```

SQL Server samples default to `TINYEVENTS_SAMPLE_SQLSERVER`. PostgreSQL samples default to `TINYEVENTS_SAMPLE_POSTGRESQL`. All samples also accept a command-line connection string. See [Samples](samples/README.md) for the full runbook and the package smoke sample.

## Tiny suite

Expand Down Expand Up @@ -253,23 +276,28 @@ TinyEvents is intentionally small.
## Documentation

- [Getting Started](docs/getting-started.md)
- [EF Core Provider](docs/ef-core.md)
- [ADO.NET Provider](docs/ado-net.md)
- [EF Core Providers](docs/ef-core.md)
- [ADO.NET Providers](docs/ado-net.md)
- [SQL Server EF Core](docs/sql-server/ef-core.md)
- [SQL Server ADO.NET](docs/sql-server/ado-net.md)
- [PostgreSQL EF Core](docs/postgresql/ef-core.md)
- [PostgreSQL ADO.NET](docs/postgresql/ado-net.md)
- [Workers and Leases](docs/workers.md)
- [Schema and Migrations](docs/schema-and-migrations.md)
- [The Tiny Suite](docs/tiny-suite.md)
- [Source Generator](docs/source-generator.md)
- [Architecture](docs/architecture.md)
- [Testing](docs/testing.md)
- [Samples](samples/README.md)
- [Releasing](docs/releasing.md)
- [Roadmap](docs/roadmap.md)

## Current limitations

TinyEvents is an alpha.

- SQL Server is the only real database target in the current providers.
- SQL Server providers use SQL Server-specific atomic claiming.
- SQL Server and PostgreSQL are the current real database targets.
- Providers use database-specific atomic claiming.
- There is no claim heartbeat or renewal in v1.
- Long-running consumers must use a long enough `ClaimTimeout`.
- There is no migration runner.
Expand All @@ -286,7 +314,7 @@ The goal of the alpha is to validate:

- package boundaries
- generated registrations
- SQL Server provider behavior
- SQL Server and PostgreSQL provider behavior
- worker processing
- sample application ergonomics
- how TinyDispatcher, TinyValidations, and TinyEvents fit together as an application layer
Expand Down
Loading
Loading