Skip to content

Commit fa40a1c

Browse files
authored
Merge pull request #26 from SuessLabs/feature/GitHubBuilds
Build project via GitHub pipelines
2 parents 85da0da + 67430e9 commit fa40a1c

3 files changed

Lines changed: 215 additions & 79 deletions

File tree

build-github.yml

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
2+
name: Build, Test, Pack, Zip, and Publish
3+
4+
on:
5+
push:
6+
branches: [ master, develop ]
7+
pull_request:
8+
branches: [ master, develop ]
9+
10+
11+
jobs:
12+
build-test-pack:
13+
runs-on: windows-latest
14+
15+
env:
16+
# Update to desired major.minor. This is the base version family.
17+
BASE_VERSION: "1.1"
18+
19+
steps:
20+
# 1. Checkout source
21+
- name: Checkout repository
22+
uses: actions/checkout@v4
23+
with:
24+
fetch-depth: 0 # ensure tags/commits info is available when we expand logic later
25+
26+
# 2. Setup .NET SDK
27+
- name: Setup .NET
28+
uses: actions/setup-dotnet@v4
29+
with:
30+
dotnet-version: '10.0.x' # Change to your target version
31+
32+
# 3. Restore dependencies
33+
- name: Restore dependencies
34+
run: dotnet restore
35+
36+
# 4. Build solution
37+
- name: Build
38+
run: dotnet build --configuration Release --no-restore
39+
40+
# 5. Run tests
41+
- name: Test
42+
run: dotnet test --configuration Release --no-build --verbosity normal
43+
44+
# 6. Determin SemVersion package version
45+
- name: Determine version
46+
shell: pwsh
47+
run: |
48+
$branch = "${{ github.ref_name }}"
49+
$shortSha = (git rev-parse --short HEAD)
50+
$base = "${{ env.BASE_VERSION }}"
51+
$run = "${{ github.run_number }}"
52+
53+
if ($branch -eq "master") {
54+
# Stable versions on master
55+
$version = "$base.$run"
56+
$prerelease = ""
57+
}
58+
elseif ($branch -eq "develop") {
59+
# Pre-release versions on develop
60+
$version = "$base.$run-beta.$shortSha"
61+
$prerelease = "beta.$shortSha"
62+
}
63+
else {
64+
# Optional default for other branches
65+
$version = "$base.$run-alpha.$shortSha"
66+
$prerelease = "alpha.$shortSha"
67+
}
68+
69+
"PACKAGE_VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Append
70+
"VERSION_SUFFIX=$prerelease" | Out-File -FilePath $env:GITHUB_ENV -Append
71+
72+
Write-Host "Calculated PACKAGE_VERSION=$version"
73+
if ($prerelease) { Write-Host "Version suffix=$prerelease" }
74+
75+
# 7. Pack NuGet
76+
- name: Pack NuGet
77+
run: dotnet pack --configuration Release --no-build --output ./artifacts
78+
#- name: Pack NuGet
79+
# shell: pwsh
80+
# run: |
81+
# $version = "${{ env.PACKAGE_VERSION }}"
82+
# dotnet pack `
83+
# --configuration Release `
84+
# --no-build `
85+
# /p:PackageVersion=$version `
86+
# /p:Version=$version `
87+
# /p:IncludeSymbols=true /p:SymbolPackageFormat=snupkg `
88+
# --output ./artifacts
89+
90+
91+
# 8. Create ZIP of artifacts
92+
- name: Create ZIP archive
93+
run: |
94+
mkdir ./zip
95+
powershell Compress-Archive -Path ./artifacts/* -DestinationPath ./zip/artifacts.zip
96+
97+
#shell: pwsh
98+
#run: |
99+
# New-Item -ItemType Directory -Force -Path ./zip | Out-Null
100+
# Compress-Archive -Path ./artifacts/* -DestinationPath ./zip/artifacts.zip
101+
102+
# 9. Upload ZIP as workflow artifact
103+
- name: Upload ZIP
104+
uses: actions/upload-artifact@v4
105+
with:
106+
name: nuget-package-zip
107+
path: ./zip/artifacts.zip
108+
109+
## 10) Publish to NuGet.org (master branch, push events only)
110+
#- name: Publish to NuGet.org
111+
# if: github.ref_name == 'master' && github.event_name == 'push'
112+
# env:
113+
# NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
114+
# shell: pwsh
115+
# run: |
116+
# # Push .nupkg first
117+
# dotnet nuget push "./artifacts/*.nupkg" `
118+
# --source "https://api.nuget.org/v3/index.json" `
119+
# --api-key "$env:NUGET_API_KEY" `
120+
# --skip-duplicate `
121+
# --no-symbols # push symbols separately
122+
#
123+
# # Push symbols (.snupkg)
124+
# dotnet nuget push "./artifacts/*.snupkg" `
125+
# --source "https://api.nuget.org/v3/index.json" `
126+
# --api-key "$env:NUGET_API_KEY" `
127+
# --skip-duplicate

docs/history.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
## History
2+
3+
### v1.1.0
4+
5+
* Option to include `Microsoft.Extensions.Logger` for deep-logging
6+
7+
### v1.0.0
8+
9+
* [New] Renamed library to "Lite.EventIpc"
10+
* Library includes local Event Aggregator and remote IPC transports
11+
* [New] Removed relyance on reflection
12+
* [New] Added ability for local event timeouts.
13+
* This can happen when there are no subscribers, but you expect there to be one. Previously this was only available for "receipted" IPC transports.
14+
* [vNext] Receipted IPC Transports bumped to next version (_`IEventEnvelopeTransport` still exists, just not implemented_)
15+
* IPC Transport timeouts for 'Envelope' (receipted) messages
16+
17+
### v0.9.0
18+
19+
* Async publish + request/response
20+
* **Strongly-typed** internal wrappers (no reflection & no System.Linq)
21+
* **Timeout support** in RequestAsync
22+
* **Three IPC transports** _(Named Pipes, Memory-Mapped Files, TCP/IP)_
23+
* DI extensions + hosted service
24+
* **Unit tests**
25+
* **Full working demos** (one per transport)
26+
27+
* No reflection/linq path in handler dispatch�strongly-typed wrappers are used.
28+
* Weak references to delegates to avoid leaks.
29+
* Timeout support via RequestAsync parameter (default 5s).
30+
* Length-prefixed framing across pipe/tcp; EventWaitHandle for MMF.
31+
* DI-friendly + hosted service to start transport automatically.
32+
* Unit tests for local, timeout, and each transport.
33+
* Portable across .NET 7/8.
34+
35+
### v0.8.0
36+
37+
Evolved the Event Aggregator to support **async**, **bidirectional** request/response, and **pluggable IPC transports** via Named Pipes, Memory-Mapped Files, and TCP/IP Sockets.
38+
This design preserves your weak-reference handlers, remains DI-friendly, and keeps publishers decoupled from subscribers and transport mechanics.
39+
40+
> **Note:**
41+
> 1. The implementation intentionally straightforward. Not for production at this time as it needs robust error handling, retries, backpressure, queueing, auth/ACLs, and schema versioning.
42+
> 2. Consider bringing back `SendAsync<TEvent>(..)` and `StartAsync<TEvent>(..)` along side the new `IEventTransport` bi-directional sender/receivers.
43+
44+
* **`EventAggregator` (DI singleton):**
45+
* `PublishAsync<TEvent>(TEvent eventData)`
46+
* `RequestAsync<TRequest, TResponse>(TRequest request)`
47+
* `Subscribe<TEvent>(Action<TEvent> handler)` _(one-way)_
48+
* `SubscribeRequest<TRequest, TResponse>(Func<TRequest, Task<TResponse>> handler)` _(request/response)_
49+
* **`IEventTransport` (async, bi-directional):**
50+
* `StartAsync(Func<EventEnvelope, Task> onMessageAsync, CancellationToken ct)`
51+
* `SendAsync(EventEnvelope envelope, CancellationToken ct)`
52+
* `ReplyAddress { get; }` _(used by aggregator to populate ReplyTo for requests)_
53+
* **Transports:**
54+
* `NamedPipeTransport` _(duplex via named server/client pipes + length-prefix framing)_
55+
* `MemoryMappedTransport` _(two MMFs + named EventWaitHandles for request/response signals)_
56+
* `TcpTransport` _(two ports�one for requests, one for responses�with length-prefix framing)_
57+
58+
#### Future Improvements
59+
60+
* **Reliability:** Durable queues, consider MSMQ/Service Bus/RabbitMQ/Kafka depending on needs. (Out of scope for this lightweight first-pass.)
61+
* **Security:** Named Pipes can use ACLs; TCP needs TLS + auth; MMFs need OS ACLs. Add validation and schema versioning (i.e., `EventEnvelope`).
62+
* **Backpressure & Flow Control:** Implement bounded queues, retry, and exponential backoff where applicable.
63+
* **Type Resolution:** `AssemblyQualifiedName` assumes shared assemblies across processes. Consider a type registry or message contracts package shared by both sides.
64+
* **Framing:** Length-prefix framing prevents stream-boundary issues; keep consistent across transports.
65+
* **Concurrency:** The Memory-Mapped example is single-slot; for multiple writers/readers, implement a ring buffer or per-message files + directory watcher.
66+
* Add cancellation-aware timeouts and retry policies.
67+
* Provide a full two-process demo (client & server) for each transport so you can run them separately and see request/response in action.
68+
69+
### v0.7.0
70+
71+
Adds optional (one-way) IPC transport mechanisms for inter-process communication (IPC) with **JSON serialization**. IPC can be integrated with the `IEventTransport` interface.
72+
73+
* **Named Pipe** Transport
74+
* **Memory-Mapped File** Transport (_Windows OS only_)
75+
* **TCP/IP** Transport
76+
77+
### v0.6.0
78+
79+
* Uses **weak references** to avoid memory leaks
80+
* Cleans up dead references during `Publish`.
81+
* Prevents memory leaks when subscribers are no longer needed.
82+
83+
### v0.5.0
84+
85+
* Simple and thread-safe
86+
* Added example unit test for usage

readme.md

Lines changed: 2 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -52,86 +52,9 @@ If you store strong references to handlers, subscribers will never be collected.
5252

5353
## History
5454

55-
### v1.0.0
56-
57-
* [New] Renamed library to "Lite.EventIpc"
58-
* Library includes local Event Aggregator and remote IPC transports
59-
* [New] Removed relyance on reflection
60-
* [New] Added ability for local event timeouts.
61-
* This can happen when there are no subscribers, but you expect there to be one. Previously this was only available for "receipted" IPC transports.
62-
* [vNext] Receipted IPC Transports bumped to next version (_`IEventEnvelopeTransport` still exists, just not implemented_)
63-
* IPC Transport timeouts for 'Envelope' (receipted) messages
64-
65-
### v0.9.0
66-
67-
* Async publish + request/response
68-
* **Strongly-typed** internal wrappers (no reflection & no System.Linq)
69-
* **Timeout support** in RequestAsync
70-
* **Three IPC transports** _(Named Pipes, Memory-Mapped Files, TCP/IP)_
71-
* DI extensions + hosted service
72-
* **Unit tests**
73-
* **Full working demos** (one per transport)
74-
75-
* No reflection/linq path in handler dispatch�strongly-typed wrappers are used.
76-
* Weak references to delegates to avoid leaks.
77-
* Timeout support via RequestAsync parameter (default 5s).
78-
* Length-prefixed framing across pipe/tcp; EventWaitHandle for MMF.
79-
* DI-friendly + hosted service to start transport automatically.
80-
* Unit tests for local, timeout, and each transport.
81-
* Portable across .NET 7/8.
82-
83-
### v0.8.0
84-
85-
Evolved the Event Aggregator to support **async**, **bidirectional** request/response, and **pluggable IPC transports** via Named Pipes, Memory-Mapped Files, and TCP/IP Sockets.
86-
This design preserves your weak-reference handlers, remains DI-friendly, and keeps publishers decoupled from subscribers and transport mechanics.
87-
88-
> **Note:**
89-
> 1. The implementation intentionally straightforward. Not for production at this time as it needs robust error handling, retries, backpressure, queueing, auth/ACLs, and schema versioning.
90-
> 2. Consider bringing back `SendAsync<TEvent>(..)` and `StartAsync<TEvent>(..)` along side the new `IEventTransport` bi-directional sender/receivers.
91-
92-
* **`EventAggregator` (DI singleton):**
93-
* `PublishAsync<TEvent>(TEvent eventData)`
94-
* `RequestAsync<TRequest, TResponse>(TRequest request)`
95-
* `Subscribe<TEvent>(Action<TEvent> handler)` _(one-way)_
96-
* `SubscribeRequest<TRequest, TResponse>(Func<TRequest, Task<TResponse>> handler)` _(request/response)_
97-
* **`IEventTransport` (async, bi-directional):**
98-
* `StartAsync(Func<EventEnvelope, Task> onMessageAsync, CancellationToken ct)`
99-
* `SendAsync(EventEnvelope envelope, CancellationToken ct)`
100-
* `ReplyAddress { get; }` _(used by aggregator to populate ReplyTo for requests)_
101-
* **Transports:**
102-
* `NamedPipeTransport` _(duplex via named server/client pipes + length-prefix framing)_
103-
* `MemoryMappedTransport` _(two MMFs + named EventWaitHandles for request/response signals)_
104-
* `TcpTransport` _(two ports�one for requests, one for responses�with length-prefix framing)_
105-
106-
#### Future Improvements
107-
108-
* **Reliability:** Durable queues, consider MSMQ/Service Bus/RabbitMQ/Kafka depending on needs. (Out of scope for this lightweight first-pass.)
109-
* **Security:** Named Pipes can use ACLs; TCP needs TLS + auth; MMFs need OS ACLs. Add validation and schema versioning (i.e., `EventEnvelope`).
110-
* **Backpressure & Flow Control:** Implement bounded queues, retry, and exponential backoff where applicable.
111-
* **Type Resolution:** `AssemblyQualifiedName` assumes shared assemblies across processes. Consider a type registry or message contracts package shared by both sides.
112-
* **Framing:** Length-prefix framing prevents stream-boundary issues; keep consistent across transports.
113-
* **Concurrency:** The Memory-Mapped example is single-slot; for multiple writers/readers, implement a ring buffer or per-message files + directory watcher.
114-
* Add cancellation-aware timeouts and retry policies.
115-
* Provide a full two-process demo (client & server) for each transport so you can run them separately and see request/response in action.
116-
117-
### v0.7.0
118-
119-
Adds optional (one-way) IPC transport mechanisms for inter-process communication (IPC) with **JSON serialization**. IPC can be integrated with the `IEventTransport` interface.
120-
121-
* **Named Pipe** Transport
122-
* **Memory-Mapped File** Transport (_Windows OS only_)
123-
* **TCP/IP** Transport
124-
125-
### v0.6.0
55+
### v1.1.0
12656

127-
* Uses **weak references** to avoid memory leaks
128-
* Cleans up dead references during `Publish`.
129-
* Prevents memory leaks when subscribers are no longer needed.
130-
131-
### v0.5.0
132-
133-
* Simple and thread-safe
134-
* Added example unit test for usage
57+
* Option to include `Microsoft.Extensions.Logger` for deep-logging
13558

13659
## Future Considerations
13760

0 commit comments

Comments
 (0)