From a6a6cf49c7849120c9d71e50337bd6bc9be0eee2 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Sun, 11 Jan 2026 18:43:51 -0600 Subject: [PATCH 1/2] build: upgrade to .NET 10 and update dependencies - Bump TargetFramework to net10.0 in Directory.Build.props - Update Microsoft.Extensions and OpenTelemetry packages to latest versions - Update test SDK and xunit runner - Refactor TestWebSocketServer to use HostBuilder and ConfigureWebHost to respond to deprecation notice - Pin FluentAssertions version to [7.2.0] - Remove redundant Microsoft.Extensions.Http reference in StevesBot.Webhook --- src/Directory.Build.props | 2 +- src/src/Directory.Packages.props | 16 ++++---- .../StevesBot.Webhook.csproj | 1 - src/tests/Directory.Packages.props | 8 ++-- .../Infrastructure/TestWebSocketServer.cs | 41 +++++++++++-------- 5 files changed, 37 insertions(+), 31 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 807df2c..2f80156 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - net9.0 + net10.0 enable enable latest diff --git a/src/src/Directory.Packages.props b/src/src/Directory.Packages.props index e98ac39..67f857c 100644 --- a/src/src/Directory.Packages.props +++ b/src/src/Directory.Packages.props @@ -6,14 +6,14 @@ - - - - - - - - + + + + + + + + diff --git a/src/src/StevesBot.Webhook/StevesBot.Webhook.csproj b/src/src/StevesBot.Webhook/StevesBot.Webhook.csproj index 79c3094..81073f2 100644 --- a/src/src/StevesBot.Webhook/StevesBot.Webhook.csproj +++ b/src/src/StevesBot.Webhook/StevesBot.Webhook.csproj @@ -2,7 +2,6 @@ - diff --git a/src/tests/Directory.Packages.props b/src/tests/Directory.Packages.props index fb6598f..cded8ee 100644 --- a/src/tests/Directory.Packages.props +++ b/src/tests/Directory.Packages.props @@ -7,13 +7,13 @@ - - - + + + - + diff --git a/src/tests/StevesBot.Worker.Tests/Integration/Infrastructure/TestWebSocketServer.cs b/src/tests/StevesBot.Worker.Tests/Integration/Infrastructure/TestWebSocketServer.cs index 110068f..0a855df 100644 --- a/src/tests/StevesBot.Worker.Tests/Integration/Infrastructure/TestWebSocketServer.cs +++ b/src/tests/StevesBot.Worker.Tests/Integration/Infrastructure/TestWebSocketServer.cs @@ -1,10 +1,12 @@ +using Microsoft.AspNetCore.Hosting.Server; + using WebSocket = System.Net.WebSockets.WebSocket; namespace StevesBot.Worker.Tests.Integration.Infrastructure; public sealed class TestWebSocketServer : IAsyncLifetime, IDisposable { - private readonly IWebHost _host; + private readonly IHost _host; private readonly CancellationTokenSource _echoCts = new(); private Uri? _webSocketUri; @@ -19,26 +21,30 @@ public sealed class TestWebSocketServer : IAsyncLifetime, IDisposable public TestWebSocketServer() { - _host = new WebHostBuilder() - .Configure(app => + _host = new HostBuilder() + .ConfigureWebHost(b => { - app.UseWebSockets(); - - app.Run(async context => + b.Configure(app => { - if (context.Request.Path == "/ws" && context.WebSockets.IsWebSocketRequest) + app.UseWebSockets(); + + app.Run(async context => { - var webSocket = await context.WebSockets.AcceptWebSocketAsync(); - await Echo(webSocket, _echoCts.Token); - } - else - { - context.Response.StatusCode = 400; - } + if (context.Request.Path == "/ws" && context.WebSockets.IsWebSocketRequest) + { + var webSocket = await context.WebSockets.AcceptWebSocketAsync(); + await Echo(webSocket, _echoCts.Token); + } + else + { + context.Response.StatusCode = 400; + } + }); }); + + b.UseKestrel(); + b.UseUrls("http://[::1]:0"); }) - .UseKestrel() - .UseUrls("http://[::1]:0") .Build(); } @@ -58,7 +64,8 @@ public sealed class TestWebSocketServer : IAsyncLifetime, IDisposable private Uri GetWebSocketUri() { - var address = _host.ServerFeatures.GetRequiredFeature().Addresses.First(); + var serverFeatures = _host.Services.GetRequiredService().Features; + var address = serverFeatures.GetRequiredFeature().Addresses.First(); var webSocketAddress = address.Replace("http://", "ws://", StringComparison.OrdinalIgnoreCase); return new Uri(webSocketAddress + "/ws"); } From cd805bdecbd3e2391b84caf75ac057ebecf675b6 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Sun, 11 Jan 2026 18:52:19 -0600 Subject: [PATCH 2/2] ci: update workflows and environments to .NET 10 - Update GitHub Actions to latest versions (checkout@v6, setup-dotnet@v5, upload-artifact@v6) - Update CI/CD workflows to use .NET 10.0.x SDK - Bump base and runtime images to .NET 10.0 in Dockerfiles - Update README documentation and prerequisites to reflect .NET 10 migration --- .github/workflows/deploy.yml | 4 ++-- .github/workflows/pull_request.yml | 18 +++++++++--------- README.md | 26 +++++++++++++------------- src/StevesBot.Webhook.Dockerfile | 4 ++-- src/StevesBot.Worker.Dockerfile | 4 ++-- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index b228e4e..86e4407 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -14,7 +14,7 @@ jobs: version: ${{ steps.version.outputs.version }} steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Login to Docker Hub uses: docker/login-action@v3 with: @@ -37,7 +37,7 @@ jobs: needs: build steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Copy compose file to server uses: appleboy/scp-action@v1 with: diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 6e685ba..d070316 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -12,11 +12,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 - - name: Setup .NET 9 - uses: actions/setup-dotnet@v4 + uses: actions/checkout@v6 + - name: Setup .NET 10 + uses: actions/setup-dotnet@v5 with: - dotnet-version: 9.0.x + dotnet-version: 10.0.x - name: Format code run: dotnet format src --verify-no-changes --verbosity diagnostic test: @@ -24,11 +24,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 - - name: Setup .NET 9 - uses: actions/setup-dotnet@v4 + uses: actions/checkout@v6 + - name: Setup .NET 10 + uses: actions/setup-dotnet@v5 with: - dotnet-version: 9.0.x + dotnet-version: 10.0.x - name: Install report generator run: dotnet tool install -g dotnet-reportgenerator-globaltool - name: Run tests @@ -36,7 +36,7 @@ jobs: - name: Merge coverage reports run: reportgenerator "-reports:src/tests/*/TestResults/*/coverage.cobertura.xml" "-reporttypes:Html;Cobertura" "-targetdir:src/tests/TestResults/Coverage" - name: Upload code coverage - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: coverage-reports path: src/tests/TestResults/Coverage diff --git a/README.md b/README.md index 274080e..0e88106 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Steve's Bot 🤖 -This is a comprehensive Discord bot platform built with .NET 9, designed to be a full-featured and extensible solution for having my own assistant in my [Discord server](https://discord.stevanfreeborn.com). +This is a comprehensive Discord bot platform built with .NET 10, designed to be a full-featured and extensible solution for having my own assistant in my [Discord server](https://discord.stevanfreeborn.com). ## ✨ Features @@ -32,7 +32,7 @@ This is a comprehensive Discord bot platform built with .NET 9, designed to be a ### Prerequisites -- [.NET 9 SDK](https://dotnet.microsoft.com/download) +- [.NET 10 SDK](https://dotnet.microsoft.com/download) - Discord Bot Token (from [Discord Developer Portal](https://discord.com/developers/applications)) - For YouTube integration: YouTube Data API v3 key from [Google Cloud Console](https://console.cloud.google.com/apis/credentials) @@ -150,14 +150,14 @@ src/ ### YouTube Webhook Options -| Setting | Description | Required | -|----------------------------------------|---------------------------------------|----------| -| `YouTubeClientOptions__BaseUrl` | YouTube Data API base URL | Yes | -| `YouTubeClientOptions__ApiKey` | YouTube Data API v3 key | Yes | -| `SubscriptionOptions__CallbackUrl` | Webhook callback URL | Yes | -| `SubscriptionOptions__TopicUrl` | YouTube channel topic URL | Yes | -| `PubSubClientOptions__BaseUrl` | PubSubHubbub hub URL | Yes | -| `DiscordNotificationOptions__ChannelId` | Discord channel for notifications | Yes | +| Setting | Description | Required | +|-----------------------------------------|-----------------------------------|----------| +| `YouTubeClientOptions__BaseUrl` | YouTube Data API base URL | Yes | +| `YouTubeClientOptions__ApiKey` | YouTube Data API v3 key | Yes | +| `SubscriptionOptions__CallbackUrl` | Webhook callback URL | Yes | +| `SubscriptionOptions__TopicUrl` | YouTube channel topic URL | Yes | +| `PubSubClientOptions__BaseUrl` | PubSubHubbub hub URL | Yes | +| `DiscordNotificationOptions__ChannelId` | Discord channel for notifications | Yes | ### Telemetry Options @@ -226,11 +226,11 @@ The project includes a multi-stage Dockerfile for optimized production builds: ```dockerfile # Build stage with .NET SDK -FROM mcr.microsoft.com/dotnet/sdk:9.0 AS base +FROM mcr.microsoft.com/dotnet/sdk:10.0 AS base # ... build steps ... # Runtime stage with optimized ASP.NET runtime -FROM mcr.microsoft.com/dotnet/aspnet:9.0 +FROM mcr.microsoft.com/dotnet/aspnet:10.0 # ... runtime setup ... ``` @@ -266,6 +266,6 @@ This project is licensed under the terms found in the [LICENSE.md](LICENSE.md) f --- -Built with ❤️ using .NET 9 and a lot of coffee ☕ +Built with ❤️ using .NET 10 and a lot of coffee ☕ *Steve's Bot - Helping Stevan and friends since 2025* 🚀 diff --git a/src/StevesBot.Webhook.Dockerfile b/src/StevesBot.Webhook.Dockerfile index f9909e1..13715b3 100644 --- a/src/StevesBot.Webhook.Dockerfile +++ b/src/StevesBot.Webhook.Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/sdk:9.0 AS base +FROM mcr.microsoft.com/dotnet/sdk:10.0 AS base WORKDIR /app # solution level @@ -29,7 +29,7 @@ COPY . . FROM base AS publish-stage RUN dotnet publish -c Release -o dist src/StevesBot.Webhook/StevesBot.Webhook.csproj -FROM mcr.microsoft.com/dotnet/aspnet:9.0 +FROM mcr.microsoft.com/dotnet/aspnet:10.0 WORKDIR /app COPY --from=publish-stage /app/dist ./ ENTRYPOINT ["dotnet", "StevesBot.Webhook.dll"] diff --git a/src/StevesBot.Worker.Dockerfile b/src/StevesBot.Worker.Dockerfile index 0a199f3..83ef455 100644 --- a/src/StevesBot.Worker.Dockerfile +++ b/src/StevesBot.Worker.Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/sdk:9.0 AS base +FROM mcr.microsoft.com/dotnet/sdk:10.0 AS base WORKDIR /app # solution level @@ -29,7 +29,7 @@ COPY . . FROM base AS publish-stage RUN dotnet publish -c Release -o dist src/StevesBot.Worker/StevesBot.Worker.csproj -FROM mcr.microsoft.com/dotnet/aspnet:9.0 +FROM mcr.microsoft.com/dotnet/aspnet:10.0 WORKDIR /app COPY --from=publish-stage /app/dist ./ ENTRYPOINT ["dotnet", "StevesBot.Worker.dll"]