From c5d75a7c46c2f75d905c0fb12ef831c3d64e3aab Mon Sep 17 00:00:00 2001 From: Che Date: Thu, 30 Apr 2026 13:07:27 +0100 Subject: [PATCH 01/13] Create new src directory to hold new file structure for apps. separate dotnet from terraform. move dotnet code into dotnet location, and add terraform + initial scaffold --- ...r-1d9d2bc7-25ca-4498-aade-a6f0d0ff776e.yml | 2 +- .gitignore | 7 ++- TheSexy6BotWorker.sln | 51 ------------------- TheSexy6BotWorker.slnx | 2 +- .../BotConfigurationExtensionsTests.cs | 0 .../BotConfigurationIntegrationTests.cs | 0 .../GeminiBotConfigurationTests.cs | 0 .../GrokBotConfigurationTests.cs | 0 .../Integration/MarkdownIntegrationTests.cs | 0 .../Markdown/MarkdownBuilderTests.cs | 0 .../Markdown/MarkdownGeneratorTests.cs | 0 .../Services/BotRegistryTests.cs | 0 .../ConversationSessionManagerTests.cs | 0 .../Services/PerplexityApiIntegrationTest.cs | 0 .../PerplexityKernelIntegrationTest.cs | 0 .../Services/WeatherApiIntegrationTests.cs | 0 .../Services/WeatherKernelIntegrationTest.cs | 0 .../TheSexy6BotWorker.Tests.csproj | 0 .../Commands/PingCommand.cs | 0 .../BotConfigurationExtensions.cs | 0 .../Configuration/GeminiBotConfiguration.cs | 0 .../Configuration/GrokBotConfiguration.cs | 0 .../Configuration/README.md | 0 .../Contracts/IBotConfiguration.cs | 0 .../Contracts/IConversationSessionManager.cs | 0 .../DTOs/PerplexitySearchRequest.cs | 0 .../DTOs/PerplexitySearchResult.cs | 0 .../TheSexy6BotWorker}/DTOs/WeatherRequest.cs | 0 .../DTOs/WeatherResponse.cs | 0 .../TheSexy6BotWorker}/DiscordWorker.cs | 0 .../Handlers/MessageCreatedHandler.cs | 0 .../Helpers/DiscordMessageFormatter.cs | 0 .../Helpers/DiscordMessageSender.cs | 0 .../Helpers/DiscordReplyChainHelper.cs | 0 .../Markdown/MarkdownBuilder.cs | 0 .../Markdown/MarkdownGenerator.cs | 0 .../Markdown/MarkdownIgnoreAttribute.cs | 0 .../Markdown/MarkdownPropertyAttribute.cs | 0 .../Markdown/MarkdownSectionAttribute.cs | 0 .../TheSexy6BotWorker}/Markdown/README.md | 0 .../Models/BotConfigurationModel.cs | 0 .../Models/ConversationSession.cs | 0 .../Models/EngagementDecision.cs | 0 .../dotnet/TheSexy6BotWorker}/Program.cs | 0 .../Properties/launchSettings.json | 0 .../Services/BotRegistry.cs | 0 .../Services/ConversationSessionManager.cs | 0 .../Services/DynamicStatusService.cs | 0 .../Services/PerplexitySearchService.cs | 0 .../Services/WeatherService.cs | 0 .../TheSexy6BotWorker.csproj | 0 .../appsettings.Development.json | 0 .../TheSexy6BotWorker}/appsettings.json | 0 src/terraform/environment.tfvars | 9 ++++ src/terraform/locals.tf | 9 ++++ src/terraform/main.tf | 5 ++ src/terraform/providers.tf | 13 +++++ src/terraform/terraform.tfvars | 6 +++ src/terraform/variables.tf | 29 +++++++++++ 59 files changed, 79 insertions(+), 54 deletions(-) delete mode 100644 TheSexy6BotWorker.sln rename {TheSexy6BotWorker.Tests => src/dotnet/TheSexy6BotWorker.Tests}/Configuration/BotConfigurationExtensionsTests.cs (100%) rename {TheSexy6BotWorker.Tests => src/dotnet/TheSexy6BotWorker.Tests}/Configuration/BotConfigurationIntegrationTests.cs (100%) rename {TheSexy6BotWorker.Tests => src/dotnet/TheSexy6BotWorker.Tests}/Configuration/GeminiBotConfigurationTests.cs (100%) rename {TheSexy6BotWorker.Tests => src/dotnet/TheSexy6BotWorker.Tests}/Configuration/GrokBotConfigurationTests.cs (100%) rename {TheSexy6BotWorker.Tests => src/dotnet/TheSexy6BotWorker.Tests}/Integration/MarkdownIntegrationTests.cs (100%) rename {TheSexy6BotWorker.Tests => src/dotnet/TheSexy6BotWorker.Tests}/Markdown/MarkdownBuilderTests.cs (100%) rename {TheSexy6BotWorker.Tests => src/dotnet/TheSexy6BotWorker.Tests}/Markdown/MarkdownGeneratorTests.cs (100%) rename {TheSexy6BotWorker.Tests => src/dotnet/TheSexy6BotWorker.Tests}/Services/BotRegistryTests.cs (100%) rename {TheSexy6BotWorker.Tests => src/dotnet/TheSexy6BotWorker.Tests}/Services/ConversationSessionManagerTests.cs (100%) rename {TheSexy6BotWorker.Tests => src/dotnet/TheSexy6BotWorker.Tests}/Services/PerplexityApiIntegrationTest.cs (100%) rename {TheSexy6BotWorker.Tests => src/dotnet/TheSexy6BotWorker.Tests}/Services/PerplexityKernelIntegrationTest.cs (100%) rename {TheSexy6BotWorker.Tests => src/dotnet/TheSexy6BotWorker.Tests}/Services/WeatherApiIntegrationTests.cs (100%) rename {TheSexy6BotWorker.Tests => src/dotnet/TheSexy6BotWorker.Tests}/Services/WeatherKernelIntegrationTest.cs (100%) rename {TheSexy6BotWorker.Tests => src/dotnet/TheSexy6BotWorker.Tests}/TheSexy6BotWorker.Tests.csproj (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Commands/PingCommand.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Configuration/BotConfigurationExtensions.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Configuration/GeminiBotConfiguration.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Configuration/GrokBotConfiguration.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Configuration/README.md (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Contracts/IBotConfiguration.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Contracts/IConversationSessionManager.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/DTOs/PerplexitySearchRequest.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/DTOs/PerplexitySearchResult.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/DTOs/WeatherRequest.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/DTOs/WeatherResponse.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/DiscordWorker.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Handlers/MessageCreatedHandler.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Helpers/DiscordMessageFormatter.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Helpers/DiscordMessageSender.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Helpers/DiscordReplyChainHelper.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Markdown/MarkdownBuilder.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Markdown/MarkdownGenerator.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Markdown/MarkdownIgnoreAttribute.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Markdown/MarkdownPropertyAttribute.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Markdown/MarkdownSectionAttribute.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Markdown/README.md (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Models/BotConfigurationModel.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Models/ConversationSession.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Models/EngagementDecision.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Program.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Properties/launchSettings.json (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Services/BotRegistry.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Services/ConversationSessionManager.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Services/DynamicStatusService.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Services/PerplexitySearchService.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/Services/WeatherService.cs (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/TheSexy6BotWorker.csproj (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/appsettings.Development.json (100%) rename {TheSexy6BotWorker => src/dotnet/TheSexy6BotWorker}/appsettings.json (100%) create mode 100644 src/terraform/environment.tfvars create mode 100644 src/terraform/locals.tf create mode 100644 src/terraform/main.tf create mode 100644 src/terraform/providers.tf create mode 100644 src/terraform/terraform.tfvars create mode 100644 src/terraform/variables.tf diff --git a/.github/workflows/uks-discordbot-capp-AutoDeployTrigger-1d9d2bc7-25ca-4498-aade-a6f0d0ff776e.yml b/.github/workflows/uks-discordbot-capp-AutoDeployTrigger-1d9d2bc7-25ca-4498-aade-a6f0d0ff776e.yml index 38e626c..311907b 100644 --- a/.github/workflows/uks-discordbot-capp-AutoDeployTrigger-1d9d2bc7-25ca-4498-aade-a6f0d0ff776e.yml +++ b/.github/workflows/uks-discordbot-capp-AutoDeployTrigger-1d9d2bc7-25ca-4498-aade-a6f0d0ff776e.yml @@ -45,7 +45,7 @@ jobs: COMMIT_MSG_SAFE="$(git log -1 --pretty=%s | tr -cs '[:alnum:]._+-' '-')" echo "msg_safe=${COMMIT_MSG_SAFE}" >> $GITHUB_OUTPUT - - name: Azure Login + - name : Azure Login uses: azure/login@v2 with: client-id: ${{ secrets.UKSDISCORDBOTCAPP_AZURE_CLIENT_ID }} diff --git a/.gitignore b/.gitignore index 74a6897..94dbbc6 100644 --- a/.gitignore +++ b/.gitignore @@ -363,4 +363,9 @@ MigrationBackup/ FodyWeavers.xsd # TheSexy6BotWorker -.env \ No newline at end of file +.env + +#terraform + +src/terraform/.terraform +.terraform.lock.hcl \ No newline at end of file diff --git a/TheSexy6BotWorker.sln b/TheSexy6BotWorker.sln deleted file mode 100644 index 8a7ecbf..0000000 --- a/TheSexy6BotWorker.sln +++ /dev/null @@ -1,51 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.5.2.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TheSexy6BotWorker", "TheSexy6BotWorker\TheSexy6BotWorker.csproj", "{277B9C4A-C549-A038-445C-2F6BB26DE6D6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TheSexy6BotWorker.Tests", "TheSexy6BotWorker.Tests\TheSexy6BotWorker.Tests.csproj", "{3B1E557F-5E60-4E4B-8917-3BBAAA998C93}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {277B9C4A-C549-A038-445C-2F6BB26DE6D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {277B9C4A-C549-A038-445C-2F6BB26DE6D6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {277B9C4A-C549-A038-445C-2F6BB26DE6D6}.Debug|x64.ActiveCfg = Debug|Any CPU - {277B9C4A-C549-A038-445C-2F6BB26DE6D6}.Debug|x64.Build.0 = Debug|Any CPU - {277B9C4A-C549-A038-445C-2F6BB26DE6D6}.Debug|x86.ActiveCfg = Debug|Any CPU - {277B9C4A-C549-A038-445C-2F6BB26DE6D6}.Debug|x86.Build.0 = Debug|Any CPU - {277B9C4A-C549-A038-445C-2F6BB26DE6D6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {277B9C4A-C549-A038-445C-2F6BB26DE6D6}.Release|Any CPU.Build.0 = Release|Any CPU - {277B9C4A-C549-A038-445C-2F6BB26DE6D6}.Release|x64.ActiveCfg = Release|Any CPU - {277B9C4A-C549-A038-445C-2F6BB26DE6D6}.Release|x64.Build.0 = Release|Any CPU - {277B9C4A-C549-A038-445C-2F6BB26DE6D6}.Release|x86.ActiveCfg = Release|Any CPU - {277B9C4A-C549-A038-445C-2F6BB26DE6D6}.Release|x86.Build.0 = Release|Any CPU - {3B1E557F-5E60-4E4B-8917-3BBAAA998C93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3B1E557F-5E60-4E4B-8917-3BBAAA998C93}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3B1E557F-5E60-4E4B-8917-3BBAAA998C93}.Debug|x64.ActiveCfg = Debug|Any CPU - {3B1E557F-5E60-4E4B-8917-3BBAAA998C93}.Debug|x64.Build.0 = Debug|Any CPU - {3B1E557F-5E60-4E4B-8917-3BBAAA998C93}.Debug|x86.ActiveCfg = Debug|Any CPU - {3B1E557F-5E60-4E4B-8917-3BBAAA998C93}.Debug|x86.Build.0 = Debug|Any CPU - {3B1E557F-5E60-4E4B-8917-3BBAAA998C93}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3B1E557F-5E60-4E4B-8917-3BBAAA998C93}.Release|Any CPU.Build.0 = Release|Any CPU - {3B1E557F-5E60-4E4B-8917-3BBAAA998C93}.Release|x64.ActiveCfg = Release|Any CPU - {3B1E557F-5E60-4E4B-8917-3BBAAA998C93}.Release|x64.Build.0 = Release|Any CPU - {3B1E557F-5E60-4E4B-8917-3BBAAA998C93}.Release|x86.ActiveCfg = Release|Any CPU - {3B1E557F-5E60-4E4B-8917-3BBAAA998C93}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {ACBB3BA7-8E81-466A-A1B4-73747E78639C} - EndGlobalSection -EndGlobal diff --git a/TheSexy6BotWorker.slnx b/TheSexy6BotWorker.slnx index 47fab7f..f2e9aeb 100644 --- a/TheSexy6BotWorker.slnx +++ b/TheSexy6BotWorker.slnx @@ -1,4 +1,4 @@ - + diff --git a/TheSexy6BotWorker.Tests/Configuration/BotConfigurationExtensionsTests.cs b/src/dotnet/TheSexy6BotWorker.Tests/Configuration/BotConfigurationExtensionsTests.cs similarity index 100% rename from TheSexy6BotWorker.Tests/Configuration/BotConfigurationExtensionsTests.cs rename to src/dotnet/TheSexy6BotWorker.Tests/Configuration/BotConfigurationExtensionsTests.cs diff --git a/TheSexy6BotWorker.Tests/Configuration/BotConfigurationIntegrationTests.cs b/src/dotnet/TheSexy6BotWorker.Tests/Configuration/BotConfigurationIntegrationTests.cs similarity index 100% rename from TheSexy6BotWorker.Tests/Configuration/BotConfigurationIntegrationTests.cs rename to src/dotnet/TheSexy6BotWorker.Tests/Configuration/BotConfigurationIntegrationTests.cs diff --git a/TheSexy6BotWorker.Tests/Configuration/GeminiBotConfigurationTests.cs b/src/dotnet/TheSexy6BotWorker.Tests/Configuration/GeminiBotConfigurationTests.cs similarity index 100% rename from TheSexy6BotWorker.Tests/Configuration/GeminiBotConfigurationTests.cs rename to src/dotnet/TheSexy6BotWorker.Tests/Configuration/GeminiBotConfigurationTests.cs diff --git a/TheSexy6BotWorker.Tests/Configuration/GrokBotConfigurationTests.cs b/src/dotnet/TheSexy6BotWorker.Tests/Configuration/GrokBotConfigurationTests.cs similarity index 100% rename from TheSexy6BotWorker.Tests/Configuration/GrokBotConfigurationTests.cs rename to src/dotnet/TheSexy6BotWorker.Tests/Configuration/GrokBotConfigurationTests.cs diff --git a/TheSexy6BotWorker.Tests/Integration/MarkdownIntegrationTests.cs b/src/dotnet/TheSexy6BotWorker.Tests/Integration/MarkdownIntegrationTests.cs similarity index 100% rename from TheSexy6BotWorker.Tests/Integration/MarkdownIntegrationTests.cs rename to src/dotnet/TheSexy6BotWorker.Tests/Integration/MarkdownIntegrationTests.cs diff --git a/TheSexy6BotWorker.Tests/Markdown/MarkdownBuilderTests.cs b/src/dotnet/TheSexy6BotWorker.Tests/Markdown/MarkdownBuilderTests.cs similarity index 100% rename from TheSexy6BotWorker.Tests/Markdown/MarkdownBuilderTests.cs rename to src/dotnet/TheSexy6BotWorker.Tests/Markdown/MarkdownBuilderTests.cs diff --git a/TheSexy6BotWorker.Tests/Markdown/MarkdownGeneratorTests.cs b/src/dotnet/TheSexy6BotWorker.Tests/Markdown/MarkdownGeneratorTests.cs similarity index 100% rename from TheSexy6BotWorker.Tests/Markdown/MarkdownGeneratorTests.cs rename to src/dotnet/TheSexy6BotWorker.Tests/Markdown/MarkdownGeneratorTests.cs diff --git a/TheSexy6BotWorker.Tests/Services/BotRegistryTests.cs b/src/dotnet/TheSexy6BotWorker.Tests/Services/BotRegistryTests.cs similarity index 100% rename from TheSexy6BotWorker.Tests/Services/BotRegistryTests.cs rename to src/dotnet/TheSexy6BotWorker.Tests/Services/BotRegistryTests.cs diff --git a/TheSexy6BotWorker.Tests/Services/ConversationSessionManagerTests.cs b/src/dotnet/TheSexy6BotWorker.Tests/Services/ConversationSessionManagerTests.cs similarity index 100% rename from TheSexy6BotWorker.Tests/Services/ConversationSessionManagerTests.cs rename to src/dotnet/TheSexy6BotWorker.Tests/Services/ConversationSessionManagerTests.cs diff --git a/TheSexy6BotWorker.Tests/Services/PerplexityApiIntegrationTest.cs b/src/dotnet/TheSexy6BotWorker.Tests/Services/PerplexityApiIntegrationTest.cs similarity index 100% rename from TheSexy6BotWorker.Tests/Services/PerplexityApiIntegrationTest.cs rename to src/dotnet/TheSexy6BotWorker.Tests/Services/PerplexityApiIntegrationTest.cs diff --git a/TheSexy6BotWorker.Tests/Services/PerplexityKernelIntegrationTest.cs b/src/dotnet/TheSexy6BotWorker.Tests/Services/PerplexityKernelIntegrationTest.cs similarity index 100% rename from TheSexy6BotWorker.Tests/Services/PerplexityKernelIntegrationTest.cs rename to src/dotnet/TheSexy6BotWorker.Tests/Services/PerplexityKernelIntegrationTest.cs diff --git a/TheSexy6BotWorker.Tests/Services/WeatherApiIntegrationTests.cs b/src/dotnet/TheSexy6BotWorker.Tests/Services/WeatherApiIntegrationTests.cs similarity index 100% rename from TheSexy6BotWorker.Tests/Services/WeatherApiIntegrationTests.cs rename to src/dotnet/TheSexy6BotWorker.Tests/Services/WeatherApiIntegrationTests.cs diff --git a/TheSexy6BotWorker.Tests/Services/WeatherKernelIntegrationTest.cs b/src/dotnet/TheSexy6BotWorker.Tests/Services/WeatherKernelIntegrationTest.cs similarity index 100% rename from TheSexy6BotWorker.Tests/Services/WeatherKernelIntegrationTest.cs rename to src/dotnet/TheSexy6BotWorker.Tests/Services/WeatherKernelIntegrationTest.cs diff --git a/TheSexy6BotWorker.Tests/TheSexy6BotWorker.Tests.csproj b/src/dotnet/TheSexy6BotWorker.Tests/TheSexy6BotWorker.Tests.csproj similarity index 100% rename from TheSexy6BotWorker.Tests/TheSexy6BotWorker.Tests.csproj rename to src/dotnet/TheSexy6BotWorker.Tests/TheSexy6BotWorker.Tests.csproj diff --git a/TheSexy6BotWorker/Commands/PingCommand.cs b/src/dotnet/TheSexy6BotWorker/Commands/PingCommand.cs similarity index 100% rename from TheSexy6BotWorker/Commands/PingCommand.cs rename to src/dotnet/TheSexy6BotWorker/Commands/PingCommand.cs diff --git a/TheSexy6BotWorker/Configuration/BotConfigurationExtensions.cs b/src/dotnet/TheSexy6BotWorker/Configuration/BotConfigurationExtensions.cs similarity index 100% rename from TheSexy6BotWorker/Configuration/BotConfigurationExtensions.cs rename to src/dotnet/TheSexy6BotWorker/Configuration/BotConfigurationExtensions.cs diff --git a/TheSexy6BotWorker/Configuration/GeminiBotConfiguration.cs b/src/dotnet/TheSexy6BotWorker/Configuration/GeminiBotConfiguration.cs similarity index 100% rename from TheSexy6BotWorker/Configuration/GeminiBotConfiguration.cs rename to src/dotnet/TheSexy6BotWorker/Configuration/GeminiBotConfiguration.cs diff --git a/TheSexy6BotWorker/Configuration/GrokBotConfiguration.cs b/src/dotnet/TheSexy6BotWorker/Configuration/GrokBotConfiguration.cs similarity index 100% rename from TheSexy6BotWorker/Configuration/GrokBotConfiguration.cs rename to src/dotnet/TheSexy6BotWorker/Configuration/GrokBotConfiguration.cs diff --git a/TheSexy6BotWorker/Configuration/README.md b/src/dotnet/TheSexy6BotWorker/Configuration/README.md similarity index 100% rename from TheSexy6BotWorker/Configuration/README.md rename to src/dotnet/TheSexy6BotWorker/Configuration/README.md diff --git a/TheSexy6BotWorker/Contracts/IBotConfiguration.cs b/src/dotnet/TheSexy6BotWorker/Contracts/IBotConfiguration.cs similarity index 100% rename from TheSexy6BotWorker/Contracts/IBotConfiguration.cs rename to src/dotnet/TheSexy6BotWorker/Contracts/IBotConfiguration.cs diff --git a/TheSexy6BotWorker/Contracts/IConversationSessionManager.cs b/src/dotnet/TheSexy6BotWorker/Contracts/IConversationSessionManager.cs similarity index 100% rename from TheSexy6BotWorker/Contracts/IConversationSessionManager.cs rename to src/dotnet/TheSexy6BotWorker/Contracts/IConversationSessionManager.cs diff --git a/TheSexy6BotWorker/DTOs/PerplexitySearchRequest.cs b/src/dotnet/TheSexy6BotWorker/DTOs/PerplexitySearchRequest.cs similarity index 100% rename from TheSexy6BotWorker/DTOs/PerplexitySearchRequest.cs rename to src/dotnet/TheSexy6BotWorker/DTOs/PerplexitySearchRequest.cs diff --git a/TheSexy6BotWorker/DTOs/PerplexitySearchResult.cs b/src/dotnet/TheSexy6BotWorker/DTOs/PerplexitySearchResult.cs similarity index 100% rename from TheSexy6BotWorker/DTOs/PerplexitySearchResult.cs rename to src/dotnet/TheSexy6BotWorker/DTOs/PerplexitySearchResult.cs diff --git a/TheSexy6BotWorker/DTOs/WeatherRequest.cs b/src/dotnet/TheSexy6BotWorker/DTOs/WeatherRequest.cs similarity index 100% rename from TheSexy6BotWorker/DTOs/WeatherRequest.cs rename to src/dotnet/TheSexy6BotWorker/DTOs/WeatherRequest.cs diff --git a/TheSexy6BotWorker/DTOs/WeatherResponse.cs b/src/dotnet/TheSexy6BotWorker/DTOs/WeatherResponse.cs similarity index 100% rename from TheSexy6BotWorker/DTOs/WeatherResponse.cs rename to src/dotnet/TheSexy6BotWorker/DTOs/WeatherResponse.cs diff --git a/TheSexy6BotWorker/DiscordWorker.cs b/src/dotnet/TheSexy6BotWorker/DiscordWorker.cs similarity index 100% rename from TheSexy6BotWorker/DiscordWorker.cs rename to src/dotnet/TheSexy6BotWorker/DiscordWorker.cs diff --git a/TheSexy6BotWorker/Handlers/MessageCreatedHandler.cs b/src/dotnet/TheSexy6BotWorker/Handlers/MessageCreatedHandler.cs similarity index 100% rename from TheSexy6BotWorker/Handlers/MessageCreatedHandler.cs rename to src/dotnet/TheSexy6BotWorker/Handlers/MessageCreatedHandler.cs diff --git a/TheSexy6BotWorker/Helpers/DiscordMessageFormatter.cs b/src/dotnet/TheSexy6BotWorker/Helpers/DiscordMessageFormatter.cs similarity index 100% rename from TheSexy6BotWorker/Helpers/DiscordMessageFormatter.cs rename to src/dotnet/TheSexy6BotWorker/Helpers/DiscordMessageFormatter.cs diff --git a/TheSexy6BotWorker/Helpers/DiscordMessageSender.cs b/src/dotnet/TheSexy6BotWorker/Helpers/DiscordMessageSender.cs similarity index 100% rename from TheSexy6BotWorker/Helpers/DiscordMessageSender.cs rename to src/dotnet/TheSexy6BotWorker/Helpers/DiscordMessageSender.cs diff --git a/TheSexy6BotWorker/Helpers/DiscordReplyChainHelper.cs b/src/dotnet/TheSexy6BotWorker/Helpers/DiscordReplyChainHelper.cs similarity index 100% rename from TheSexy6BotWorker/Helpers/DiscordReplyChainHelper.cs rename to src/dotnet/TheSexy6BotWorker/Helpers/DiscordReplyChainHelper.cs diff --git a/TheSexy6BotWorker/Markdown/MarkdownBuilder.cs b/src/dotnet/TheSexy6BotWorker/Markdown/MarkdownBuilder.cs similarity index 100% rename from TheSexy6BotWorker/Markdown/MarkdownBuilder.cs rename to src/dotnet/TheSexy6BotWorker/Markdown/MarkdownBuilder.cs diff --git a/TheSexy6BotWorker/Markdown/MarkdownGenerator.cs b/src/dotnet/TheSexy6BotWorker/Markdown/MarkdownGenerator.cs similarity index 100% rename from TheSexy6BotWorker/Markdown/MarkdownGenerator.cs rename to src/dotnet/TheSexy6BotWorker/Markdown/MarkdownGenerator.cs diff --git a/TheSexy6BotWorker/Markdown/MarkdownIgnoreAttribute.cs b/src/dotnet/TheSexy6BotWorker/Markdown/MarkdownIgnoreAttribute.cs similarity index 100% rename from TheSexy6BotWorker/Markdown/MarkdownIgnoreAttribute.cs rename to src/dotnet/TheSexy6BotWorker/Markdown/MarkdownIgnoreAttribute.cs diff --git a/TheSexy6BotWorker/Markdown/MarkdownPropertyAttribute.cs b/src/dotnet/TheSexy6BotWorker/Markdown/MarkdownPropertyAttribute.cs similarity index 100% rename from TheSexy6BotWorker/Markdown/MarkdownPropertyAttribute.cs rename to src/dotnet/TheSexy6BotWorker/Markdown/MarkdownPropertyAttribute.cs diff --git a/TheSexy6BotWorker/Markdown/MarkdownSectionAttribute.cs b/src/dotnet/TheSexy6BotWorker/Markdown/MarkdownSectionAttribute.cs similarity index 100% rename from TheSexy6BotWorker/Markdown/MarkdownSectionAttribute.cs rename to src/dotnet/TheSexy6BotWorker/Markdown/MarkdownSectionAttribute.cs diff --git a/TheSexy6BotWorker/Markdown/README.md b/src/dotnet/TheSexy6BotWorker/Markdown/README.md similarity index 100% rename from TheSexy6BotWorker/Markdown/README.md rename to src/dotnet/TheSexy6BotWorker/Markdown/README.md diff --git a/TheSexy6BotWorker/Models/BotConfigurationModel.cs b/src/dotnet/TheSexy6BotWorker/Models/BotConfigurationModel.cs similarity index 100% rename from TheSexy6BotWorker/Models/BotConfigurationModel.cs rename to src/dotnet/TheSexy6BotWorker/Models/BotConfigurationModel.cs diff --git a/TheSexy6BotWorker/Models/ConversationSession.cs b/src/dotnet/TheSexy6BotWorker/Models/ConversationSession.cs similarity index 100% rename from TheSexy6BotWorker/Models/ConversationSession.cs rename to src/dotnet/TheSexy6BotWorker/Models/ConversationSession.cs diff --git a/TheSexy6BotWorker/Models/EngagementDecision.cs b/src/dotnet/TheSexy6BotWorker/Models/EngagementDecision.cs similarity index 100% rename from TheSexy6BotWorker/Models/EngagementDecision.cs rename to src/dotnet/TheSexy6BotWorker/Models/EngagementDecision.cs diff --git a/TheSexy6BotWorker/Program.cs b/src/dotnet/TheSexy6BotWorker/Program.cs similarity index 100% rename from TheSexy6BotWorker/Program.cs rename to src/dotnet/TheSexy6BotWorker/Program.cs diff --git a/TheSexy6BotWorker/Properties/launchSettings.json b/src/dotnet/TheSexy6BotWorker/Properties/launchSettings.json similarity index 100% rename from TheSexy6BotWorker/Properties/launchSettings.json rename to src/dotnet/TheSexy6BotWorker/Properties/launchSettings.json diff --git a/TheSexy6BotWorker/Services/BotRegistry.cs b/src/dotnet/TheSexy6BotWorker/Services/BotRegistry.cs similarity index 100% rename from TheSexy6BotWorker/Services/BotRegistry.cs rename to src/dotnet/TheSexy6BotWorker/Services/BotRegistry.cs diff --git a/TheSexy6BotWorker/Services/ConversationSessionManager.cs b/src/dotnet/TheSexy6BotWorker/Services/ConversationSessionManager.cs similarity index 100% rename from TheSexy6BotWorker/Services/ConversationSessionManager.cs rename to src/dotnet/TheSexy6BotWorker/Services/ConversationSessionManager.cs diff --git a/TheSexy6BotWorker/Services/DynamicStatusService.cs b/src/dotnet/TheSexy6BotWorker/Services/DynamicStatusService.cs similarity index 100% rename from TheSexy6BotWorker/Services/DynamicStatusService.cs rename to src/dotnet/TheSexy6BotWorker/Services/DynamicStatusService.cs diff --git a/TheSexy6BotWorker/Services/PerplexitySearchService.cs b/src/dotnet/TheSexy6BotWorker/Services/PerplexitySearchService.cs similarity index 100% rename from TheSexy6BotWorker/Services/PerplexitySearchService.cs rename to src/dotnet/TheSexy6BotWorker/Services/PerplexitySearchService.cs diff --git a/TheSexy6BotWorker/Services/WeatherService.cs b/src/dotnet/TheSexy6BotWorker/Services/WeatherService.cs similarity index 100% rename from TheSexy6BotWorker/Services/WeatherService.cs rename to src/dotnet/TheSexy6BotWorker/Services/WeatherService.cs diff --git a/TheSexy6BotWorker/TheSexy6BotWorker.csproj b/src/dotnet/TheSexy6BotWorker/TheSexy6BotWorker.csproj similarity index 100% rename from TheSexy6BotWorker/TheSexy6BotWorker.csproj rename to src/dotnet/TheSexy6BotWorker/TheSexy6BotWorker.csproj diff --git a/TheSexy6BotWorker/appsettings.Development.json b/src/dotnet/TheSexy6BotWorker/appsettings.Development.json similarity index 100% rename from TheSexy6BotWorker/appsettings.Development.json rename to src/dotnet/TheSexy6BotWorker/appsettings.Development.json diff --git a/TheSexy6BotWorker/appsettings.json b/src/dotnet/TheSexy6BotWorker/appsettings.json similarity index 100% rename from TheSexy6BotWorker/appsettings.json rename to src/dotnet/TheSexy6BotWorker/appsettings.json diff --git a/src/terraform/environment.tfvars b/src/terraform/environment.tfvars new file mode 100644 index 0000000..452df90 --- /dev/null +++ b/src/terraform/environment.tfvars @@ -0,0 +1,9 @@ +application = "discordbot" +location = "uksouth" +location_sort = "uks" +environment = "__ENVIRONMENT__" + +#these populate: +# name_prefix in format "${var.environment}-${var.application}" +# name_prefix_no_dash in format "${var.environment}${var.application}" +# e.g. stg-uks-discordbot \ No newline at end of file diff --git a/src/terraform/locals.tf b/src/terraform/locals.tf new file mode 100644 index 0000000..116161b --- /dev/null +++ b/src/terraform/locals.tf @@ -0,0 +1,9 @@ +locals { + common_tags = { + Environment = upper(var.environment) + Application = var.application + Location = var.location + } + name_prefix = "${var.environment}-${var.application}" + name_prefix_no_dash = "${var.environment}${var.application}" +} \ No newline at end of file diff --git a/src/terraform/main.tf b/src/terraform/main.tf new file mode 100644 index 0000000..90317a4 --- /dev/null +++ b/src/terraform/main.tf @@ -0,0 +1,5 @@ +resource "azurerm_resource_group" "this" { + name = "${local.name_prefix}-rg" + location = var.location + tags = local.common_tags +} \ No newline at end of file diff --git a/src/terraform/providers.tf b/src/terraform/providers.tf new file mode 100644 index 0000000..0f995d9 --- /dev/null +++ b/src/terraform/providers.tf @@ -0,0 +1,13 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 4.1.0" + } + } +} + +provider "azurerm" { + use_oidc = true + features {} +} diff --git a/src/terraform/terraform.tfvars b/src/terraform/terraform.tfvars new file mode 100644 index 0000000..1ca5640 --- /dev/null +++ b/src/terraform/terraform.tfvars @@ -0,0 +1,6 @@ +application = "discordbot" +location = "uksouth" +location_sort = "uks" +environment = "stg" + +# populate these for local tf plan \ No newline at end of file diff --git a/src/terraform/variables.tf b/src/terraform/variables.tf new file mode 100644 index 0000000..a88c3dd --- /dev/null +++ b/src/terraform/variables.tf @@ -0,0 +1,29 @@ +variable "application" { + type = string + description = "Application name" +} + +variable "location_short" { + type = string + description = "Short name for the Azure region to deploy to" +} + +variable "location" { + type = string + description = "Azure region to deploy to" +} + +variable "environment" { + type = string + description = "Environment (staging / prd)" +} + +variable "name_prefix" { + type = string + description = "Used for prefixing resource names" +} + +variable "name_prefix_no_dash" { + type = string + description = "Name prefix but with no dash" +} \ No newline at end of file From 6f7748765b2059dae120a2b57e5a40dbeff722a9 Mon Sep 17 00:00:00 2001 From: Che Date: Thu, 30 Apr 2026 18:01:03 +0100 Subject: [PATCH 02/13] update terraform, .gitignore --- .gitignore | 2 +- .vscode/settings.json | 5 +++++ src/terraform/README.md | 6 ++++++ src/terraform/environment.tfvars | 2 +- src/terraform/terraform.tfvars | 2 +- src/terraform/variables.tf | 10 ---------- 6 files changed, 14 insertions(+), 13 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 src/terraform/README.md diff --git a/.gitignore b/.gitignore index 94dbbc6..7de18fa 100644 --- a/.gitignore +++ b/.gitignore @@ -367,5 +367,5 @@ FodyWeavers.xsd #terraform -src/terraform/.terraform +src/terraform/.terraform* .terraform.lock.hcl \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..54a23de --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "chat.tools.terminal.autoApprove": { + "terraform": true + } +} \ No newline at end of file diff --git a/src/terraform/README.md b/src/terraform/README.md new file mode 100644 index 0000000..490d094 --- /dev/null +++ b/src/terraform/README.md @@ -0,0 +1,6 @@ + + + +Before running tf plan: +1. Set environment subscription +run `export ARM_SUBSCRIPTION_ID=your-subscription-id` \ No newline at end of file diff --git a/src/terraform/environment.tfvars b/src/terraform/environment.tfvars index 452df90..f9b95fb 100644 --- a/src/terraform/environment.tfvars +++ b/src/terraform/environment.tfvars @@ -1,6 +1,6 @@ application = "discordbot" location = "uksouth" -location_sort = "uks" +location_short = "uks" environment = "__ENVIRONMENT__" #these populate: diff --git a/src/terraform/terraform.tfvars b/src/terraform/terraform.tfvars index 1ca5640..d8e04f9 100644 --- a/src/terraform/terraform.tfvars +++ b/src/terraform/terraform.tfvars @@ -1,6 +1,6 @@ application = "discordbot" location = "uksouth" -location_sort = "uks" +location_short = "uks" environment = "stg" # populate these for local tf plan \ No newline at end of file diff --git a/src/terraform/variables.tf b/src/terraform/variables.tf index a88c3dd..666effa 100644 --- a/src/terraform/variables.tf +++ b/src/terraform/variables.tf @@ -16,14 +16,4 @@ variable "location" { variable "environment" { type = string description = "Environment (staging / prd)" -} - -variable "name_prefix" { - type = string - description = "Used for prefixing resource names" -} - -variable "name_prefix_no_dash" { - type = string - description = "Name prefix but with no dash" } \ No newline at end of file From 4ed3bffa7c3da76a59b3f6aa3e74036d0c895904 Mon Sep 17 00:00:00 2001 From: Che Date: Thu, 30 Apr 2026 18:13:59 +0100 Subject: [PATCH 03/13] push test script --- .github/workflows/sample_workflow.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/sample_workflow.yml diff --git a/.github/workflows/sample_workflow.yml b/.github/workflows/sample_workflow.yml new file mode 100644 index 0000000..24aa103 --- /dev/null +++ b/.github/workflows/sample_workflow.yml @@ -0,0 +1,25 @@ +name: Run Azure CLI Login with OpenID Connect +on: + pull_request: + +jobs: + test: + permissions: + id-token: write # Require write permission to Fetch an OIDC token. + + runs-on: ubuntu-latest + steps: + - name: Azure CLI Login + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + - name: Azure CLI script + uses: azure/cli@v2 + with: + azcliversion: latest + inlineScript: | + az account show + # You can write your Azure CLI inline scripts here. \ No newline at end of file From 8d4434a0843bbfceaea1aa746e98c1b1a43cbc50 Mon Sep 17 00:00:00 2001 From: Che Date: Thu, 30 Apr 2026 19:07:09 +0100 Subject: [PATCH 04/13] update locals, git ignore, update pr validation - conditional, only runs terraform plan if tf changes. runs dotnet test always. fails pr if status check fails (either of depedent) --- .github/workflows/pr-validation.yml | 73 ++++++++++++++++++++++++++++- .gitignore | 4 +- src/terraform/locals.tf | 4 +- 3 files changed, 77 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index 9f49726..a3518b0 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -1,11 +1,70 @@ name: PR Validation +permissions: { id-token: write, contents: read } + on: pull_request: branches: [main] jobs: - test: + changes: + runs-on: ubuntu-latest + outputs: + terraform: ${{ steps.filter.outputs.terraform }} + steps: + - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d + id: filter + with: + filters: | + terraform: + - 'src/terraform/**' + terraform-plan: + permissions: + id-token: write + environment: stg + runs-on: ubuntu-latest + needs: changes + if: needs.changes.outputs.terraform == 'true' + steps: + - name: Checkout Terraform files only + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 1 + sparse-checkout: | + src/terraform + sparse-checkout-cone-mode: true + + - name: Token replace Terraform env vars + env: + ENVIRONMENT: ${{ vars.NAME_PREFIX }} + run: | + sed "s|__ENVIRONMENT__|${ENVIRONMENT}|g" \ + src/terraform/environment.tfvars \ + > src/terraform/environment.auto.tfvars + + - name: Azure Login + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + enable-AzPSSession: true + - name: Setup Terraform + uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd + with: + terraform_version: 1.9.8 + - name: Terraform Init + run: | + terraform -chdir=src/terraform init -input=false \ + -backend-config="resource_group_name=${{ vars.TFSTATE_RESOURCE_GROUP}}" \ + -backend-config="storage_Account_name=${{ vars.TFSTATE_STORAGE_ACCOUNT}}" \ + -backend-config="container_name=${{ vars.TFSTATE_CONTAINER}}" \ + -backend-config="key=${{ vars.TFSTATE_KEY}}" + + - name: Terraform Plan + run: terraform -chdir=src/terraform plan -input=false -no-color + + test-dotnet: runs-on: ubuntu-latest steps: - name: 'Checkout' @@ -24,3 +83,15 @@ jobs: - name: 'Test' run: dotnet test TheSexy6BotWorker.sln --no-build --verbosity normal --filter "Category!=Integration" + + status-check: + if: ${{ always() }} + needs: [test-dotnet, terraform-plan] + runs-on: ubuntu-latest + steps: + - name: Fail if required jobs failed + run: | + echo "dotnet=${{ needs.test-dotnet.result }}" + echo "terraform=${{ needs.terraform-plan.result }}" + test "${{ needs.test-dotnet.result }}" = "success" + test "${{ needs.terraform-plan.result }}" = "success" -o "${{ needs.terraform-plan.result }}" = "skipped" diff --git a/.gitignore b/.gitignore index 7de18fa..a14dd53 100644 --- a/.gitignore +++ b/.gitignore @@ -368,4 +368,6 @@ FodyWeavers.xsd #terraform src/terraform/.terraform* -.terraform.lock.hcl \ No newline at end of file +.terraform.lock.hcl + +*terraform.tfstate* \ No newline at end of file diff --git a/src/terraform/locals.tf b/src/terraform/locals.tf index 116161b..de26bc2 100644 --- a/src/terraform/locals.tf +++ b/src/terraform/locals.tf @@ -4,6 +4,6 @@ locals { Application = var.application Location = var.location } - name_prefix = "${var.environment}-${var.application}" - name_prefix_no_dash = "${var.environment}${var.application}" + name_prefix = "${var.environment}-${var.location_short}-${var.application}" + name_prefix_no_dash = "${var.environment}${var.location_short}${var.application}" } \ No newline at end of file From 83809c409530011539a1b5295a075a79dcba542a Mon Sep 17 00:00:00 2001 From: Che Date: Thu, 30 Apr 2026 21:40:54 +0100 Subject: [PATCH 05/13] update pr validation for test-dotnet job, rerun for new oidc changes. --- .github/workflows/pr-validation.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index a3518b0..34b7c4e 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -76,13 +76,13 @@ jobs: dotnet-version: '9.0.x' - name: 'Restore dependencies' - run: dotnet restore TheSexy6BotWorker.sln + run: dotnet restore TheSexy6BotWorker.slnx - name: 'Build' - run: dotnet build TheSexy6BotWorker.sln --no-restore + run: dotnet build TheSexy6BotWorker.slnx --no-restore - name: 'Test' - run: dotnet test TheSexy6BotWorker.sln --no-build --verbosity normal --filter "Category!=Integration" + run: dotnet test TheSexy6BotWorker.slnx --no-build --verbosity normal --filter "Category!=Integration" status-check: if: ${{ always() }} From 7b7714b38a55bab36a1e5b0936c2e2d342eb8f1e Mon Sep 17 00:00:00 2001 From: Che Date: Thu, 30 Apr 2026 21:44:20 +0100 Subject: [PATCH 06/13] delete sample workflow, add subscription id to terraform init. --- .github/workflows/pr-validation.yml | 3 ++- .github/workflows/sample_workflow.yml | 25 ------------------------- 2 files changed, 2 insertions(+), 26 deletions(-) delete mode 100644 .github/workflows/sample_workflow.yml diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index 34b7c4e..d1177e4 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -59,7 +59,8 @@ jobs: -backend-config="resource_group_name=${{ vars.TFSTATE_RESOURCE_GROUP}}" \ -backend-config="storage_Account_name=${{ vars.TFSTATE_STORAGE_ACCOUNT}}" \ -backend-config="container_name=${{ vars.TFSTATE_CONTAINER}}" \ - -backend-config="key=${{ vars.TFSTATE_KEY}}" + -backend-config="key=${{ vars.TFSTATE_KEY}}" \ + -backend-config="subscription_id=${{ secrets.AZURE_SUBSCRIPTION_ID }}" \ - name: Terraform Plan run: terraform -chdir=src/terraform plan -input=false -no-color diff --git a/.github/workflows/sample_workflow.yml b/.github/workflows/sample_workflow.yml deleted file mode 100644 index 24aa103..0000000 --- a/.github/workflows/sample_workflow.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Run Azure CLI Login with OpenID Connect -on: - pull_request: - -jobs: - test: - permissions: - id-token: write # Require write permission to Fetch an OIDC token. - - runs-on: ubuntu-latest - steps: - - name: Azure CLI Login - uses: azure/login@v2 - with: - client-id: ${{ secrets.AZURE_CLIENT_ID }} - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - - - name: Azure CLI script - uses: azure/cli@v2 - with: - azcliversion: latest - inlineScript: | - az account show - # You can write your Azure CLI inline scripts here. \ No newline at end of file From 19497f40bf6ebf2a3786b451fde554e858a265e4 Mon Sep 17 00:00:00 2001 From: Che Date: Thu, 30 Apr 2026 21:54:18 +0100 Subject: [PATCH 07/13] explicit set ARM_USE_OIDC=true, set ARM_SUBSCRIPTION_ID at terraform-plan job level. Add new job - Zizmor security scan. --- .github/workflows/pr-validation.yml | 30 ++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index d1177e4..9de2e26 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -18,6 +18,31 @@ jobs: filters: | terraform: - 'src/terraform/**' + github: + - '.github/**' + zizmor-scan: + runs-on: ubuntu-latest + needs: changes + if: needs.changes.outputs.github == 'true' + steps: + - name: Sparse Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 1 + sparse-checkout: | + .github + sparse-checkout-cone-mode: true + + - name: Zizmor Scan + uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3 + with: + advanced-security: false + inputs: + .github + persona: pedantic + fail-on-no-inputs: true + + terraform-plan: permissions: id-token: write @@ -25,6 +50,9 @@ jobs: runs-on: ubuntu-latest needs: changes if: needs.changes.outputs.terraform == 'true' + env: + ARM_USE_OIDC: true + ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} steps: - name: Checkout Terraform files only uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -60,10 +88,10 @@ jobs: -backend-config="storage_Account_name=${{ vars.TFSTATE_STORAGE_ACCOUNT}}" \ -backend-config="container_name=${{ vars.TFSTATE_CONTAINER}}" \ -backend-config="key=${{ vars.TFSTATE_KEY}}" \ - -backend-config="subscription_id=${{ secrets.AZURE_SUBSCRIPTION_ID }}" \ - name: Terraform Plan run: terraform -chdir=src/terraform plan -input=false -no-color + test-dotnet: runs-on: ubuntu-latest From 89d90a384e59cb7fd942769983edb90ae8d4d02b Mon Sep 17 00:00:00 2001 From: Che Date: Thu, 30 Apr 2026 21:55:56 +0100 Subject: [PATCH 08/13] update to include github output so zizmor scan job can run. --- .github/workflows/pr-validation.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index 9de2e26..b2db017 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -11,6 +11,7 @@ jobs: runs-on: ubuntu-latest outputs: terraform: ${{ steps.filter.outputs.terraform }} + github: ${{ steps.filter.outputs.github }} steps: - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d id: filter From 30bb15c1d6c5345bad37146d9c95aff586a3c2b4 Mon Sep 17 00:00:00 2001 From: Che Date: Thu, 30 Apr 2026 22:12:13 +0100 Subject: [PATCH 09/13] fix zizmor errors. comment out docker-ci yaml --- .../{docker-ci.yml => docker-ci.txt} | 11 ++++++-- .github/workflows/pr-validation.yml | 28 ++++++++++++------- 2 files changed, 27 insertions(+), 12 deletions(-) rename .github/workflows/{docker-ci.yml => docker-ci.txt} (81%) diff --git a/.github/workflows/docker-ci.yml b/.github/workflows/docker-ci.txt similarity index 81% rename from .github/workflows/docker-ci.yml rename to .github/workflows/docker-ci.txt index fb6c23d..768c58a 100644 --- a/.github/workflows/docker-ci.yml +++ b/.github/workflows/docker-ci.txt @@ -11,6 +11,8 @@ jobs: steps: - name: 'Checkout' uses: actions/checkout@v4 + with: + persist-credentials: false - name: 'Setup .NET' uses: actions/setup-dotnet@v4 @@ -32,6 +34,8 @@ jobs: steps: - name: 'Checkout' uses: actions/checkout@v4 + with: + persist-credentials: false - name: 'Login via Azure CLI' uses: azure/login@v1 @@ -53,9 +57,12 @@ jobs: - run: | docker build . \ - --build-arg GIT_SHA=${{ steps.commit.outputs.sha }} \ - --build-arg "GIT_COMMIT_MSG=${{ steps.commit.outputs.msg }}" \ + --build-arg GIT_SHA=${STEPS_COMMIT_OUTPUTS_SHA} \ + --build-arg "GIT_COMMIT_MSG=${STEPS_COMMIT_OUTPUTS_MSG}" \ -t ${{ secrets.REGISTRY_LOGIN_SERVER }}/thesexy6bot:${{ github.sha }} \ -t ${{ secrets.REGISTRY_LOGIN_SERVER }}/thesexy6bot:latest docker push ${{ secrets.REGISTRY_LOGIN_SERVER }}/thesexy6bot:${{ github.sha }} docker push ${{ secrets.REGISTRY_LOGIN_SERVER }}/thesexy6bot:latest + env: + STEPS_COMMIT_OUTPUTS_SHA: ${{ steps.commit.outputs.sha }} + STEPS_COMMIT_OUTPUTS_MSG: ${{ steps.commit.outputs.msg }} diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index b2db017..8e9ac52 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -1,7 +1,5 @@ name: PR Validation -permissions: { id-token: write, contents: read } - on: pull_request: branches: [main] @@ -33,6 +31,7 @@ jobs: sparse-checkout: | .github sparse-checkout-cone-mode: true + persist-credentials: false - name: Zizmor Scan uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3 @@ -47,6 +46,7 @@ jobs: terraform-plan: permissions: id-token: write + contents: read environment: stg runs-on: ubuntu-latest needs: changes @@ -62,6 +62,7 @@ jobs: sparse-checkout: | src/terraform sparse-checkout-cone-mode: true + persist-credentials: false - name: Token replace Terraform env vars env: @@ -72,23 +73,28 @@ jobs: > src/terraform/environment.auto.tfvars - name: Azure Login - uses: azure/login@v2 + uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} enable-AzPSSession: true - name: Setup Terraform - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd + uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd with: terraform_version: 1.9.8 - name: Terraform Init run: | terraform -chdir=src/terraform init -input=false \ - -backend-config="resource_group_name=${{ vars.TFSTATE_RESOURCE_GROUP}}" \ - -backend-config="storage_Account_name=${{ vars.TFSTATE_STORAGE_ACCOUNT}}" \ - -backend-config="container_name=${{ vars.TFSTATE_CONTAINER}}" \ - -backend-config="key=${{ vars.TFSTATE_KEY}}" \ + -backend-config="resource_group_name=${VARS_TFSTATE_RESOURCE_GROUP}" \ + -backend-config="storage_Account_name=${VARS_TFSTATE_STORAGE_ACCOUNT}" \ + -backend-config="container_name=${VARS_TFSTATE_CONTAINER}" \ + -backend-config="key=${VARS_TFSTATE_KEY}" \ + env: + VARS_TFSTATE_RESOURCE_GROUP: ${{ vars.TFSTATE_RESOURCE_GROUP}} + VARS_TFSTATE_STORAGE_ACCOUNT: ${{ vars.TFSTATE_STORAGE_ACCOUNT}} + VARS_TFSTATE_CONTAINER: ${{ vars.TFSTATE_CONTAINER}} + VARS_TFSTATE_KEY: ${{ vars.TFSTATE_KEY}} - name: Terraform Plan run: terraform -chdir=src/terraform plan -input=false -no-color @@ -98,10 +104,12 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout' - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - name: 'Setup .NET' - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 #5.2.0 with: dotnet-version: '9.0.x' From ae31432ca46d5fe4a7462dc4edf9d5cbe5a96181 Mon Sep 17 00:00:00 2001 From: Che Date: Thu, 30 Apr 2026 22:14:20 +0100 Subject: [PATCH 10/13] change zizmor to default as pedantic is... well really quite pedantic. --- .github/workflows/pr-validation.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index 8e9ac52..5dc8da5 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -39,7 +39,6 @@ jobs: advanced-security: false inputs: .github - persona: pedantic fail-on-no-inputs: true From 8480817863353dfa7e12b1a523ee4bfed3271cb4 Mon Sep 17 00:00:00 2001 From: Che Date: Thu, 30 Apr 2026 22:21:21 +0100 Subject: [PATCH 11/13] do zizmor fixes. --- .github/workflows/pr-validation.yml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index 5dc8da5..e7bdfc5 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -1,11 +1,15 @@ name: PR Validation +permissions: {} + on: pull_request: branches: [main] jobs: changes: + permissions: + pull-requests: read runs-on: ubuntu-latest outputs: terraform: ${{ steps.filter.outputs.terraform }} @@ -19,8 +23,12 @@ jobs: - 'src/terraform/**' github: - '.github/**' + + zizmor-scan: runs-on: ubuntu-latest + permissions: + contents: read needs: changes if: needs.changes.outputs.github == 'true' steps: @@ -86,7 +94,7 @@ jobs: run: | terraform -chdir=src/terraform init -input=false \ -backend-config="resource_group_name=${VARS_TFSTATE_RESOURCE_GROUP}" \ - -backend-config="storage_Account_name=${VARS_TFSTATE_STORAGE_ACCOUNT}" \ + -backend-config="storage_account_name=${VARS_TFSTATE_STORAGE_ACCOUNT}" \ -backend-config="container_name=${VARS_TFSTATE_CONTAINER}" \ -backend-config="key=${VARS_TFSTATE_KEY}" \ env: @@ -100,6 +108,8 @@ jobs: test-dotnet: + permissions: + contents: read runs-on: ubuntu-latest steps: - name: 'Checkout' @@ -108,7 +118,7 @@ jobs: persist-credentials: false - name: 'Setup .NET' - uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 #5.2.0 + uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 with: dotnet-version: '9.0.x' From e7a94c040a1f176d343a33f94772d5a17e71dc23 Mon Sep 17 00:00:00 2001 From: Che Date: Thu, 30 Apr 2026 23:54:02 +0100 Subject: [PATCH 12/13] add zizmor scan to status check --- .github/workflows/pr-validation.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index e7bdfc5..4d6c8c4 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -133,12 +133,14 @@ jobs: status-check: if: ${{ always() }} - needs: [test-dotnet, terraform-plan] + needs: [test-dotnet, terraform-plan, zizmor-scan] runs-on: ubuntu-latest steps: - name: Fail if required jobs failed run: | echo "dotnet=${{ needs.test-dotnet.result }}" echo "terraform=${{ needs.terraform-plan.result }}" + echo "zizmor=${{ needs.zizmor-scan.result }}" test "${{ needs.test-dotnet.result }}" = "success" test "${{ needs.terraform-plan.result }}" = "success" -o "${{ needs.terraform-plan.result }}" = "skipped" + test "${{ needs.zizmor-scan.result }}" = "success" -o "${{ needs.zizmor-scan.result }}" = "skipped" From a0ce23090a6cfdb88759d83886d98151ee19062d Mon Sep 17 00:00:00 2001 From: Che Date: Wed, 6 May 2026 20:46:36 +0100 Subject: [PATCH 13/13] major changes - container app terraform, key vault creation, pipeline rbac, ci-cd --- src/terraform/container_app.tf | 42 +++++++++++++++++++++++++++++ src/terraform/container_registry.tf | 25 +++++++++++++++++ src/terraform/data.tf | 1 + src/terraform/key_vault.tf | 17 ++++++++++++ src/terraform/law.tf | 10 +++++++ src/terraform/locals.tf | 2 +- src/terraform/outputs.tf | 23 ++++++++++++++++ src/terraform/policies.tf | 0 src/terraform/storage.tf | 11 ++++++++ 9 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 src/terraform/container_app.tf create mode 100644 src/terraform/container_registry.tf create mode 100644 src/terraform/data.tf create mode 100644 src/terraform/key_vault.tf create mode 100644 src/terraform/law.tf create mode 100644 src/terraform/outputs.tf create mode 100644 src/terraform/policies.tf create mode 100644 src/terraform/storage.tf diff --git a/src/terraform/container_app.tf b/src/terraform/container_app.tf new file mode 100644 index 0000000..f2fd04c --- /dev/null +++ b/src/terraform/container_app.tf @@ -0,0 +1,42 @@ +resource "azurerm_container_app_environment" "this" { + name = "${local.name_prefix}-cae" + location = azurerm_resource_group.this.location + resource_group_name = azurerm_resource_group.this.name + log_analytics_workspace_id = azurerm_log_analytics_workspace.this.id + tags = local.common_tags +} + +resource "azurerm_container_app" "this" { + name = "${local.name_prefix}-app" + container_app_environment_id = azurerm_container_app_environment.this.id + resource_group_name = azurerm_resource_group.this.name + revision_mode = "Single" + tags = local.common_tags + + // bootstrap - pipeline owns image + template { + container { + name = "${local.name_prefix}" + image = "mcr.microsoft.com/k8se/quickstart:latest" + cpu = 0.25 + memory = "0.5Gi" + } + } + + lifecycle { + ignore_changes = [ + template[0].container[0].image, + ] + } + + identity { + type = "SystemAssigned" + } +} + +// rbac +resource "azurerm_role_assignment" "container_app_acr_pull" { + scope = azurerm_container_app.this.id + role_definition_name = "Contributor" + principal_id = data.azurerm_client_config.this.object_id +} \ No newline at end of file diff --git a/src/terraform/container_registry.tf b/src/terraform/container_registry.tf new file mode 100644 index 0000000..3c9a4f5 --- /dev/null +++ b/src/terraform/container_registry.tf @@ -0,0 +1,25 @@ +resource "azurerm_container_registry" "this" { + name = "${local.name_prefix_no_dash}acr" + resource_group_name = azurerm_resource_group.this.name + location = var.location + sku = "Basic" + admin_enabled = false + tags = local.common_tags + + identity { + type = "SystemAssigned" + } +} + +resource "azurerm_role_assignment" "acr_push" { + scope = azurerm_container_registry.this.id + role_definition_name = "AcrPush" + principal_id = data.azurerm_client_config.this.object_id +} + +resource "azurerm_role_assignment" "acr_pull" { + scope = azurerm_container_registry.this.id + role_definition_name = "AcrPull" + principal_id = azurerm_container_app.this.identity[0].principal_id +} + diff --git a/src/terraform/data.tf b/src/terraform/data.tf new file mode 100644 index 0000000..012126a --- /dev/null +++ b/src/terraform/data.tf @@ -0,0 +1 @@ +data "azurerm_client_config" "this" {} \ No newline at end of file diff --git a/src/terraform/key_vault.tf b/src/terraform/key_vault.tf new file mode 100644 index 0000000..d9797ef --- /dev/null +++ b/src/terraform/key_vault.tf @@ -0,0 +1,17 @@ +resource "azurerm_key_vault" "this" { + name = "${local.name_prefix}-kv" + resource_group_name = azurerm_resource_group.this.name + location = var.location + tenant_id = data.azurerm_client_config.this.tenant_id + purge_protection_enabled = false + sku_name = "standard" + enable_rbac_authorization = true + + tags = local.common_tags +} + +resource "azurerm_role_assignment" "kv_pipeline_access" { + scope = azurerm_key_vault.this.id + role_definition_name = "Key Vault Secrets User" + principal_id = data.azurerm_client_config.this.client_id +} \ No newline at end of file diff --git a/src/terraform/law.tf b/src/terraform/law.tf new file mode 100644 index 0000000..23edc9c --- /dev/null +++ b/src/terraform/law.tf @@ -0,0 +1,10 @@ +resource "azurerm_log_analytics_workspace" "this" { + name = "${local.name_prefix}-law" + location = azurerm_resource_group.this.location + resource_group_name = azurerm_resource_group.this.name + sku = "PerGB2018" + retention_in_days = 30 + daily_quota_gb = 1 + + tags = local.common_tags +} \ No newline at end of file diff --git a/src/terraform/locals.tf b/src/terraform/locals.tf index de26bc2..17f1154 100644 --- a/src/terraform/locals.tf +++ b/src/terraform/locals.tf @@ -1,6 +1,6 @@ locals { common_tags = { - Environment = upper(var.environment) + Environment = var.environment Application = var.application Location = var.location } diff --git a/src/terraform/outputs.tf b/src/terraform/outputs.tf new file mode 100644 index 0000000..c7ac54b --- /dev/null +++ b/src/terraform/outputs.tf @@ -0,0 +1,23 @@ +output "resource_group_name" { + value = azurerm_resource_group.this.name +} + +output "container_app_name" { + value = azurerm_container_app.this.name +} + +output "container_app_environment_name" { + value = azurerm_container_app_environment.this.name +} + +output "container_registry_login_server" { + value = azurerm_container_registry.this.login_server +} + +output "container_app_id" { + value = azurerm_container_app.this.id +} + +output "container_registry_id" { + value = azurerm_container_registry.this.id +} diff --git a/src/terraform/policies.tf b/src/terraform/policies.tf new file mode 100644 index 0000000..e69de29 diff --git a/src/terraform/storage.tf b/src/terraform/storage.tf new file mode 100644 index 0000000..dc0db2a --- /dev/null +++ b/src/terraform/storage.tf @@ -0,0 +1,11 @@ +resource "azurerm_storage_account" "this" { + name = "${local.name_prefix_no_dash}sa" + resource_group_name = azurerm_resource_group.this.name + location = var.location + account_tier = "Standard" + account_replication_type = "LRS" + tags = local.common_tags + shared_access_key_enabled = false + https_traffic_only_enabled = true + +} \ No newline at end of file