From f52b7e7f89f7b4ed9c9a86f0a6d52572cc84482e Mon Sep 17 00:00:00 2001 From: Ayrat Hudaygulov Date: Fri, 14 Jun 2024 16:22:24 +0100 Subject: [PATCH 01/14] added some tests! --- .gitignore | 1 + Dockerfile | 6 + README.md | 10 +- init.sql | 6 + src/VahterBanBot.Tests/ContainerTestBase.fs | 137 ++++++++++++++++++ src/VahterBanBot.Tests/Program.fs | 7 + src/VahterBanBot.Tests/Tests.fs | 37 +++++ .../VahterBanBot.Tests.fsproj | 29 ++++ src/VahterBanBot/Program.fs | 24 +-- src/VahterBanBot/StartupMessage.fs | 41 ++++++ src/VahterBanBot/VahterBanBot.fsproj | 1 + vahter-ban-bot.sln | 7 + 12 files changed, 274 insertions(+), 32 deletions(-) create mode 100644 init.sql create mode 100644 src/VahterBanBot.Tests/ContainerTestBase.fs create mode 100644 src/VahterBanBot.Tests/Program.fs create mode 100644 src/VahterBanBot.Tests/Tests.fs create mode 100644 src/VahterBanBot.Tests/VahterBanBot.Tests.fsproj create mode 100644 src/VahterBanBot/StartupMessage.fs diff --git a/.gitignore b/.gitignore index b94f593..163764f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ .idea .env flyway.conf +*sln.DotSettings.user \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 039349e..ba7cd73 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,10 @@ FROM mcr.microsoft.com/dotnet/sdk:7.0.402-jammy as build-env + +### workaround for testcontainers resource reaper issue +ARG RESOURCE_REAPER_SESSION_ID="00000000-0000-0000-0000-000000000000" +LABEL "org.testcontainers.resource-reaper-session"=$RESOURCE_REAPER_SESSION_ID +### end of workaround + WORKDIR /src/VahterBanBot COPY src/VahterBanBot/VahterBanBot.fsproj . RUN dotnet restore diff --git a/README.md b/README.md index 05f3be1..ea43b97 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,5 @@ Database setup - -```postgresql -CREATE ROLE vahter_bot_ban_service WITH LOGIN PASSWORD 'vahter_bot_ban_service'; -GRANT vahter_bot_ban_service TO postgres; -CREATE DATABASE vahter_bot_ban OWNER vahter_bot_ban_service ENCODING 'UTF8'; -GRANT ALL ON DATABASE vahter_bot_ban TO vahter_bot_ban_service; -GRANT USAGE, CREATE ON SCHEMA public TO vahter_bot_ban_service; -CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -``` +- run init.sql Run migrations diff --git a/init.sql b/init.sql new file mode 100644 index 0000000..c9982b8 --- /dev/null +++ b/init.sql @@ -0,0 +1,6 @@ +CREATE ROLE vahter_bot_ban_service WITH LOGIN PASSWORD 'vahter_bot_ban_service'; +GRANT vahter_bot_ban_service TO postgres; +CREATE DATABASE vahter_bot_ban OWNER vahter_bot_ban_service ENCODING 'UTF8'; +GRANT ALL ON DATABASE vahter_bot_ban TO vahter_bot_ban_service; +GRANT USAGE, CREATE ON SCHEMA public TO vahter_bot_ban_service; +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; diff --git a/src/VahterBanBot.Tests/ContainerTestBase.fs b/src/VahterBanBot.Tests/ContainerTestBase.fs new file mode 100644 index 0000000..632833e --- /dev/null +++ b/src/VahterBanBot.Tests/ContainerTestBase.fs @@ -0,0 +1,137 @@ +module VahterBanBot.Tests.ContainerTestBase + +open System +open System.IO +open System.Net.Http +open System.Text +open DotNet.Testcontainers.Builders +open DotNet.Testcontainers.Configurations +open DotNet.Testcontainers.Containers +open Newtonsoft.Json +open Telegram.Bot.Types +open Testcontainers.PostgreSql +open Xunit + +type VahterTestContainers() = + let solutionDir = CommonDirectoryPath.GetSolutionDirectory() + let dbAlias = "vahter-db" + let pgImage = "postgres:15.6" // same as in Azure + + // will be filled in IAsyncLifetime.InitializeAsync + let mutable uri: Uri = null + let mutable httpClient: HttpClient = null + + // base image for the app, we'll build exactly how we build it in Azure + let image = + ImageFromDockerfileBuilder() + .WithDockerfileDirectory(solutionDir, String.Empty) + .WithDockerfile("./Dockerfile") + .WithName("vahter-bot-ban-test") + // workaround for multi-stage builds cleanup + .WithBuildArgument("RESOURCE_REAPER_SESSION_ID", ResourceReaper.DefaultSessionId.ToString("D")) + // it might speed up the process to not clean up the base image + .WithCleanUp(false) + .Build() + + // private network for the containers + let network = + NetworkBuilder() + .Build() + + // PostgreSQL container. Important to have the same image as in Azure + // and assign network alias to it as it will be "host" in DB connection string for the app + let dbContainer = + PostgreSqlBuilder() + .WithImage(pgImage) + .WithNetwork(network) + .WithNetworkAliases(dbAlias) + .Build() + + // Flyway container to run migrations + let flywayContainer = + ContainerBuilder() + .WithImage("redgate/flyway") + .WithNetwork(network) + .WithBindMount(CommonDirectoryPath.GetSolutionDirectory().DirectoryPath + "/src/migrations", "/flyway/sql", AccessMode.ReadOnly) + .WithEnvironment("FLYWAY_URL", "jdbc:postgresql://vahter-db:5432/vahter_bot_ban") + .WithEnvironment("FLYWAY_USER", "vahter_bot_ban_service") + .WithEnvironment("FLYWAY_PASSWORD", "vahter_bot_ban_service") + .WithCommand("migrate", "-schemas=public") + .WithWaitStrategy(Wait.ForUnixContainer().UntilMessageIsLogged("Successfully applied \d+ migrations")) + .DependsOn(dbContainer) + .Build() + + // the app container + // we'll pass all the necessary environment variables to it + let appContainer = + ContainerBuilder() + .WithImage(image) + .WithNetwork(network) + .WithPortBinding(80, true) + .WithEnvironment("BOT_TELEGRAM_TOKEN", "TELEGRAM_SECRET") + .WithEnvironment("BOT_AUTH_TOKEN", "OUR_SECRET") + .WithEnvironment("LOGS_CHANNEL_ID", "-123") + .WithEnvironment("CHATS_TO_MONITOR", """{"pro.hell": -666, "dotnetru": -42}""") + .WithEnvironment("ALLOWED_USERS", """{"vahter_1": 34, "vahter_2": 69}""") + .WithEnvironment("SHOULD_DELETE_CHANNEL_MESSAGES", "true") + .WithEnvironment("IGNORE_SIDE_EFFECTS", "false") + .WithEnvironment("USE_POLLING", "false") + .WithEnvironment("DATABASE_URL", $"Server={dbAlias};Database=vahter_bot_ban;Port=5432;User Id=vahter_bot_ban_service;Password=vahter_bot_ban_service;Include Error Detail=true;Minimum Pool Size=1;Maximum Pool Size=20;Max Auto Prepare=100;Auto Prepare Min Usages=1;Trust Server Certificate=true;") + .DependsOn(flywayContainer) + .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(80)) + .Build() + + interface IAsyncLifetime with + member this.InitializeAsync() = task { + // start building the image and spin up db at the same time + let imageTask = image.CreateAsync() + let dbTask = dbContainer.StartAsync() + + // wait for both to finish + do! imageTask + do! dbTask + + // initialize DB with the schema, database and a DB user + let script = File.ReadAllText(CommonDirectoryPath.GetSolutionDirectory().DirectoryPath + "/init.sql") + let! initResult = dbContainer.ExecScriptAsync(script) + if initResult.Stderr <> "" then + failwith initResult.Stderr + + // run migrations + do! flywayContainer.StartAsync() + + // seed some test data + // inserting the only admin users we have + // TODO might be a script in test assembly + let! _ = dbContainer.ExecAsync([|"""INSERT INTO "user"(id, username, banned_by, banned_at, ban_reason) VALUES (34, 'vahter_1', NULL, NULL, NULL), (69, 'vahter_2', NULL, NULL, NULL);"""|]) + + // start the app container + do! appContainer.StartAsync() + + // initialize the http client with correct hostname and port + httpClient <- new HttpClient() + uri <- Uri($"http://{appContainer.Hostname}:{appContainer.GetMappedPublicPort(80)}") + httpClient.BaseAddress <- uri + httpClient.DefaultRequestHeaders.Add("X-Telegram-Bot-Api-Secret-Token", "OUR_SECRET") + } + member this.DisposeAsync() = task { + // stop all the containers, flyway might be dead already + do! flywayContainer.DisposeAsync() + do! appContainer.DisposeAsync() + do! dbContainer.DisposeAsync() + // do! image.DisposeAsync() // might be faster not to dispose base image to cache? + } + + member _.Http = httpClient + member _.Uri = uri + + member this.SendMessage(update: Update) = task { + let json = JsonConvert.SerializeObject(update) + return! this.SendMessage(json) + } + + member _.SendMessage(json: string) = task { + let content = new StringContent(json, Encoding.UTF8, "application/json") + let! resp = httpClient.PostAsync("/bot", content) + return resp + } diff --git a/src/VahterBanBot.Tests/Program.fs b/src/VahterBanBot.Tests/Program.fs new file mode 100644 index 0000000..6bc27f8 --- /dev/null +++ b/src/VahterBanBot.Tests/Program.fs @@ -0,0 +1,7 @@ +open Xunit +open Xunit.Extensions.AssemblyFixture + +[] +do () + +module Program = let [] main _ = 0 diff --git a/src/VahterBanBot.Tests/Tests.fs b/src/VahterBanBot.Tests/Tests.fs new file mode 100644 index 0000000..bca8d56 --- /dev/null +++ b/src/VahterBanBot.Tests/Tests.fs @@ -0,0 +1,37 @@ +module Tests + +open System +open System.Net.Http +open System.Text +open Telegram.Bot.Types +open VahterBanBot.Tests.ContainerTestBase +open Xunit +open Xunit.Extensions.AssemblyFixture + +type Tests(containers: VahterTestContainers) = + [] + let ``Random path returns OK`` () = task { + let! resp = containers.Http.GetAsync("/" + Guid.NewGuid().ToString()) + let! body = resp.Content.ReadAsStringAsync() + Assert.Equal(System.Net.HttpStatusCode.OK, resp.StatusCode) + Assert.Equal("OK", body) + } + + [] + let ``Not possible to interact with the bot without authorization`` () = task { + let http = new HttpClient() + let content = new StringContent("""{"update_id":123}""", Encoding.UTF8, "application/json") + let uri = containers.Uri.ToString() + "bot" + let! resp = http.PostAsync(uri, content) + Assert.Equal(System.Net.HttpStatusCode.Unauthorized, resp.StatusCode) + } + + [] + let ``Should be possible to interact with the bot`` () = task { + let! resp = Update(Id = 123) |> containers.SendMessage + let! body = resp.Content.ReadAsStringAsync() + Assert.Equal(System.Net.HttpStatusCode.OK, resp.StatusCode) + Assert.Equal("null", body) + } + + interface IAssemblyFixture diff --git a/src/VahterBanBot.Tests/VahterBanBot.Tests.fsproj b/src/VahterBanBot.Tests/VahterBanBot.Tests.fsproj new file mode 100644 index 0000000..da257b8 --- /dev/null +++ b/src/VahterBanBot.Tests/VahterBanBot.Tests.fsproj @@ -0,0 +1,29 @@ + + + + net7.0 + false + false + true + true + + + + + + + + + + + + + + + + + + + + + diff --git a/src/VahterBanBot/Program.fs b/src/VahterBanBot/Program.fs index b796527..a7880bb 100644 --- a/src/VahterBanBot/Program.fs +++ b/src/VahterBanBot/Program.fs @@ -13,7 +13,6 @@ open Telegram.Bot.Types open Giraffe open Microsoft.Extensions.DependencyInjection open Telegram.Bot.Types.Enums -open VahterBanBot open VahterBanBot.Cleanup open VahterBanBot.Utils open VahterBanBot.Bot @@ -136,30 +135,9 @@ let app = builder.Build() app.UseGiraffe(webApp) let server = app.RunAsync() -let telegramClient = app.Services.GetRequiredService() - -let getStartLogMsg() = - let sb = System.Text.StringBuilder() - %sb.AppendLine("Bot started with following configuration") - %sb.AppendLine("AllowedUsers:") - for KeyValue(username, userId) in botConf.AllowedUsers do - %sb.AppendLine($" {prependUsername username} ({userId})") - %sb.AppendLine("ChatsToMonitor:") - for KeyValue(username, chatId) in botConf.ChatsToMonitor do - %sb.AppendLine($" {prependUsername username} ({chatId})") - - let totalStats = (DB.getVahterStats None).Result - %sb.AppendLine (string totalStats) - - sb.ToString() - -if not botConf.IgnoreSideEffects then - let startLogMsg = getStartLogMsg() - app.Logger.LogInformation startLogMsg - telegramClient.SendTextMessageAsync(ChatId(botConf.LogsChannelId), startLogMsg).Wait() - // Dev mode only if botConf.UsePolling then + let telegramClient = app.Services.GetRequiredService() let pollingHandler = { new IUpdateHandler with member x.HandleUpdateAsync (botClient: ITelegramBotClient, update: Update, cancellationToken: CancellationToken) = diff --git a/src/VahterBanBot/StartupMessage.fs b/src/VahterBanBot/StartupMessage.fs new file mode 100644 index 0000000..866169e --- /dev/null +++ b/src/VahterBanBot/StartupMessage.fs @@ -0,0 +1,41 @@ +module VahterBanBot.StartupMessage + +open System.Text +open System.Threading.Tasks +open Microsoft.Extensions.Logging +open Telegram.Bot +open Telegram.Bot.Types +open VahterBanBot.Types +open VahterBanBot.Utils +open Microsoft.Extensions.Hosting + +type StartupMessage( + logger: ILogger, + telegramClient: ITelegramBotClient, + botConf: BotConfiguration +) = + let getStartLogMsg() = + let sb = StringBuilder() + %sb.AppendLine("Bot started with following configuration") + %sb.AppendLine("AllowedUsers:") + for KeyValue(username, userId) in botConf.AllowedUsers do + %sb.AppendLine($" {prependUsername username} ({userId})") + %sb.AppendLine("ChatsToMonitor:") + for KeyValue(username, chatId) in botConf.ChatsToMonitor do + %sb.AppendLine($" {prependUsername username} ({chatId})") + + let totalStats = (DB.getVahterStats None).Result + %sb.AppendLine (string totalStats) + + sb.ToString() + interface IHostedService with + member this.StartAsync _ = task { + if not botConf.IgnoreSideEffects then + let startLogMsg = getStartLogMsg() + logger.LogInformation startLogMsg + do! telegramClient.SendTextMessageAsync(ChatId(botConf.LogsChannelId), startLogMsg) + |> taskIgnore + } + + member this.StopAsync _ = + Task.CompletedTask diff --git a/src/VahterBanBot/VahterBanBot.fsproj b/src/VahterBanBot/VahterBanBot.fsproj index 91e3c1a..2e681da 100644 --- a/src/VahterBanBot/VahterBanBot.fsproj +++ b/src/VahterBanBot/VahterBanBot.fsproj @@ -13,6 +13,7 @@ + diff --git a/vahter-ban-bot.sln b/vahter-ban-bot.sln index 3f3c1c6..0149ac7 100644 --- a/vahter-ban-bot.sln +++ b/vahter-ban-bot.sln @@ -7,6 +7,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B17C5EB6-2D8 EndProject Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "VahterBanBot", "src\VahterBanBot\VahterBanBot.fsproj", "{3CDDAF2F-8555-476B-9CF0-298615ED39A6}" EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "VahterBanBot.Tests", "src\VahterBanBot.Tests\VahterBanBot.Tests.fsproj", "{6AFF7FFB-F313-40FE-BF5D-6A5797CEB311}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -20,8 +22,13 @@ Global {3CDDAF2F-8555-476B-9CF0-298615ED39A6}.Debug|Any CPU.Build.0 = Debug|Any CPU {3CDDAF2F-8555-476B-9CF0-298615ED39A6}.Release|Any CPU.ActiveCfg = Release|Any CPU {3CDDAF2F-8555-476B-9CF0-298615ED39A6}.Release|Any CPU.Build.0 = Release|Any CPU + {6AFF7FFB-F313-40FE-BF5D-6A5797CEB311}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6AFF7FFB-F313-40FE-BF5D-6A5797CEB311}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6AFF7FFB-F313-40FE-BF5D-6A5797CEB311}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6AFF7FFB-F313-40FE-BF5D-6A5797CEB311}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {3CDDAF2F-8555-476B-9CF0-298615ED39A6} = {B17C5EB6-2D87-4E13-B740-4B220A7E4F66} + {6AFF7FFB-F313-40FE-BF5D-6A5797CEB311} = {B17C5EB6-2D87-4E13-B740-4B220A7E4F66} EndGlobalSection EndGlobal From 64c58b6c6f9399a406946d7c9eb8c4d728462083 Mon Sep 17 00:00:00 2001 From: Ayrat Hudaygulov Date: Fri, 14 Jun 2024 16:22:55 +0100 Subject: [PATCH 02/14] wip --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 163764f..154e338 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ .idea .env flyway.conf -*sln.DotSettings.user \ No newline at end of file +*sln.DotSettings.user From 370d76e2aa994514874e83b0877b5d548f535eee Mon Sep 17 00:00:00 2001 From: Ayrat Hudaygulov Date: Fri, 14 Jun 2024 16:33:10 +0100 Subject: [PATCH 03/14] added gh wf --- .github/workflows/build-and-test.yml | 19 +++++++++++++++++++ .github/workflows/deploy-azure-acr.yml | 9 ++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/build-and-test.yml diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml new file mode 100644 index 0000000..b13bfc2 --- /dev/null +++ b/.github/workflows/build-and-test.yml @@ -0,0 +1,19 @@ +name: Build and test + +on: + pull_request: + branches: [ "main" ] + workflow_dispatch: + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-dotnet@v4 + with: + global-json-file: global.json + - run: dotnet test -c Release diff --git a/.github/workflows/deploy-azure-acr.yml b/.github/workflows/deploy-azure-acr.yml index 8759135..34ff941 100644 --- a/.github/workflows/deploy-azure-acr.yml +++ b/.github/workflows/deploy-azure-acr.yml @@ -21,7 +21,14 @@ jobs: - name: Checkout uses: actions/checkout@v2 - - name: Apply migrations + # run tests + - uses: actions/setup-dotnet@v4 + with: + global-json-file: global.json + - run: dotnet test -c Release + + # if tests are ok, deploy to production + - name: Apply migrations to production DB run: >- docker run --rm --volume ${{ github.workspace }}/src/migrations:/flyway/sql:ro From ab7d24642b039301a85cba2932e44692b1a57281 Mon Sep 17 00:00:00 2001 From: Ayrat Hudaygulov Date: Fri, 14 Jun 2024 16:38:52 +0100 Subject: [PATCH 04/14] wip --- src/VahterBanBot.Tests/VahterBanBot.Tests.fsproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/VahterBanBot.Tests/VahterBanBot.Tests.fsproj b/src/VahterBanBot.Tests/VahterBanBot.Tests.fsproj index da257b8..b119d95 100644 --- a/src/VahterBanBot.Tests/VahterBanBot.Tests.fsproj +++ b/src/VahterBanBot.Tests/VahterBanBot.Tests.fsproj @@ -20,6 +20,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + From 980d16b35c99626c56876d7b39f4aa04dc527387 Mon Sep 17 00:00:00 2001 From: Ayrat Hudaygulov Date: Fri, 14 Jun 2024 16:50:38 +0100 Subject: [PATCH 05/14] wip --- .github/workflows/build-and-test.yml | 11 ++++++++++- .github/workflows/deploy-azure-acr.yml | 11 ++++++++++- .gitignore | 1 + 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index b13bfc2..6c78550 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -16,4 +16,13 @@ jobs: - uses: actions/setup-dotnet@v4 with: global-json-file: global.json - - run: dotnet test -c Release + - run: dotnet test -c Release --logger trx --results-directory TestResults + + # upload test results + - name: Upload dotnet test results + uses: actions/upload-artifact@v4 + with: + name: dotnet-results + path: TestResults + # Use always() to always run this step to publish test results when there are test failures + if: ${{ always() }} diff --git a/.github/workflows/deploy-azure-acr.yml b/.github/workflows/deploy-azure-acr.yml index 34ff941..1110306 100644 --- a/.github/workflows/deploy-azure-acr.yml +++ b/.github/workflows/deploy-azure-acr.yml @@ -25,7 +25,16 @@ jobs: - uses: actions/setup-dotnet@v4 with: global-json-file: global.json - - run: dotnet test -c Release + - run: dotnet test -c Release --logger trx --results-directory TestResults + + # upload test results + - name: Upload dotnet test results + uses: actions/upload-artifact@v4 + with: + name: dotnet-results + path: TestResults + # Use always() to always run this step to publish test results when there are test failures + if: ${{ always() }} # if tests are ok, deploy to production - name: Apply migrations to production DB diff --git a/.gitignore b/.gitignore index 154e338..4f60465 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ .env flyway.conf *sln.DotSettings.user +TestResults From f1066e44a6dcd08b2c89c4c98fc68bb5d5e99575 Mon Sep 17 00:00:00 2001 From: Ayrat Hudaygulov Date: Fri, 14 Jun 2024 16:57:31 +0100 Subject: [PATCH 06/14] wip --- .github/workflows/build-and-test.yml | 13 +++++++++++-- .github/workflows/deploy-azure-acr.yml | 11 ++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 6c78550..ca9f62d 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -16,9 +16,10 @@ jobs: - uses: actions/setup-dotnet@v4 with: global-json-file: global.json - - run: dotnet test -c Release --logger trx --results-directory TestResults + - name: Tests + run: dotnet test -c Release --logger trx --results-directory TestResults - # upload test results + # upload test results - name: Upload dotnet test results uses: actions/upload-artifact@v4 with: @@ -26,3 +27,11 @@ jobs: path: TestResults # Use always() to always run this step to publish test results when there are test failures if: ${{ always() }} + + # report test results + - uses: dorny/test-reporter@v1 + with: + artifact: TestResults + name: .NET Tests + path: '*.trx' + reporter: dotnet-trx diff --git a/.github/workflows/deploy-azure-acr.yml b/.github/workflows/deploy-azure-acr.yml index 1110306..4fde504 100644 --- a/.github/workflows/deploy-azure-acr.yml +++ b/.github/workflows/deploy-azure-acr.yml @@ -25,7 +25,8 @@ jobs: - uses: actions/setup-dotnet@v4 with: global-json-file: global.json - - run: dotnet test -c Release --logger trx --results-directory TestResults + - name: Tests + run: dotnet test -c Release --logger trx --results-directory TestResults # upload test results - name: Upload dotnet test results @@ -35,6 +36,14 @@ jobs: path: TestResults # Use always() to always run this step to publish test results when there are test failures if: ${{ always() }} + + # report test results + - uses: dorny/test-reporter@v1 + with: + artifact: TestResults + name: .NET Tests + path: '*.trx' + reporter: dotnet-trx # if tests are ok, deploy to production - name: Apply migrations to production DB From b2567b1ca82a68decda61d51d638cba8719f1d92 Mon Sep 17 00:00:00 2001 From: Ayrat Hudaygulov Date: Fri, 14 Jun 2024 17:01:42 +0100 Subject: [PATCH 07/14] wip --- .github/workflows/build-and-test.yml | 7 ++++--- .github/workflows/deploy-azure-acr.yml | 9 +++++---- .gitignore | 1 + 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index ca9f62d..ad3f16f 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -17,7 +17,7 @@ jobs: with: global-json-file: global.json - name: Tests - run: dotnet test -c Release --logger trx --results-directory TestResults + run: dotnet test -c Release --logger "trx;LogFileName=test-results.trx" # upload test results - name: Upload dotnet test results @@ -29,9 +29,10 @@ jobs: if: ${{ always() }} # report test results - - uses: dorny/test-reporter@v1 + - name: Report test results + uses: dorny/test-reporter@v1 with: - artifact: TestResults + artifact: test-results name: .NET Tests path: '*.trx' reporter: dotnet-trx diff --git a/.github/workflows/deploy-azure-acr.yml b/.github/workflows/deploy-azure-acr.yml index 4fde504..61c1155 100644 --- a/.github/workflows/deploy-azure-acr.yml +++ b/.github/workflows/deploy-azure-acr.yml @@ -26,7 +26,7 @@ jobs: with: global-json-file: global.json - name: Tests - run: dotnet test -c Release --logger trx --results-directory TestResults + run: dotnet test -c Release --logger "trx;LogFileName=test-results.trx" # upload test results - name: Upload dotnet test results @@ -37,10 +37,11 @@ jobs: # Use always() to always run this step to publish test results when there are test failures if: ${{ always() }} - # report test results - - uses: dorny/test-reporter@v1 + # report test results + - name: Report test results + uses: dorny/test-reporter@v1 with: - artifact: TestResults + artifact: test-results name: .NET Tests path: '*.trx' reporter: dotnet-trx diff --git a/.gitignore b/.gitignore index 4f60465..17c5c37 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ flyway.conf *sln.DotSettings.user TestResults +*.trx From ad93ed6dcd380921e479284a72d44c888444aa9f Mon Sep 17 00:00:00 2001 From: Ayrat Hudaygulov Date: Fri, 14 Jun 2024 17:06:11 +0100 Subject: [PATCH 08/14] wip --- .github/workflows/build-and-test.yml | 6 +++--- .github/workflows/deploy-azure-acr.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index ad3f16f..939dcd2 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -32,7 +32,7 @@ jobs: - name: Report test results uses: dorny/test-reporter@v1 with: - artifact: test-results - name: .NET Tests - path: '*.trx' + name: Test results + path: "**/*.trx" reporter: dotnet-trx + fail-on-error: true diff --git a/.github/workflows/deploy-azure-acr.yml b/.github/workflows/deploy-azure-acr.yml index 61c1155..4076277 100644 --- a/.github/workflows/deploy-azure-acr.yml +++ b/.github/workflows/deploy-azure-acr.yml @@ -41,10 +41,10 @@ jobs: - name: Report test results uses: dorny/test-reporter@v1 with: - artifact: test-results - name: .NET Tests - path: '*.trx' + name: Test results + path: "**/*.trx" reporter: dotnet-trx + fail-on-error: true # if tests are ok, deploy to production - name: Apply migrations to production DB From a34a0199b1e13c7a2ddc38a29d8f1ab2653f6b72 Mon Sep 17 00:00:00 2001 From: Ayrat Hudaygulov Date: Fri, 14 Jun 2024 17:10:55 +0100 Subject: [PATCH 09/14] wip --- .github/workflows/build-and-test.yml | 6 +++--- .github/workflows/deploy-azure-acr.yml | 2 +- .github/workflows/test-results.yml | 23 +++++++++++++++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/test-results.yml diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 939dcd2..de8df97 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -1,4 +1,4 @@ -name: Build and test +name: CI on: pull_request: @@ -23,8 +23,8 @@ jobs: - name: Upload dotnet test results uses: actions/upload-artifact@v4 with: - name: dotnet-results - path: TestResults + name: test-results + path: "**/*.trx" # Use always() to always run this step to publish test results when there are test failures if: ${{ always() }} diff --git a/.github/workflows/deploy-azure-acr.yml b/.github/workflows/deploy-azure-acr.yml index 4076277..e9762dc 100644 --- a/.github/workflows/deploy-azure-acr.yml +++ b/.github/workflows/deploy-azure-acr.yml @@ -1,4 +1,4 @@ -name: Build and deploy a container to an Azure Container Registry +name: CD on: push: diff --git a/.github/workflows/test-results.yml b/.github/workflows/test-results.yml new file mode 100644 index 0000000..4a5bf13 --- /dev/null +++ b/.github/workflows/test-results.yml @@ -0,0 +1,23 @@ +name: Test results + +on: + # Run this workflow after the testing workflow completes + workflow_run: + workflows: + - CI + - CD + types: + - completed + +jobs: + build: + runs-on: ubuntu-latest + steps: + # Extract the test result files from the artifacts + - uses: dorny/test-reporter@v1 + with: + name: Test results + artifact: test-results + path: "**/*.trx" + reporter: dotnet-trx + fail-on-error: true From 856136cbd8268bf9a95ae9243acbae9e7f3f8ace Mon Sep 17 00:00:00 2001 From: Ayrat Hudaygulov Date: Fri, 14 Jun 2024 17:12:00 +0100 Subject: [PATCH 10/14] wip --- .../workflows/{deploy-azure-acr.yml => cd.yml} | 15 +++------------ .github/workflows/{build-and-test.yml => ci.yml} | 9 --------- 2 files changed, 3 insertions(+), 21 deletions(-) rename .github/workflows/{deploy-azure-acr.yml => cd.yml} (88%) rename .github/workflows/{build-and-test.yml => ci.yml} (75%) diff --git a/.github/workflows/deploy-azure-acr.yml b/.github/workflows/cd.yml similarity index 88% rename from .github/workflows/deploy-azure-acr.yml rename to .github/workflows/cd.yml index e9762dc..5a4b319 100644 --- a/.github/workflows/deploy-azure-acr.yml +++ b/.github/workflows/cd.yml @@ -27,24 +27,15 @@ jobs: global-json-file: global.json - name: Tests run: dotnet test -c Release --logger "trx;LogFileName=test-results.trx" - + # upload test results - name: Upload dotnet test results uses: actions/upload-artifact@v4 with: - name: dotnet-results - path: TestResults + name: test-results + path: "**/*.trx" # Use always() to always run this step to publish test results when there are test failures if: ${{ always() }} - - # report test results - - name: Report test results - uses: dorny/test-reporter@v1 - with: - name: Test results - path: "**/*.trx" - reporter: dotnet-trx - fail-on-error: true # if tests are ok, deploy to production - name: Apply migrations to production DB diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/ci.yml similarity index 75% rename from .github/workflows/build-and-test.yml rename to .github/workflows/ci.yml index de8df97..2069584 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/ci.yml @@ -27,12 +27,3 @@ jobs: path: "**/*.trx" # Use always() to always run this step to publish test results when there are test failures if: ${{ always() }} - - # report test results - - name: Report test results - uses: dorny/test-reporter@v1 - with: - name: Test results - path: "**/*.trx" - reporter: dotnet-trx - fail-on-error: true From 973558c9b611a72314c635f13472933aecf1ded2 Mon Sep 17 00:00:00 2001 From: Ayrat Hudaygulov Date: Fri, 14 Jun 2024 17:21:31 +0100 Subject: [PATCH 11/14] wip --- .github/workflows/test-results.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-results.yml b/.github/workflows/test-results.yml index 4a5bf13..72f8353 100644 --- a/.github/workflows/test-results.yml +++ b/.github/workflows/test-results.yml @@ -1,11 +1,9 @@ name: Test results on: - # Run this workflow after the testing workflow completes + # Run this workflow after the CI/CD workflow completes workflow_run: - workflows: - - CI - - CD + workflows: ["CI", "CD"] types: - completed From 513733184e803f91e7a36a5c4cc215851daa2b83 Mon Sep 17 00:00:00 2001 From: Ayrat Hudaygulov Date: Fri, 14 Jun 2024 17:23:36 +0100 Subject: [PATCH 12/14] wip --- .github/workflows/test-results.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-results.yml b/.github/workflows/test-results.yml index 72f8353..1974703 100644 --- a/.github/workflows/test-results.yml +++ b/.github/workflows/test-results.yml @@ -3,7 +3,7 @@ name: Test results on: # Run this workflow after the CI/CD workflow completes workflow_run: - workflows: ["CI", "CD"] + workflows: [CI, CD] types: - completed From 1d38d566efccc4a5abae6ff8c45310e3a7e2a557 Mon Sep 17 00:00:00 2001 From: Ayrat Hudaygulov Date: Fri, 14 Jun 2024 17:29:27 +0100 Subject: [PATCH 13/14] wip --- .github/workflows/cd.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/test-results.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 5a4b319..5354699 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -14,7 +14,7 @@ env: SCHEMAS: public jobs: - build: + cd: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2069584..d62575c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ permissions: contents: read jobs: - build: + ci: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/test-results.yml b/.github/workflows/test-results.yml index 1974703..4d37cd6 100644 --- a/.github/workflows/test-results.yml +++ b/.github/workflows/test-results.yml @@ -3,7 +3,7 @@ name: Test results on: # Run this workflow after the CI/CD workflow completes workflow_run: - workflows: [CI, CD] + workflows: [ci, cd] types: - completed From 8270d74f5c275ba6c2db9873da766f892f8721cd Mon Sep 17 00:00:00 2001 From: Ayrat Hudaygulov Date: Fri, 14 Jun 2024 17:31:53 +0100 Subject: [PATCH 14/14] wip --- .github/workflows/{ci.yml => build.yml} | 4 ++-- .github/workflows/{cd.yml => deploy.yml} | 4 ++-- .github/workflows/test-results.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename .github/workflows/{ci.yml => build.yml} (96%) rename .github/workflows/{cd.yml => deploy.yml} (98%) diff --git a/.github/workflows/ci.yml b/.github/workflows/build.yml similarity index 96% rename from .github/workflows/ci.yml rename to .github/workflows/build.yml index d62575c..c7b2430 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: CI +name: Build on: pull_request: @@ -9,7 +9,7 @@ permissions: contents: read jobs: - ci: + build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/cd.yml b/.github/workflows/deploy.yml similarity index 98% rename from .github/workflows/cd.yml rename to .github/workflows/deploy.yml index 5354699..2ffba09 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/deploy.yml @@ -1,4 +1,4 @@ -name: CD +name: Deploy on: push: @@ -14,7 +14,7 @@ env: SCHEMAS: public jobs: - cd: + deploy: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/test-results.yml b/.github/workflows/test-results.yml index 4d37cd6..7c8cdd0 100644 --- a/.github/workflows/test-results.yml +++ b/.github/workflows/test-results.yml @@ -3,7 +3,7 @@ name: Test results on: # Run this workflow after the CI/CD workflow completes workflow_run: - workflows: [ci, cd] + workflows: [Build, Deploy] types: - completed