From e3ed50fc6bf16d494c3d8ecfffde8a003ca796d1 Mon Sep 17 00:00:00 2001 From: Sayed Ali Date: Tue, 29 Oct 2024 10:17:52 +0100 Subject: [PATCH 01/14] Remove unused GitHub Pages workflow --- .github/workflows/pages.yml | 62 ------------------------------------- 1 file changed, 62 deletions(-) delete mode 100644 .github/workflows/pages.yml diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml deleted file mode 100644 index cedae546..00000000 --- a/.github/workflows/pages.yml +++ /dev/null @@ -1,62 +0,0 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -# Sample workflow for building and deploying a Jekyll site to GitHub Pages -name: Deploy Jekyll site to Pages - -on: - push: - branches: ["main"] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - -# Allow one concurrent deployment -concurrency: - group: "pages" - cancel-in-progress: true - -jobs: - # Build job - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Setup Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.1' # Not needed with a .ruby-version file - bundler-cache: true # runs 'bundle install' and caches installed gems automatically - cache-version: 0 # Increment this number if you need to re-download cached gems - - name: Setup Pages - id: pages - uses: actions/configure-pages@v2 - - name: Build with Jekyll - # Outputs to the './_site' directory by default - run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}" - env: - JEKYLL_ENV: production - - name: Upload artifact - # Automatically uploads an artifact from the './_site' directory by default - uses: actions/upload-pages-artifact@v1 - - # Deployment job - deploy: - environment: - name: github-pages - url: "${{ steps.deployment.outputs.page_url }}" - runs-on: ubuntu-latest - needs: build - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v1 From c1c3c69e6a1711712cdc3834e6204fb51af3799f Mon Sep 17 00:00:00 2001 From: Sayed Ali Date: Tue, 29 Oct 2024 13:09:22 +0100 Subject: [PATCH 02/14] First Workflow --- .github/workflows/first-workflow.yml | 56 ++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 .github/workflows/first-workflow.yml diff --git a/.github/workflows/first-workflow.yml b/.github/workflows/first-workflow.yml new file mode 100644 index 00000000..e1135e12 --- /dev/null +++ b/.github/workflows/first-workflow.yml @@ -0,0 +1,56 @@ +# The name of the job is what will display on the GitHub repository in the Actions tab. +name: First Workflow + +# The 'on' section tells GitHub under what conditions we want to run this workflow. +# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows +# Common scenarios include: + # workflow-dispatch (manual execution) + # issues + # push + # pull_request + # schedule +on: + workflow_dispatch: + issues: + types: [opened] + +# This section covers the work to perform. +# We include one or more jobs in this section. +jobs: + # Each individual job will include details like execution order, + # pre-requisite jobs, and execution platform. + job1: + # We can run jobs on GitHub hosted VM runners in Windows, Ubuntu, and Mac OS. + # We can also run jobs on self-hosted hardware. + runs-on: ubuntu-latest + + # Each job contains one or more steps. A step needs to have at least a name and a command. + steps: + - name: Step one + # The 'run' command executes a shell or command script. Because this is Ubuntu, the + # default run command will be /bin/bash + run: echo "Log from step one" + # This section does not appear in the solution file but demonstrates how to set + # custom variables that will be available in the run script. + env: + VARIABLE_NAME: value + - name: Step two + run: echo "Log from step two" + + job2: + # Job 2 will only run after job 1 completes. + # Removing this 'needs' section would make the jobs run simultaneously. + needs: job1 + runs-on: ubuntu-latest + + steps: + - name: Cowsays + # The 'uses' command executes a remote GitHub action. + # A command like mscoutermarsh/cowsays-action means you can + # find this code at https://github.com/mscoutermarsh/cowsays-action + uses: mscoutermarsh/cowsays-action@master + # The 'with' block includes parameters that the workflow will pass + # to this action. Parameters are all in key-value format. + with: + text: 'Ready for prod--ship it!' + color: 'magenta' \ No newline at end of file From 93328eecbef14f8c9abf2531548c83f293a78f80 Mon Sep 17 00:00:00 2001 From: Sayed Ali Date: Tue, 29 Oct 2024 14:37:58 +0100 Subject: [PATCH 03/14] Resolves #6 --- .../src/RazorPagesTestSample/Data/Message.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Application/src/RazorPagesTestSample/Data/Message.cs b/src/Application/src/RazorPagesTestSample/Data/Message.cs index ea99cbd6..4f2d1657 100644 --- a/src/Application/src/RazorPagesTestSample/Data/Message.cs +++ b/src/Application/src/RazorPagesTestSample/Data/Message.cs @@ -7,7 +7,17 @@ public class Message { public int Id { get; set; } - [Required] + /// + /// Gets or sets the text of the message. + /// + /// + /// The text content of the message, limited to 200 characters. + /// + /// + /// This property is required and must be a text data type. + /// If the text exceeds 200 characters, an error message will be displayed. + /// + /// /// /// /// /// /// /// /// /// /// [Required] [DataType(DataType.Text)] [StringLength(200, ErrorMessage = "There's a 200 character limit on messages. Please shorten your message.")] public string Text { get; set; } From 2a0b1c0f585e87315dd4ac57923cc4823d541221 Mon Sep 17 00:00:00 2001 From: Sayed Ali Date: Wed, 30 Oct 2024 10:32:59 +0100 Subject: [PATCH 04/14] azuredeployment --- .github/workflows/AzureDeployment.yml | 52 +++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 .github/workflows/AzureDeployment.yml diff --git a/.github/workflows/AzureDeployment.yml b/.github/workflows/AzureDeployment.yml new file mode 100644 index 00000000..904782d1 --- /dev/null +++ b/.github/workflows/AzureDeployment.yml @@ -0,0 +1,52 @@ + # We only want to run this script manually. + on: + workflow_dispatch + + # Environment variables are defined in an "env" section. + # We set the target environment to dev. + # Open the deploy-advanced.yml file to see how we can accept user input + # instead of needing to change this file to switch environments. + env: + targetEnv: dev + + # The overall workflow name will be Azure Bicep. This will show up in the + # GitHub Action page. + name: Azure Bicep + jobs: + # This script has one job: build and deploy the IaC resources + build-and-deploy: + # We run this on an Ubuntu-based GitHub hosted runner. This hosted runner + # has certain software already installed, including az cli + runs-on: ubuntu-latest + steps: + # Check out the code. This grabs code from the repository and + # makes it available to the GitHub hosted runner. It will usually be the + # first task for any workflow + - uses: actions/checkout@main + + # Log into Azure using a federated credential. We have already set up the + # federation process in a prior step, so we need to pass in the following: + # Client ID = Application registration ID + # Tenant ID = Application owner organization ID (previously called Tenant ID in Azure) + # Subscription ID + # https://github.com/azure/login + - uses: azure/login@v2.1.1 + with: + client-id: $ + tenant-id: $ + subscription-id: $ + # We also need to ensure that enable-AzPSSession is true. This is important for + # using OIDC in Azure. If we were to pass in a client secret instead, we would not need + # this setting enabled + enable-AzPSSession: true + + # Deploy ARM template + - name: Run ARM deploy + # https://github.com/azure/arm-deploy + uses: azure/arm-deploy@v1 + with: + subscriptionId: $ + resourceGroupName: $ + template: ./InfrastructureAsCode/main.bicep + # Use the environment variable called targetEnv + parameters: environment=$ From 7094494688b999d757073b5bfd743663724fb227 Mon Sep 17 00:00:00 2001 From: Sayed Ali Date: Wed, 30 Oct 2024 11:15:31 +0100 Subject: [PATCH 05/14] azuredeployment --- .github/workflows/AzureDeployment.yml | 79 +++++++++++---------------- 1 file changed, 31 insertions(+), 48 deletions(-) diff --git a/.github/workflows/AzureDeployment.yml b/.github/workflows/AzureDeployment.yml index 904782d1..fb6905d0 100644 --- a/.github/workflows/AzureDeployment.yml +++ b/.github/workflows/AzureDeployment.yml @@ -1,52 +1,35 @@ - # We only want to run this script manually. - on: - workflow_dispatch +name: Azure Bicep - # Environment variables are defined in an "env" section. - # We set the target environment to dev. - # Open the deploy-advanced.yml file to see how we can accept user input - # instead of needing to change this file to switch environments. - env: - targetEnv: dev +on: + workflow_dispatch - # The overall workflow name will be Azure Bicep. This will show up in the - # GitHub Action page. - name: Azure Bicep - jobs: - # This script has one job: build and deploy the IaC resources - build-and-deploy: - # We run this on an Ubuntu-based GitHub hosted runner. This hosted runner - # has certain software already installed, including az cli - runs-on: ubuntu-latest - steps: - # Check out the code. This grabs code from the repository and - # makes it available to the GitHub hosted runner. It will usually be the - # first task for any workflow - - uses: actions/checkout@main +env: + targetEnv: dev - # Log into Azure using a federated credential. We have already set up the - # federation process in a prior step, so we need to pass in the following: - # Client ID = Application registration ID - # Tenant ID = Application owner organization ID (previously called Tenant ID in Azure) - # Subscription ID - # https://github.com/azure/login - - uses: azure/login@v2.1.1 - with: - client-id: $ - tenant-id: $ - subscription-id: $ - # We also need to ensure that enable-AzPSSession is true. This is important for - # using OIDC in Azure. If we were to pass in a client secret instead, we would not need - # this setting enabled - enable-AzPSSession: true +jobs: + build-and-deploy: + runs-on: ubuntu-latest + permissions: + contents: read + pages: write + id-token: write + steps: + # Checkout code + - uses: actions/checkout@main - # Deploy ARM template - - name: Run ARM deploy - # https://github.com/azure/arm-deploy - uses: azure/arm-deploy@v1 - with: - subscriptionId: $ - resourceGroupName: $ - template: ./InfrastructureAsCode/main.bicep - # Use the environment variable called targetEnv - parameters: environment=$ + # Log into Azure + - uses: azure/login@v2.1.1 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + enable-AzPSSession: true + + # Deploy ARM template + - name: Run ARM deploy + uses: azure/arm-deploy@v1 + with: + subscriptionId: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + resourceGroupName: ${{ secrets.AZURE_RG }} + template: ./src/InfrastructureAsCode/main.bicep + parameters: environment=${{ env.targetEnv }} \ No newline at end of file From 3a217676f499e56e968d46bc0d57943577b8f121 Mon Sep 17 00:00:00 2001 From: Sayed Ali Date: Wed, 30 Oct 2024 11:29:28 +0100 Subject: [PATCH 06/14] mainfile --- src/InfrastructureAsCode/main.bicep | 92 ++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/src/InfrastructureAsCode/main.bicep b/src/InfrastructureAsCode/main.bicep index 6dc69618..d8e740d2 100644 --- a/src/InfrastructureAsCode/main.bicep +++ b/src/InfrastructureAsCode/main.bicep @@ -8,10 +8,98 @@ var webAppName = '${uniqueString(resourceGroup().id)}-${environment}' var appServicePlanName = '${uniqueString(resourceGroup().id)}-mpnp-asp' var logAnalyticsName = '${uniqueString(resourceGroup().id)}-mpnp-la' var appInsightsName = '${uniqueString(resourceGroup().id)}-mpnp-ai' -var sku = 'S1' +var sku = 'P0V3' var registryName = '${uniqueString(resourceGroup().id)}mpnpreg' var registrySku = 'Standard' var imageName = 'techexcel/dotnetcoreapp' var startupCommand = '' -// TODO: complete this script + +resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-12-01-preview' = { + name: logAnalyticsName + location: location + properties: { + sku: { + name: 'PerGB2018' + } + retentionInDays: 90 + workspaceCapping: { + dailyQuotaGb: 1 + } + } +} + +resource appInsights 'Microsoft.Insights/components@2020-02-02-preview' = { + name: appInsightsName + location: location + kind: 'web' + properties: { + Application_Type: 'web' + WorkspaceResourceId: logAnalyticsWorkspace.id + } +} + +resource containerRegistry 'Microsoft.ContainerRegistry/registries@2020-11-01-preview' = { + name: registryName + location: location + sku: { + name: registrySku + } + properties: { + adminUserEnabled: true + } +} + +resource appServicePlan 'Microsoft.Web/serverFarms@2022-09-01' = { + name: appServicePlanName + location: location + kind: 'linux' + properties: { + reserved: true + } + sku: { + name: sku + } +} + +resource appServiceApp 'Microsoft.Web/sites@2020-12-01' = { + name: webAppName + location: location + properties: { + serverFarmId: appServicePlan.id + httpsOnly: true + clientAffinityEnabled: false + siteConfig: { + linuxFxVersion: 'DOCKER|${containerRegistry.name}.azurecr.io/${uniqueString(resourceGroup().id)}/${imageName}' + http20Enabled: true + minTlsVersion: '1.2' + appCommandLine: startupCommand + appSettings: [ + { + name: 'WEBSITES_ENABLE_APP_SERVICE_STORAGE' + value: 'false' + } + { + name: 'DOCKER_REGISTRY_SERVER_URL' + value: 'https://${containerRegistry.name}.azurecr.io' + } + { + name: 'DOCKER_REGISTRY_SERVER_USERNAME' + value: containerRegistry.name + } + { + name: 'DOCKER_REGISTRY_SERVER_PASSWORD' + value: containerRegistry.listCredentials().passwords[0].value + } + { + name: 'APPINSIGHTS_INSTRUMENTATIONKEY' + value: appInsights.properties.InstrumentationKey + } + ] + } + } +} + +output application_name string = appServiceApp.name +output application_url string = appServiceApp.properties.hostNames[0] +output container_registry_name string = containerRegistry.name From 76e1baabae7554ec3f7f7e76e78bfddaa567b82a Mon Sep 17 00:00:00 2001 From: Sayed Ali Date: Wed, 30 Oct 2024 11:58:51 +0100 Subject: [PATCH 07/14] Update SKU for app service plan --- src/InfrastructureAsCode/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/InfrastructureAsCode/main.bicep b/src/InfrastructureAsCode/main.bicep index d8e740d2..c2de2c91 100644 --- a/src/InfrastructureAsCode/main.bicep +++ b/src/InfrastructureAsCode/main.bicep @@ -8,7 +8,7 @@ var webAppName = '${uniqueString(resourceGroup().id)}-${environment}' var appServicePlanName = '${uniqueString(resourceGroup().id)}-mpnp-asp' var logAnalyticsName = '${uniqueString(resourceGroup().id)}-mpnp-la' var appInsightsName = '${uniqueString(resourceGroup().id)}-mpnp-ai' -var sku = 'P0V3' +var sku = 'S1' var registryName = '${uniqueString(resourceGroup().id)}mpnpreg' var registrySku = 'Standard' var imageName = 'techexcel/dotnetcoreapp' From 73d708ba66a1e67996e959309ace7a8e1708924b Mon Sep 17 00:00:00 2001 From: Sayed Ali Date: Wed, 30 Oct 2024 12:10:36 +0100 Subject: [PATCH 08/14] Update location parameter to 'GermanyWestCentral' --- src/InfrastructureAsCode/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/InfrastructureAsCode/main.bicep b/src/InfrastructureAsCode/main.bicep index c2de2c91..2ce09735 100644 --- a/src/InfrastructureAsCode/main.bicep +++ b/src/InfrastructureAsCode/main.bicep @@ -2,7 +2,7 @@ param environment string = 'dev' @description('Location of services') -param location string = resourceGroup().location +param location string = 'GermanyWestCentral' var webAppName = '${uniqueString(resourceGroup().id)}-${environment}' var appServicePlanName = '${uniqueString(resourceGroup().id)}-mpnp-asp' From b37bc16c34894bf45aa89d0132992d55e1dadc50 Mon Sep 17 00:00:00 2001 From: Sayed Ali Date: Wed, 30 Oct 2024 12:53:32 +0100 Subject: [PATCH 09/14] Update .NET CI workflow and Dockerfile --- .github/workflows/donnetdeploy.yml | 123 ++++++++++++++++++ .../src/RazorPagesTestSample/Dockerfile | 18 +++ 2 files changed, 141 insertions(+) create mode 100644 .github/workflows/donnetdeploy.yml create mode 100644 src/Application/src/RazorPagesTestSample/Dockerfile diff --git a/.github/workflows/donnetdeploy.yml b/.github/workflows/donnetdeploy.yml new file mode 100644 index 00000000..994d6adb --- /dev/null +++ b/.github/workflows/donnetdeploy.yml @@ -0,0 +1,123 @@ +name: .NET CI + +env: + registryName: b6dxcqbxqrzqwmpnpreg.azurecr.io + repositoryName: techexcel/dotnetcoreapp + dockerFolderPath: ./src/Application/src/RazorPagesTestSample + tag: ${{github.run_number}} + +on: + push: + branches: [ main ] + paths: src/Application/** + pull_request: + branches: [ main ] + paths: src/Application/** + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Setup .NET + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 8.0 + + - name: Restore dependencies + run: dotnet restore ./src/Application/src/RazorPagesTestSample/RazorPagesTestSample.csproj + - name: Build + run: dotnet build --no-restore ./src/Application/src/RazorPagesTestSample/RazorPagesTestSample.csproj + - name: Test + run: dotnet test --no-build --verbosity normal ./src/Application/tests/RazorPagesTestSample.Tests/RazorPagesTestSample.Tests.csproj + + dockerBuildPush: + runs-on: ubuntu-latest + needs: build + + steps: + - uses: actions/checkout@v3 + + - name: Docker Login + # You may pin to the exact commit or the version. + # uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c + uses: docker/login-action@v1.9.0 + with: + # Server address of Docker registry. If not set then will default to Docker Hub + registry: ${{ secrets.ACR_LOGIN_SERVER }} + # Username used to log against the Docker registry + username: ${{ secrets.ACR_USERNAME }} + # Password or personal access token used to log against the Docker registry + password: ${{ secrets.ACR_PASSWORD }} + # Log out from the Docker registry at the end of a job + logout: true + + - name: Docker Build + run: docker build -t $registryName/$repositoryName:$tag --build-arg build_version=$tag $dockerFolderPath + + - name: Docker Push + run: docker push $registryName/$repositoryName:$tag + + deploy-to-dev: + + runs-on: ubuntu-latest + needs: dockerBuildPush + environment: + name: dev + url: https://b6dxcqbxqrzqw-dev.azurewebsites.net/ + + steps: + - name: 'Login via Azure CLI' + uses: azure/login@v2.1.1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - uses: azure/webapps-deploy@v2 + with: + app-name: 'b6dxcqbxqrzqw-dev' + images: b6dxcqbxqrzqwmpnpreg.azurecr.io/techexcel/dotnetcoreapp:${{github.run_number}} + + deploy-to-test: + + runs-on: ubuntu-latest + needs: deploy-to-dev + environment: + name: test + url: https://b6dxcqbxqrzqw-test.azurewebsites.net/ + + steps: + - uses: actions/checkout@v3 + + - name: 'Login via Azure CLI' + uses: azure/login@v2.1.1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - uses: azure/webapps-deploy@v2 + with: + app-name: 'b6dxcqbxqrzqw-test' + images: b6dxcqbxqrzqwmpnpreg.azurecr.io/techexcel/dotnetcoreapp:${{github.run_number}} + + deploy-to-prod: + + runs-on: ubuntu-latest + needs: deploy-to-test + environment: + name: prod + url: https://b6dxcqbxqrzqw-prod.azurewebsites.net/ + + steps: + - uses: actions/checkout@v3 + + - name: 'Login via Azure CLI' + uses: azure/login@v2.1.1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - uses: azure/webapps-deploy@v2 + with: + app-name: 'b6dxcqbxqrzqw-prod' + images: b6dxcqbxqrzqwmpnpreg.azurecr.io/techexcel/dotnetcoreapp:${{github.run_number}} \ No newline at end of file diff --git a/src/Application/src/RazorPagesTestSample/Dockerfile b/src/Application/src/RazorPagesTestSample/Dockerfile new file mode 100644 index 00000000..ab3fcaf2 --- /dev/null +++ b/src/Application/src/RazorPagesTestSample/Dockerfile @@ -0,0 +1,18 @@ +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env +WORKDIR /app + +# Copy csproj and restore as distinct layers +COPY *.csproj ./ +RUN dotnet restore + +# Copy everything else and build +COPY . ./ +RUN dotnet publish -c Release -o out + +# Build runtime image +FROM mcr.microsoft.com/dotnet/aspnet:8.0 +WORKDIR /app +COPY --from=build-env /app/out . +# Default ASP.NET port changed with .NET 8.0 +ENV ASPNETCORE_HTTP_PORTS=80 +ENTRYPOINT ["dotnet", "RazorPagesTestSample.dll"] \ No newline at end of file From 3de26b5f019a2a9308a31635e602dce7f6a64b43 Mon Sep 17 00:00:00 2001 From: Sayed Ali Date: Wed, 30 Oct 2024 13:12:28 +0100 Subject: [PATCH 10/14] Add CODEOWNERS file for /src/Application/ directory --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) create mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 00000000..42750a8c --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +/src/Application/ sayedpfe \ No newline at end of file From 05ecb3beb94dd5be7080149204d786afc4d9dfd5 Mon Sep 17 00:00:00 2001 From: Sayed Ali Date: Wed, 30 Oct 2024 13:17:14 +0100 Subject: [PATCH 11/14] Update page title in Index.cshtml --- src/Application/src/RazorPagesTestSample/Pages/Index.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Application/src/RazorPagesTestSample/Pages/Index.cshtml b/src/Application/src/RazorPagesTestSample/Pages/Index.cshtml index f7645733..f796f9f5 100644 --- a/src/Application/src/RazorPagesTestSample/Pages/Index.cshtml +++ b/src/Application/src/RazorPagesTestSample/Pages/Index.cshtml @@ -1,7 +1,7 @@ @page @model IndexModel @{ - ViewData["Title"] = "Munson's Pickles and Preserves Team Messaging System"; + ViewData["Title"] = "Sayed's Pickles and Preserves Team Messaging System"; }

