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/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/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"]
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");
}