From f2f5fa17b5c6d581e260e5c590ffd30d59e0717c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 29 Jun 2024 13:51:40 +0300 Subject: [PATCH 1/3] Bump ws from 7.5.3 to 7.5.10 in /src/Saunter.UI (#215) Bumps [ws](https://github.com/websockets/ws) from 7.5.3 to 7.5.10. - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/7.5.3...7.5.10) --- updated-dependencies: - dependency-name: ws dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/Saunter.UI/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Saunter.UI/package-lock.json b/src/Saunter.UI/package-lock.json index 65b5c97..ed3f11c 100644 --- a/src/Saunter.UI/package-lock.json +++ b/src/Saunter.UI/package-lock.json @@ -2318,9 +2318,9 @@ } }, "node_modules/ws": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", - "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "engines": { "node": ">=8.3.0" }, @@ -4105,9 +4105,9 @@ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==" }, "ws": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", - "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "requires": {} }, "xml-name-validator": { From 24b915d8a2904857c4d3388851083e482e80616f Mon Sep 17 00:00:00 2001 From: smoerijf <51750688+smoerijf@users.noreply.github.com> Date: Sat, 29 Jun 2024 12:54:43 +0200 Subject: [PATCH 2/3] #213 [FEATURE] Allow usages of the annotation attributes on interfaces (#214) Co-authored-by: senn.g --- src/Saunter/Attributes/AsyncApiAttribute.cs | 4 +- src/Saunter/Attributes/ChannelAttribute.cs | 2 +- .../Attributes/ChannelParameterAttribute.cs | 2 +- src/Saunter/Attributes/OperationAttribute.cs | 2 +- .../ClassAttributesTests.cs | 127 +++++++++++++++--- .../InterfaceAttributeTests.cs | 107 +++++++++++++++ 6 files changed, 220 insertions(+), 24 deletions(-) create mode 100644 test/Saunter.Tests/Generation/DocumentGeneratorTests/InterfaceAttributeTests.cs diff --git a/src/Saunter/Attributes/AsyncApiAttribute.cs b/src/Saunter/Attributes/AsyncApiAttribute.cs index a886966..b92b3ba 100644 --- a/src/Saunter/Attributes/AsyncApiAttribute.cs +++ b/src/Saunter/Attributes/AsyncApiAttribute.cs @@ -3,9 +3,9 @@ namespace Saunter.Attributes { /// - /// Marks a class as containing asyncapi channels. + /// Marks a class or interface as containing asyncapi channels. /// - [AttributeUsage(AttributeTargets.Class)] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)] public sealed class AsyncApiAttribute : Attribute { public string DocumentName { get; } diff --git a/src/Saunter/Attributes/ChannelAttribute.cs b/src/Saunter/Attributes/ChannelAttribute.cs index b7ea022..de8939d 100644 --- a/src/Saunter/Attributes/ChannelAttribute.cs +++ b/src/Saunter/Attributes/ChannelAttribute.cs @@ -2,7 +2,7 @@ namespace Saunter.Attributes { - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)] + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Interface)] public class ChannelAttribute : Attribute { /// diff --git a/src/Saunter/Attributes/ChannelParameterAttribute.cs b/src/Saunter/Attributes/ChannelParameterAttribute.cs index d4301da..aab0c95 100644 --- a/src/Saunter/Attributes/ChannelParameterAttribute.cs +++ b/src/Saunter/Attributes/ChannelParameterAttribute.cs @@ -2,7 +2,7 @@ namespace Saunter.Attributes { - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)] + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true)] public class ChannelParameterAttribute : Attribute { public ChannelParameterAttribute(string name, Type type) diff --git a/src/Saunter/Attributes/OperationAttribute.cs b/src/Saunter/Attributes/OperationAttribute.cs index 99315b4..77f2662 100644 --- a/src/Saunter/Attributes/OperationAttribute.cs +++ b/src/Saunter/Attributes/OperationAttribute.cs @@ -2,7 +2,7 @@ namespace Saunter.Attributes { - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)] + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Interface)] public abstract class OperationAttribute : Attribute { public OperationType OperationType { get; protected set; } diff --git a/test/Saunter.Tests/Generation/DocumentGeneratorTests/ClassAttributesTests.cs b/test/Saunter.Tests/Generation/DocumentGeneratorTests/ClassAttributesTests.cs index 2e59b36..8fd8d2a 100644 --- a/test/Saunter.Tests/Generation/DocumentGeneratorTests/ClassAttributesTests.cs +++ b/test/Saunter.Tests/Generation/DocumentGeneratorTests/ClassAttributesTests.cs @@ -12,15 +12,17 @@ namespace Saunter.Tests.Generation.DocumentGeneratorTests { public class ClassAttributesTests { - [Fact] - public void GetDocument_GeneratesDocumentWithMultipleMessagesPerChannel() + [Theory] + [InlineData(typeof(TenantMessageConsumer))] + [InlineData(typeof(ITenantMessageConsumer))] + public void GetDocument_GeneratesDocumentWithMultipleMessagesPerChannel(Type type) { // Arrange var options = new AsyncApiOptions(); var documentGenerator = new DocumentGenerator(); // Act - var document = documentGenerator.GenerateDocument(new[] { typeof(TenantMessageConsumer).GetTypeInfo() }, options, options.AsyncApi, ActivatorServiceProvider.Instance); + var document = documentGenerator.GenerateDocument(new[] { type.GetTypeInfo() }, options, options.AsyncApi, ActivatorServiceProvider.Instance); // Assert document.ShouldNotBeNull(); @@ -44,15 +46,17 @@ public void GetDocument_GeneratesDocumentWithMultipleMessagesPerChannel() } - [Fact] - public void GenerateDocument_GeneratesDocumentWithMultipleMessagesPerChannelInTheSameMethod() + [Theory] + [InlineData(typeof(TenantGenericMessagePublisher))] + [InlineData(typeof(ITenantGenericMessagePublisher))] + public void GenerateDocument_GeneratesDocumentWithMultipleMessagesPerChannelInTheSameMethod(Type type) { // Arrange var options = new AsyncApiOptions(); var documentGenerator = new DocumentGenerator(); // Act - var document = documentGenerator.GenerateDocument(new[] { typeof(TenantGenericMessagePublisher).GetTypeInfo() }, options, options.AsyncApi, ActivatorServiceProvider.Instance); + var document = documentGenerator.GenerateDocument(new[] { type.GetTypeInfo() }, options, options.AsyncApi, ActivatorServiceProvider.Instance); // Assert document.ShouldNotBeNull(); @@ -76,15 +80,17 @@ public void GenerateDocument_GeneratesDocumentWithMultipleMessagesPerChannelInTh } - [Fact] - public void GenerateDocument_GeneratesDocumentWithSingleMessage() + [Theory] + [InlineData(typeof(TenantSingleMessagePublisher))] + [InlineData(typeof(ITenantSingleMessagePublisher))] + public void GenerateDocument_GeneratesDocumentWithSingleMessage(Type type) { // Arrange var options = new AsyncApiOptions(); var documentGenerator = new DocumentGenerator(); // Act - var document = documentGenerator.GenerateDocument(new[] { typeof(TenantSingleMessagePublisher).GetTypeInfo() }, options, options.AsyncApi, ActivatorServiceProvider.Instance); + var document = documentGenerator.GenerateDocument(new[] { type.GetTypeInfo() }, options, options.AsyncApi, ActivatorServiceProvider.Instance); // Assert document.ShouldNotBeNull(); @@ -104,8 +110,10 @@ public void GenerateDocument_GeneratesDocumentWithSingleMessage() } - [Fact] - public void GetDocument_WhenMultipleClassesUseSameChannelKey_GeneratesDocumentWithMultipleMessagesPerChannel() + [Theory] + [InlineData(typeof(TenantMessageConsumer), typeof(TenantMessagePublisher))] + [InlineData(typeof(ITenantMessageConsumer), typeof(ITenantMessagePublisher))] + public void GetDocument_WhenMultipleClassesUseSameChannelKey_GeneratesDocumentWithMultipleMessagesPerChannel(Type type1, Type type2) { // Arrange var options = new AsyncApiOptions(); @@ -114,8 +122,8 @@ public void GetDocument_WhenMultipleClassesUseSameChannelKey_GeneratesDocumentWi // Act var document = documentGenerator.GenerateDocument(new[] { - typeof(TenantMessageConsumer).GetTypeInfo(), - typeof(TenantMessagePublisher).GetTypeInfo() + type1.GetTypeInfo(), + type2.GetTypeInfo() }, options, options.AsyncApi, ActivatorServiceProvider.Instance); // Assert @@ -153,15 +161,17 @@ public void GetDocument_WhenMultipleClassesUseSameChannelKey_GeneratesDocumentWi } - [Fact] - public void GenerateDocument_GeneratesDocumentWithChannelParameters() + [Theory] + [InlineData(typeof(OneTenantMessageConsumer))] + [InlineData(typeof(IOneTenantMessageConsumer))] + public void GenerateDocument_GeneratesDocumentWithChannelParameters(Type type) { // Arrange var options = new AsyncApiOptions(); var documentGenerator = new DocumentGenerator(); // Act - var document = documentGenerator.GenerateDocument(new[] { typeof(OneTenantMessageConsumer).GetTypeInfo() }, options, options.AsyncApi, ActivatorServiceProvider.Instance); + var document = documentGenerator.GenerateDocument(new[] { type.GetTypeInfo() }, options, options.AsyncApi, ActivatorServiceProvider.Instance); // Assert document.ShouldNotBeNull(); @@ -188,15 +198,17 @@ public void GenerateDocument_GeneratesDocumentWithChannelParameters() } - [Fact] - public void GenerateDocument_GeneratesDocumentWithMessageHeader() + [Theory] + [InlineData(typeof(MyMessagePublisher))] + [InlineData(typeof(IMyMessagePublisher))] + public void GenerateDocument_GeneratesDocumentWithMessageHeader(Type type) { // Arrange var options = new AsyncApiOptions(); var documentGenerator = new DocumentGenerator(); // Act - var document = documentGenerator.GenerateDocument(new[] { typeof(MyMessagePublisher).GetTypeInfo() }, options, options.AsyncApi, ActivatorServiceProvider.Instance); + var document = documentGenerator.GenerateDocument(new[] { type.GetTypeInfo() }, options, options.AsyncApi, ActivatorServiceProvider.Instance); // Assert document.ShouldNotBeNull(); @@ -216,6 +228,15 @@ public class MyMessagePublisher public void PublishMyMessage() { } } + [AsyncApi] + [Channel("channel.my.message")] + [PublishOperation] + public interface IMyMessagePublisher + { + [Message(typeof(MyMessage), HeadersType = typeof(MyMessageHeader))] + void PublishMyMessage(); + } + [AsyncApi] [Channel("asw.tenant_service.tenants_history", Description = "Tenant events.")] [SubscribeOperation(OperationId = "TenantMessageConsumer", Summary = "Subscribe to domains events about tenants.")] @@ -231,6 +252,21 @@ public void SubscribeTenantUpdatedEvent(Guid _, TenantUpdated __) { } public void SubscribeTenantRemovedEvent(Guid _, TenantRemoved __) { } } + [AsyncApi] + [Channel("asw.tenant_service.tenants_history", Description = "Tenant events.")] + [SubscribeOperation(OperationId = "TenantMessageConsumer", Summary = "Subscribe to domains events about tenants.")] + public interface ITenantMessageConsumer + { + [Message(typeof(TenantCreated))] + void SubscribeTenantCreatedEvent(Guid _, TenantCreated __); + + [Message(typeof(TenantUpdated))] + void SubscribeTenantUpdatedEvent(Guid _, TenantUpdated __); + + [Message(typeof(TenantRemoved))] + void SubscribeTenantRemovedEvent(Guid _, TenantRemoved __); + } + [AsyncApi] [Channel("asw.tenant_service.tenants_history", Description = "Tenant events.")] [PublishOperation(OperationId = "TenantMessagePublisher", Summary = "Publish domains events about tenants.")] @@ -246,6 +282,21 @@ public void PublishTenantUpdatedEvent(Guid _, TenantUpdated __) { } public void PublishTenantRemovedEvent(Guid _, TenantRemoved __) { } } + [AsyncApi] + [Channel("asw.tenant_service.tenants_history", Description = "Tenant events.")] + [PublishOperation(OperationId = "TenantMessagePublisher", Summary = "Publish domains events about tenants.")] + public interface ITenantMessagePublisher + { + [Message(typeof(TenantCreated))] + void PublishTenantCreatedEvent(Guid _, TenantCreated __); + + [Message(typeof(TenantUpdated))] + void PublishTenantUpdatedEvent(Guid _, TenantUpdated __); + + [Message(typeof(TenantRemoved))] + void PublishTenantRemovedEvent(Guid _, TenantRemoved __); + } + [AsyncApi] [Channel("asw.tenant_service.tenants_history", Description = "Tenant events.")] [PublishOperation(OperationId = "TenantMessagePublisher", Summary = "Publish domains events about tenants.")] @@ -260,6 +311,18 @@ public void PublishTenantEvent(Guid _, TEvent __) } } + [AsyncApi] + [Channel("asw.tenant_service.tenants_history", Description = "Tenant events.")] + [PublishOperation(OperationId = "TenantMessagePublisher", Summary = "Publish domains events about tenants.")] + public interface ITenantGenericMessagePublisher + { + [Message(typeof(AnyTenantCreated))] + [Message(typeof(AnyTenantUpdated))] + [Message(typeof(AnyTenantRemoved))] + void PublishTenantEvent(Guid _, TEvent __) + where TEvent : IEvent; + } + [AsyncApi] [Channel("asw.tenant_service.tenants_history", Description = "Tenant events.")] [PublishOperation(OperationId = "TenantSingleMessagePublisher", Summary = "Publish single domain event about tenants.")] @@ -271,6 +334,15 @@ public void PublishTenantCreated(Guid _, AnyTenantCreated __) } } + [AsyncApi] + [Channel("asw.tenant_service.tenants_history", Description = "Tenant events.")] + [PublishOperation(OperationId = "TenantSingleMessagePublisher", Summary = "Publish single domain event about tenants.")] + public interface ITenantSingleMessagePublisher + { + [Message(typeof(AnyTenantCreated))] + public void PublishTenantCreated(Guid _, AnyTenantCreated __); + } + [AsyncApi] [Channel("asw.tenant_service.{tenant_id}.{tenant_status}", Description = "A tenant events.")] [ChannelParameter("tenant_id", typeof(long), Description = "The tenant identifier.")] @@ -287,6 +359,23 @@ public void SubscribeTenantUpdatedEvent(Guid _, TenantUpdated __) { } [Message(typeof(TenantRemoved))] public void SubscribeTenantRemovedEvent(Guid _, TenantRemoved __) { } } + + [AsyncApi] + [Channel("asw.tenant_service.{tenant_id}.{tenant_status}", Description = "A tenant events.")] + [ChannelParameter("tenant_id", typeof(long), Description = "The tenant identifier.")] + [ChannelParameter("tenant_status", typeof(string), Description = "The tenant status.")] + [SubscribeOperation(OperationId = "OneTenantMessageConsumer", Summary = "Subscribe to domains events about a tenant.")] + public interface IOneTenantMessageConsumer + { + [Message(typeof(TenantCreated))] + void SubscribeTenantCreatedEvent(Guid _, TenantCreated __); + + [Message(typeof(TenantUpdated))] + void SubscribeTenantUpdatedEvent(Guid _, TenantUpdated __); + + [Message(typeof(TenantRemoved))] + void SubscribeTenantRemovedEvent(Guid _, TenantRemoved __); + } } public class TenantCreated { } diff --git a/test/Saunter.Tests/Generation/DocumentGeneratorTests/InterfaceAttributeTests.cs b/test/Saunter.Tests/Generation/DocumentGeneratorTests/InterfaceAttributeTests.cs new file mode 100644 index 0000000..a518389 --- /dev/null +++ b/test/Saunter.Tests/Generation/DocumentGeneratorTests/InterfaceAttributeTests.cs @@ -0,0 +1,107 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Reflection; +using Saunter.AsyncApiSchema.v2; +using Saunter.Attributes; +using Saunter.Generation; +using Shouldly; +using Xunit; +using System.Linq; + +namespace Saunter.Tests.Generation.DocumentGeneratorTests +{ + public class InterfaceAttributeTests + { + [Theory] + [InlineData(typeof(IServiceEvents))] + [InlineData(typeof(ServiceEventsFromInterface))] + [InlineData(typeof(ServiceEventsFromAnnotatedInterface))] // Check that annotations are not inherited from the interface + public void NonAnnotatedTypesTest(Type type) + { + // Arrange + var options = new AsyncApiOptions(); + var documentGenerator = new DocumentGenerator(); + + // Act + var document = documentGenerator.GenerateDocument(new[] { type.GetTypeInfo() }, options, options.AsyncApi, ActivatorServiceProvider.Instance); + + // Assert + document.ShouldNotBeNull(); + document.Channels.Count.ShouldBe(0); + } + + [Theory] + [InlineData(typeof(IAnnotatedServiceEvents), "interface")] + [InlineData(typeof(AnnotatedServiceEventsFromInterface), "class")] + [InlineData(typeof(AnnotatedServiceEventsFromAnnotatedInterface), "class")] // Check that the actual type's annotation takes precedence of the inherited interface + public void AnnotatedTypesTest(Type type, string source) + { + // Arrange + var options = new AsyncApiOptions(); + var documentGenerator = new DocumentGenerator(); + + // Act + var document = documentGenerator.GenerateDocument(new[] { type.GetTypeInfo() }, options, options.AsyncApi, ActivatorServiceProvider.Instance); + + // Assert + document.ShouldNotBeNull(); + document.Channels.Count.ShouldBe(1); + + var channel = document.Channels.First(); + channel.Key.ShouldBe($"{source}.event"); + channel.Value.Description.ShouldBeNull(); + + var publish = channel.Value.Publish; + publish.ShouldNotBeNull(); + publish.OperationId.ShouldBe("PublishEvent"); + publish.Description.ShouldBe($"({source}) Subscribe to domains events about a tenant."); + + var messageRef = publish.Message.ShouldBeOfType(); + messageRef.Id.ShouldBe("tenantEvent"); + } + + [AsyncApi] + private interface IAnnotatedServiceEvents + { + [Channel("interface.event")] + [PublishOperation(typeof(TenantEvent), Description = "(interface) Subscribe to domains events about a tenant.")] + void PublishEvent(TenantEvent evt); + } + + private interface IServiceEvents + { + void PublishEvent(TenantEvent evt); + } + + private class ServiceEventsFromInterface : IServiceEvents + { + public void PublishEvent(TenantEvent evt) { } + } + + private class ServiceEventsFromAnnotatedInterface : IAnnotatedServiceEvents + { + public void PublishEvent(TenantEvent evt) { } + } + + [AsyncApi] + private class AnnotatedServiceEventsFromInterface : IAnnotatedServiceEvents + { + [Channel("class.event")] + [PublishOperation(typeof(TenantEvent), Description = "(class) Subscribe to domains events about a tenant.")] + public void PublishEvent(TenantEvent evt) { } + } + + [AsyncApi] + private class AnnotatedServiceEventsFromAnnotatedInterface : IAnnotatedServiceEvents + { + [Channel("class.event")] + [PublishOperation(typeof(TenantEvent), Description = "(class) Subscribe to domains events about a tenant.")] + public void PublishEvent(TenantEvent evt) { } + } + + private class TenantEvent { } + } +} From 6a3441d109ec292312f4fe5516073678c510cdc3 Mon Sep 17 00:00:00 2001 From: yurvon-screamo <109030262+yurvon-screamo@users.noreply.github.com> Date: Mon, 8 Jul 2024 12:36:04 +0300 Subject: [PATCH 3/3] Check unit, fmt, build on ci (#211) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Dotnet format jobs * Dotnet format job - fix cmd * CI - build, test + fmt ci * CI - build, test + fmt ci * CI - build, test + fmt ci * CI - build, test + fmt ci * CI - build, test + fmt ci * fmt sln * fmt docs * CI: only main * Remove fmt tool * Add inner editorconfig on test * Add inner editorconfig on test --------- Co-authored-by: Юрий Турбин --- .github/dotnet/action.yaml | 10 ++++ .github/npm/action.yaml | 14 +++++ .github/workflows/ci.yaml | 54 ++++++++++--------- .github/workflows/release.yaml | 48 +++++------------ CONTRIBUTING.md | 3 +- Saunter.sln | 22 ++++++-- .../.editorconfig | 7 +++ test/Saunter.Tests/.editorconfig | 7 +++ .../ClassAttributesTests.cs | 22 ++++---- 9 files changed, 110 insertions(+), 77 deletions(-) create mode 100644 .github/dotnet/action.yaml create mode 100644 .github/npm/action.yaml create mode 100644 test/Saunter.Tests.MarkerTypeTests/.editorconfig create mode 100644 test/Saunter.Tests/.editorconfig diff --git a/.github/dotnet/action.yaml b/.github/dotnet/action.yaml new file mode 100644 index 0000000..47858e0 --- /dev/null +++ b/.github/dotnet/action.yaml @@ -0,0 +1,10 @@ +name: dotnet setup +description: "base dotnet setup for project" +runs: + using: composite + steps: + - name: setup + id: setup-dotnet + uses: actions/setup-dotnet@v1 + with: + dotnet-version: "6.0.x" diff --git a/.github/npm/action.yaml b/.github/npm/action.yaml new file mode 100644 index 0000000..a35897e --- /dev/null +++ b/.github/npm/action.yaml @@ -0,0 +1,14 @@ +name: npm setup +description: "base npm setup for project" +runs: + using: composite + steps: + - name: setup dotnet + uses: ./.github/dotnet + - uses: actions/setup-node@v3 + with: + node-version: "lts/*" + - name: Run NPM install + shell: sh + run: npm ci + working-directory: ./src/Saunter.UI diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index bf47024..b9ab2a6 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,7 +1,4 @@ -# Note: ci.yaml and release.yaml have some similar steps -# If updating dotnet-version, set in both. - -name: CI +name: ci on: push: @@ -10,30 +7,35 @@ on: pull_request: jobs: - build: + build: runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - uses: actions/setup-node@v3 - with: - node-version: 'lts/*' # latest LTS version - - uses: actions/setup-dotnet@v2 - with: - dotnet-version: '6.0.x' # SDK Version to use; x will use the latest version of the channel + - uses: actions/checkout@v2 + - name: setup build + uses: ./.github/npm + - name: Run dotnet build + run: dotnet build --configuration Debug - - name: Run NPM install - run: npm ci - working-directory: ./src/Saunter.UI - - name: Run dotnet build - run: dotnet build --configuration Debug - - name: Run dotnet test - run: dotnet test --no-build + fmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: setup dotnet + uses: ./.github/dotnet + - name: dotnet format check + run: dotnet format --verify-no-changes *.sln + env: + PATH: ${{ github.env.PATH }}:/home/runner/.dotnet/tools - # Below steps run only on CI, not release - - uses: actions/upload-artifact@v2 - with: - name: saunter-bin - path: ./src/Saunter/bin + unit-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: setup build + uses: ./.github/npm + - name: unit test + run: dotnet test ./test/Saunter.Tests/Saunter.Tests.csproj + # TODO: why there are 2 of them.... + - name: unit mark test + run: dotnet test ./test/Saunter.Tests.MarkerTypeTests/Saunter.Tests.MarkerTypeTests.csproj diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 836b03d..c1c3310 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,45 +1,23 @@ -# Note: ci.yaml and release.yaml have some similar steps -# If updating dotnet-version, set in both. - name: Release on: push: tags: - - 'v*.*.*' # e.g. v0.1.0 + - "v*.*.*" # e.g. v0.1.0 jobs: release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - uses: actions/setup-node@v3 - with: - node-version: 'lts/*' # latest LTS version - - uses: actions/setup-dotnet@v2 - with: - dotnet-version: '6.0.x' # SDK Version to use; x will use the latest version of the channel - - - name: Run NPM install - run: npm ci - working-directory: ./src/Saunter.UI - - name: Run dotnet build - run: dotnet build --configuration Debug - - name: Run dotnet test - run: dotnet test --no-build - - # Below steps are only on release, not CI. - - name: Set version - # Gets the numeric version from a tag (e.g. v1.2.3 -> 1.2.3) - run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV - - name: Create Nuget package - run: dotnet pack ./src/Saunter/Saunter.csproj --configuration Release -p:Version="$RELEASE_VERSION" --output ./build - - name: Push Nuget package to Nuget.org - env: - NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} - run: dotnet nuget push ./build/*.nupkg --api-key $NUGET_API_KEY --source "https://api.nuget.org/v3/index.json" - - + - uses: actions/checkout@v2 + - name: setup build + uses: ./.github/npm + - name: Set version + # Gets the numeric version from a tag (e.g. v1.2.3 -> 1.2.3) + run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV + - name: Create Nuget package + run: dotnet pack ./src/Saunter/Saunter.csproj --configuration Release -p:Version="$RELEASE_VERSION" --output ./build + - name: Push Nuget package to Nuget.org + env: + NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} + run: dotnet nuget push ./build/*.nupkg --api-key $NUGET_API_KEY --source "https://api.nuget.org/v3/index.json" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e35bd6f..ce12592 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,11 +10,10 @@ Builds and releases managed with github actions. ### Build * Local builds are as simple as `dotnet build && dotnet test` -* CI builds on every push +* CI builds,fmt,unit on every push * [.github/workflows/ci.yaml](./.github/workflows/ci.yaml) * Build and tests MUST pass before merging to master - ### Release * Locally, packages can be created using `dotnet pack ./src/Saunter/Saunter.csproj` diff --git a/Saunter.sln b/Saunter.sln index 4627766..038ce2f 100644 --- a/Saunter.sln +++ b/Saunter.sln @@ -15,19 +15,33 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{6A EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StreetlightsAPI", "examples\StreetlightsAPI\StreetlightsAPI.csproj", "{F188D4A7-BBCB-464F-A370-2BD84D18EA79}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E0D34C77-924E-4F6B-9289-5A2F07D125A8}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{E0D34C77-924E-4F6B-9289-5A2F07D125A8}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig CHANGELOG.md = CHANGELOG.md - .github\workflows\ci.yaml = .github\workflows\ci.yaml README.md = README.md - .github\workflows\release.yaml = .github\workflows\release.yaml EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Saunter.IntegrationTests.ReverseProxy", "test\Saunter.IntegrationTests.ReverseProxy\Saunter.IntegrationTests.ReverseProxy.csproj", "{7CD09B89-130A-41AF-ADAE-2166C4ED695B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Saunter.Tests.MarkerTypeTests", "test\Saunter.Tests.MarkerTypeTests\Saunter.Tests.MarkerTypeTests.csproj", "{02284473-6DE7-4EE0-8433-2AC295045549}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "actions", "actions", "{D8CB9C0D-9605-457B-979F-C8994B20A926}" + ProjectSection(SolutionItems) = preProject + .github\workflows\ci.yaml = .github\workflows\ci.yaml + .github\workflows\release.yaml = .github\workflows\release.yaml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dotnet", "dotnet", "{69459F9D-DA73-4E84-8BA7-4CE03E2B7664}" + ProjectSection(SolutionItems) = preProject + .github\dotnet\action.yaml = .github\dotnet\action.yaml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "npm", "npm", "{E8FACA22-CFED-4710-89E4-D55F31BF96B3}" + ProjectSection(SolutionItems) = preProject + .github\npm\action.yaml = .github\npm\action.yaml + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -108,6 +122,8 @@ Global {F188D4A7-BBCB-464F-A370-2BD84D18EA79} = {6ABD4842-47AF-49A5-B057-0EBA64416789} {7CD09B89-130A-41AF-ADAE-2166C4ED695B} = {6491E321-2D02-44AB-9116-D722FE169595} {02284473-6DE7-4EE0-8433-2AC295045549} = {6491E321-2D02-44AB-9116-D722FE169595} + {69459F9D-DA73-4E84-8BA7-4CE03E2B7664} = {D8CB9C0D-9605-457B-979F-C8994B20A926} + {E8FACA22-CFED-4710-89E4-D55F31BF96B3} = {D8CB9C0D-9605-457B-979F-C8994B20A926} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2F85D9DA-DBCF-4F13-8C42-5719F1469B2E} diff --git a/test/Saunter.Tests.MarkerTypeTests/.editorconfig b/test/Saunter.Tests.MarkerTypeTests/.editorconfig new file mode 100644 index 0000000..0f18a2d --- /dev/null +++ b/test/Saunter.Tests.MarkerTypeTests/.editorconfig @@ -0,0 +1,7 @@ +# EditorConfig is awesome: https://EditorConfig.org + +root=false + +[*.{cs,vb}] + +dotnet_code_quality_unused_parameters = non_public diff --git a/test/Saunter.Tests/.editorconfig b/test/Saunter.Tests/.editorconfig new file mode 100644 index 0000000..0f18a2d --- /dev/null +++ b/test/Saunter.Tests/.editorconfig @@ -0,0 +1,7 @@ +# EditorConfig is awesome: https://EditorConfig.org + +root=false + +[*.{cs,vb}] + +dotnet_code_quality_unused_parameters = non_public diff --git a/test/Saunter.Tests/Generation/DocumentGeneratorTests/ClassAttributesTests.cs b/test/Saunter.Tests/Generation/DocumentGeneratorTests/ClassAttributesTests.cs index 8fd8d2a..c384d64 100644 --- a/test/Saunter.Tests/Generation/DocumentGeneratorTests/ClassAttributesTests.cs +++ b/test/Saunter.Tests/Generation/DocumentGeneratorTests/ClassAttributesTests.cs @@ -243,13 +243,13 @@ public interface IMyMessagePublisher public class TenantMessageConsumer { [Message(typeof(TenantCreated))] - public void SubscribeTenantCreatedEvent(Guid _, TenantCreated __) { } + public void SubscribeTenantCreatedEvent(Guid id, TenantCreated created) { } [Message(typeof(TenantUpdated))] - public void SubscribeTenantUpdatedEvent(Guid _, TenantUpdated __) { } + public void SubscribeTenantUpdatedEvent(Guid id, TenantUpdated updated) { } [Message(typeof(TenantRemoved))] - public void SubscribeTenantRemovedEvent(Guid _, TenantRemoved __) { } + public void SubscribeTenantRemovedEvent(Guid id, TenantRemoved removed) { } } [AsyncApi] @@ -273,13 +273,13 @@ public interface ITenantMessageConsumer public class TenantMessagePublisher { [Message(typeof(TenantCreated))] - public void PublishTenantCreatedEvent(Guid _, TenantCreated __) { } + public void PublishTenantCreatedEvent(Guid id, TenantCreated created) { } [Message(typeof(TenantUpdated))] - public void PublishTenantUpdatedEvent(Guid _, TenantUpdated __) { } + public void PublishTenantUpdatedEvent(Guid id, TenantUpdated updated) { } [Message(typeof(TenantRemoved))] - public void PublishTenantRemovedEvent(Guid _, TenantRemoved __) { } + public void PublishTenantRemovedEvent(Guid id, TenantRemoved removed) { } } [AsyncApi] @@ -305,7 +305,7 @@ public class TenantGenericMessagePublisher [Message(typeof(AnyTenantCreated))] [Message(typeof(AnyTenantUpdated))] [Message(typeof(AnyTenantRemoved))] - public void PublishTenantEvent(Guid _, TEvent __) + public void PublishTenantEvent(Guid id, TEvent @event) where TEvent : IEvent { } @@ -329,7 +329,7 @@ void PublishTenantEvent(Guid _, TEvent __) public class TenantSingleMessagePublisher { [Message(typeof(AnyTenantCreated))] - public void PublishTenantCreated(Guid _, AnyTenantCreated __) + public void PublishTenantCreated(Guid id, AnyTenantCreated created) { } } @@ -351,13 +351,13 @@ public interface ITenantSingleMessagePublisher public class OneTenantMessageConsumer { [Message(typeof(TenantCreated))] - public void SubscribeTenantCreatedEvent(Guid _, TenantCreated __) { } + public void SubscribeTenantCreatedEvent(Guid id, TenantCreated created) { } [Message(typeof(TenantUpdated))] - public void SubscribeTenantUpdatedEvent(Guid _, TenantUpdated __) { } + public void SubscribeTenantUpdatedEvent(Guid id, TenantUpdated updated) { } [Message(typeof(TenantRemoved))] - public void SubscribeTenantRemovedEvent(Guid _, TenantRemoved __) { } + public void SubscribeTenantRemovedEvent(Guid id, TenantRemoved removed) { } } [AsyncApi]