@ViewData["Title"]

From bdd965d7c737d7c25bbc6487d7d019638d777650 Mon Sep 17 00:00:00 2001 From: Sayed Ali Date: Wed, 30 Oct 2024 14:31:33 +0100 Subject: [PATCH 12/14] Refactor message analysis logic in Index.cshtml.cs --- .../Pages/Index.cshtml.cs | 47 ++++++++----------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/src/Application/src/RazorPagesTestSample/Pages/Index.cshtml.cs b/src/Application/src/RazorPagesTestSample/Pages/Index.cshtml.cs index 2e6d94bb..ab688215 100644 --- a/src/Application/src/RazorPagesTestSample/Pages/Index.cshtml.cs +++ b/src/Application/src/RazorPagesTestSample/Pages/Index.cshtml.cs @@ -62,35 +62,28 @@ public async Task OnPostDeleteMessageAsync(int id) return RedirectToPage(); } - public async Task OnPostAnalyzeMessagesAsync() - { - Messages = await _db.GetMessagesAsync(); - - if (Messages.Count == 0) - { - MessageAnalysisResult = "There are no messages to analyze."; - } - else - { - // Speed loop. Lower this number once every quarter so we - // get our performance improvement quarterly bonus. - for (int i = 0; i < 3000; i++) { - Thread.Sleep(1); - } - - var wordCount = 0; - - foreach (var message in Messages) - { - wordCount += message.Text.Split(' ').Length; - } +public async Task OnPostAnalyzeMessagesAsync() +{ + Messages = await _db.GetMessagesAsync(); - var avgWordCount = Decimal.Divide(wordCount, Messages.Count); - MessageAnalysisResult = $"The average message length is {avgWordCount:0.##} words."; - } + if (Messages.Count == 0) + { + MessageAnalysisResult = "There are no messages to analyze."; + } + else + { + // Remove the speed loop for actual performance optimization + // for (int i = 0; i < 3000; i++) { + // await Task.Delay(1); + // } + + var totalWords = Messages.Sum(message => message.Text.Split(' ').Length); + var avgWordCount = Decimal.Divide(totalWords, Messages.Count); + MessageAnalysisResult = $"The average message length is {avgWordCount:0.##} words."; + } - return RedirectToPage(); - } + return RedirectToPage(); +} public static void WriteToDirectory(ZipArchiveEntry entry, string destDirectory) { From 4192f0707334f5e9036ca2e10853cc81681785b7 Mon Sep 17 00:00:00 2001 From: Sayed Ali Date: Wed, 30 Oct 2024 14:32:22 +0100 Subject: [PATCH 13/14] Resolves #19 --- .../Pages/Index.cshtml.cs | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/Application/src/RazorPagesTestSample/Pages/Index.cshtml.cs b/src/Application/src/RazorPagesTestSample/Pages/Index.cshtml.cs index ab688215..dd9c49c6 100644 --- a/src/Application/src/RazorPagesTestSample/Pages/Index.cshtml.cs +++ b/src/Application/src/RazorPagesTestSample/Pages/Index.cshtml.cs @@ -62,28 +62,28 @@ public async Task OnPostDeleteMessageAsync(int id) return RedirectToPage(); } -public async Task OnPostAnalyzeMessagesAsync() -{ - Messages = await _db.GetMessagesAsync(); + public async Task OnPostAnalyzeMessagesAsync() + { + Messages = await _db.GetMessagesAsync(); - if (Messages.Count == 0) - { - MessageAnalysisResult = "There are no messages to analyze."; - } - else - { - // Remove the speed loop for actual performance optimization - // for (int i = 0; i < 3000; i++) { - // await Task.Delay(1); - // } - - var totalWords = Messages.Sum(message => message.Text.Split(' ').Length); - var avgWordCount = Decimal.Divide(totalWords, Messages.Count); - MessageAnalysisResult = $"The average message length is {avgWordCount:0.##} words."; - } + if (Messages.Count == 0) + { + MessageAnalysisResult = "There are no messages to analyze."; + } + else + { + // Remove the speed loop for actual performance optimization + // for (int i = 0; i < 3000; i++) { + // await Task.Delay(1); + // } + + var totalWords = Messages.Sum(message => message.Text.Split(' ').Length); + var avgWordCount = Decimal.Divide(totalWords, Messages.Count); + MessageAnalysisResult = $"The average message length is {avgWordCount:0.##} words."; + } - return RedirectToPage(); -} + return RedirectToPage(); + } public static void WriteToDirectory(ZipArchiveEntry entry, string destDirectory) { From 92f0407c56f654a06cc5f6b70f3dfdf50ce557b3 Mon Sep 17 00:00:00 2001 From: Sayed Ali Date: Wed, 30 Oct 2024 14:36:31 +0100 Subject: [PATCH 14/14] Add Redis cache resource to main.bicep --- src/InfrastructureAsCode/main.bicep | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/InfrastructureAsCode/main.bicep b/src/InfrastructureAsCode/main.bicep index 2ce09735..2be12213 100644 --- a/src/InfrastructureAsCode/main.bicep +++ b/src/InfrastructureAsCode/main.bicep @@ -15,6 +15,21 @@ var imageName = 'techexcel/dotnetcoreapp' var startupCommand = '' +var redisCacheName = '${uniqueString(resourceGroup().id)}-mpnp-redis' + +resource redisCache 'Microsoft.Cache/Redis@2021-06-01' = { + name: redisCacheName + location: location + properties: { + sku: { + name: 'Basic' + family: 'C' + capacity: 0 + } + enableNonSslPort: false + } +} + resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-12-01-preview' = { name: logAnalyticsName location: location