From 6dc7c7a25ad353750eadd985619337b3852f06db Mon Sep 17 00:00:00 2001 From: Logan Cook <2997336+MWG-Logan@users.noreply.github.com> Date: Sat, 1 Nov 2025 01:27:11 -0400 Subject: [PATCH 01/16] Refactor and enhance maintainability across files (#12) - Removed unused DTOs folder reference in `Bezalu.ProjectReporting.API.csproj`. - Replaced hardcoded values with `maxNotes` constant in `ProjectCompletionReportFunction.cs` for better readability and consistency. - Reformatted `fileSave.js` to improve code clarity without functional changes. - Added `.webmanifest` to offline cache in `service-worker.published.js` to support PWAs. - Fixed syntax issue in `service-worker.published.js` by removing an extraneous closing bracket. --- .../Bezalu.ProjectReporting.API.csproj | 4 --- .../ProjectCompletionReportFunction.cs | 7 ++-- .../wwwroot/js/fileSave.js | 34 +++++++++---------- .../wwwroot/service-worker.published.js | 4 +-- 4 files changed, 23 insertions(+), 26 deletions(-) diff --git a/Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj b/Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj index 6d72cbf..8b34146 100644 --- a/Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj +++ b/Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj @@ -25,8 +25,4 @@ - - - - diff --git a/Bezalu.ProjectReporting.API/Functions/ProjectCompletionReportFunction.cs b/Bezalu.ProjectReporting.API/Functions/ProjectCompletionReportFunction.cs index 60a93a1..f491664 100644 --- a/Bezalu.ProjectReporting.API/Functions/ProjectCompletionReportFunction.cs +++ b/Bezalu.ProjectReporting.API/Functions/ProjectCompletionReportFunction.cs @@ -220,6 +220,7 @@ private static Action TicketsSection(ProjectCompletionReportResponse c.Column(col => { col.Item().Text("Tickets").FontSize(14).Bold(); + const int maxNotes = 10; foreach (var ticket in report.Tickets ?? []) col.Item().BorderBottom(1).PaddingVertical(4).Column(inner => { @@ -233,10 +234,10 @@ private static Action TicketsSection(ProjectCompletionReportResponse inner.Item().Text($"Assigned: {ticket.AssignedTo}").FontSize(9); if (ticket.Notes?.Any() != true) return; inner.Item().Text("Notes:").FontSize(9); - foreach (var n in ticket.Notes.Take(10)) + foreach (var n in ticket.Notes.Take(maxNotes)) inner.Item().Text($" - {n}").FontSize(9); - if (ticket.Notes.Count > 10) - inner.Item().Text($" - ... ({ticket.Notes.Count - 10} more notes truncated)").FontSize(9); + if (ticket.Notes.Count > maxNotes) + inner.Item().Text($" - ... ({ticket.Notes.Count - maxNotes} more notes truncated)").FontSize(9); }); }); }; diff --git a/Bezalu.ProjectReporting.Web/wwwroot/js/fileSave.js b/Bezalu.ProjectReporting.Web/wwwroot/js/fileSave.js index d5d5f72..3bd7f76 100644 --- a/Bezalu.ProjectReporting.Web/wwwroot/js/fileSave.js +++ b/Bezalu.ProjectReporting.Web/wwwroot/js/fileSave.js @@ -1,19 +1,19 @@ window.saveFile = (base64, fileName, mime) => { - try { - const binary = atob(base64); - const len = binary.length; - const bytes = new Uint8Array(len); - for (let i =0; i < len; i++) bytes[i] = binary.charCodeAt(i); - const blob = new Blob([bytes], { type: mime || 'application/octet-stream' }); - const url = URL.createObjectURL(blob); - const a = document.createElement('a'); - a.href = url; - a.download = fileName || 'download'; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - setTimeout(() => URL.revokeObjectURL(url),5000); - } catch (e) { - console.error('saveFile error', e); - } + try { + const binary = atob(base64); + const len = binary.length; + const bytes = new Uint8Array(len); + for (let i = 0; i < len; i++) bytes[i] = binary.charCodeAt(i); + const blob = new Blob([bytes], { type: mime || 'application/octet-stream' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = fileName || 'download'; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + setTimeout(() => URL.revokeObjectURL(url), 5000); + } catch (e) { + console.error('saveFile error', e); + } }; \ No newline at end of file diff --git a/Bezalu.ProjectReporting.Web/wwwroot/service-worker.published.js b/Bezalu.ProjectReporting.Web/wwwroot/service-worker.published.js index 1f7f543..091da58 100644 --- a/Bezalu.ProjectReporting.Web/wwwroot/service-worker.published.js +++ b/Bezalu.ProjectReporting.Web/wwwroot/service-worker.published.js @@ -8,7 +8,7 @@ self.addEventListener('fetch', event => event.respondWith(onFetch(event))); const cacheNamePrefix = 'offline-cache-'; const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`; -const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/ ]; +const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/, /\.webmanifest$/ ]; const offlineAssetsExclude = [ /^service-worker\.js$/ ]; // Replace with your base path if you are hosting on a subfolder. Ensure there is a trailing '/'. @@ -52,4 +52,4 @@ async function onFetch(event) { } return cachedResponse || fetch(event.request); -} +} \ No newline at end of file From 6dea923645cff87bb81dd0a20d6cdd0d4e67fc27 Mon Sep 17 00:00:00 2001 From: Logan Cook <2997336+MWG-Logan@users.noreply.github.com> Date: Fri, 19 Dec 2025 17:22:41 -0500 Subject: [PATCH 02/16] ci: add Azure Static Web Apps workflow file on-behalf-of: @Azure opensource@microsoft.com --- ...-static-web-apps-mango-coast-0420e6310.yml | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/azure-static-web-apps-mango-coast-0420e6310.yml diff --git a/.github/workflows/azure-static-web-apps-mango-coast-0420e6310.yml b/.github/workflows/azure-static-web-apps-mango-coast-0420e6310.yml new file mode 100644 index 0000000..82a30f5 --- /dev/null +++ b/.github/workflows/azure-static-web-apps-mango-coast-0420e6310.yml @@ -0,0 +1,46 @@ +name: Azure Static Web Apps CI/CD + +on: + push: + branches: + - dev + pull_request: + types: [opened, synchronize, reopened, closed] + branches: + - dev + +jobs: + build_and_deploy_job: + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') + runs-on: ubuntu-latest + name: Build and Deploy Job + steps: + - uses: actions/checkout@v3 + with: + submodules: true + lfs: false + - name: Build And Deploy + id: builddeploy + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_MANGO_COAST_0420E6310 }} + repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments) + action: "upload" + ###### Repository/Build Configurations - These values can be configured to match your app requirements. ###### + # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig + app_location: "/Bezalu.ProjectReporting.Web" # App source code path + api_location: "Bezalu.ProjectReporting.API" # Api source code path - optional + output_location: "wwwroot" # Built app content directory - optional + ###### End of Repository/Build Configurations ###### + + close_pull_request_job: + if: github.event_name == 'pull_request' && github.event.action == 'closed' + runs-on: ubuntu-latest + name: Close Pull Request Job + steps: + - name: Close Pull Request + id: closepullrequest + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_MANGO_COAST_0420E6310 }} + action: "close" From 4f912bd0ac836859f9475ed9affa68b4fce1d4ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 20:08:39 -0500 Subject: [PATCH 03/16] Bump Microsoft.AspNetCore.Components.WebAssembly from 10.0.0-rc.2.25502.107 to 10.0.0 (#15) --- updated-dependencies: - dependency-name: Microsoft.AspNetCore.Components.WebAssembly dependency-version: 10.0.0 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj b/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj index 45401cb..ff9e1f3 100644 --- a/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj +++ b/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj @@ -20,7 +20,7 @@ - + From 05a1f71474d9afc6ec7a21200d3b01c6e5fe19a6 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Fri, 19 Dec 2025 20:11:51 -0500 Subject: [PATCH 04/16] Move maxNotes constant to method scope in TicketsSection (#14) * Initial plan * Move maxNotes constant to method level for better organization Co-authored-by: MWG-Logan <2997336+MWG-Logan@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: MWG-Logan <2997336+MWG-Logan@users.noreply.github.com> --- .../Functions/ProjectCompletionReportFunction.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Bezalu.ProjectReporting.API/Functions/ProjectCompletionReportFunction.cs b/Bezalu.ProjectReporting.API/Functions/ProjectCompletionReportFunction.cs index f491664..e43ebac 100644 --- a/Bezalu.ProjectReporting.API/Functions/ProjectCompletionReportFunction.cs +++ b/Bezalu.ProjectReporting.API/Functions/ProjectCompletionReportFunction.cs @@ -217,10 +217,10 @@ private static Action TicketsSection(ProjectCompletionReportResponse { return c => { + const int maxNotes = 10; c.Column(col => { col.Item().Text("Tickets").FontSize(14).Bold(); - const int maxNotes = 10; foreach (var ticket in report.Tickets ?? []) col.Item().BorderBottom(1).PaddingVertical(4).Column(inner => { From 5f77e02056ed9ae90303e2cadb45474213977688 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 20:12:40 -0500 Subject: [PATCH 05/16] Bump Microsoft.Azure.Functions.Worker from 2.50.0-preview2 to 2.51.0 (#17) --- updated-dependencies: - dependency-name: Microsoft.Azure.Functions.Worker dependency-version: 2.51.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj b/Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj index 8b34146..7624721 100644 --- a/Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj +++ b/Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj @@ -12,7 +12,7 @@ - + From ac68949ff94bfc51ff887b213b494dc9cbd52df0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Dec 2025 15:42:25 -0500 Subject: [PATCH 06/16] Bump Microsoft.Azure.Functions.Worker.Sdk from 2.0.5 to 2.0.7 (#19) --- updated-dependencies: - dependency-name: Microsoft.Azure.Functions.Worker.Sdk dependency-version: 2.0.7 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj b/Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj index 7624721..bcf108c 100644 --- a/Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj +++ b/Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj @@ -15,7 +15,7 @@ - + From 2e0d82a5197a188dabfbe3554731baa9c0f62d9a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Dec 2025 15:42:55 -0500 Subject: [PATCH 07/16] Bump Markdig from 0.43.0 to 0.44.0 (#21) --- updated-dependencies: - dependency-name: Markdig dependency-version: 0.44.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj b/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj index ff9e1f3..e5ed1dc 100644 --- a/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj +++ b/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj @@ -19,7 +19,7 @@ - + From 8c46d31b3875565f751de38618420d1e71dbc958 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Dec 2025 16:12:59 -0500 Subject: [PATCH 08/16] Bump Microsoft.Azure.Functions.Worker.ApplicationInsights from 2.0.0 to 2.50.0 (#18) --- updated-dependencies: - dependency-name: Microsoft.Azure.Functions.Worker.ApplicationInsights dependency-version: 2.50.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj b/Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj index bcf108c..c21260a 100644 --- a/Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj +++ b/Bezalu.ProjectReporting.API/Bezalu.ProjectReporting.API.csproj @@ -13,7 +13,7 @@ - + From 062786829d2cd206d827ce59415d45e6f769ef53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Dec 2025 16:13:29 -0500 Subject: [PATCH 09/16] Bump Microsoft.AspNetCore.Components.WebAssembly from 10.0.0 to 10.0.1 (#22) --- updated-dependencies: - dependency-name: Microsoft.AspNetCore.Components.WebAssembly dependency-version: 10.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj b/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj index e5ed1dc..2cf81e0 100644 --- a/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj +++ b/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj @@ -20,7 +20,7 @@ - + From fa5fc30201c312da6afbc6874166452d82986851 Mon Sep 17 00:00:00 2001 From: Logan Cook <2997336+MWG-Logan@users.noreply.github.com> Date: Tue, 23 Dec 2025 16:14:42 -0500 Subject: [PATCH 10/16] SWA auth (#24) * Add staticwebapp.config.json to project output * Add staticwebapp.config.json for routing and auth * Update Bezalu.ProjectReporting.Web/staticwebapp.config.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: Move staticwebapp.config.json to wwwroot directory * fix: Change routes from object to array format --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../Bezalu.ProjectReporting.Web.csproj | 6 ++++++ .../wwwroot/staticwebapp.config.json | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 Bezalu.ProjectReporting.Web/wwwroot/staticwebapp.config.json diff --git a/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj b/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj index 2cf81e0..cf6e240 100644 --- a/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj +++ b/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj @@ -30,6 +30,12 @@ + + + PreserveNewest + + + diff --git a/Bezalu.ProjectReporting.Web/wwwroot/staticwebapp.config.json b/Bezalu.ProjectReporting.Web/wwwroot/staticwebapp.config.json new file mode 100644 index 0000000..97f7b2e --- /dev/null +++ b/Bezalu.ProjectReporting.Web/wwwroot/staticwebapp.config.json @@ -0,0 +1,18 @@ +{ + "routes": [ + { + "route": "/api/*", + "allowedRoles": ["authenticated"] + }, + { + "route": "/login", + "rewrite": "/.auth/login/aad" + } + ], + "responseOverrides": { + "401": { + "redirect": "/.auth/login/aad?post_login_redirect_uri=.referrer", + "statusCode": 302 + } + } +} From 56b87c12db1a0d1a0fbb8e2704948ce86467dcac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Dec 2025 16:19:09 -0500 Subject: [PATCH 11/16] Bump Microsoft.AspNetCore.Components.WebAssembly.DevServer from 10.0.0-rc.2.25502.107 to 10.0.1 (#23) --- updated-dependencies: - dependency-name: Microsoft.AspNetCore.Components.WebAssembly.DevServer dependency-version: 10.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj b/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj index cf6e240..67f8735 100644 --- a/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj +++ b/Bezalu.ProjectReporting.Web/Bezalu.ProjectReporting.Web.csproj @@ -21,7 +21,7 @@ - + From 18b28db23bb24614fa82958e1d4d261df0fad544 Mon Sep 17 00:00:00 2001 From: Logan Cook <2997336+MWG-Logan@users.noreply.github.com> Date: Tue, 23 Dec 2025 16:27:57 -0500 Subject: [PATCH 12/16] Update workflow for .NET 10 build and custom deployment (#20) * Update workflow for .NET 10 build and custom deployment Refactored the GitHub Actions workflow to use .NET 10.0, added explicit restore/build/publish steps, and updated environment variables for optimized .NET builds. Changed deployment to use published output, skip internal builds, and set production branch to 'main'. Updated checkout and deployment actions, and cleaned up unused config and comments. * Update workflow to build and deploy new project target Changed the job name and PROJECT path in the GitHub Actions workflow to reference Bezalu.ProjectReporting.Web instead of MyAzureSWAProject, ensuring the correct project is built and deployed. * Add dotnet workload restore step to build workflow Added a "Workload Restore" step in the CI workflow to run `dotnet workload restore` after restoring project dependencies. This ensures all required .NET SDK workloads are available before build and publish steps. * Update .NET restore step to restore all packages Renamed the "Restore" step to "Package Restore" and changed the command from restoring a specific project to restoring all packages in the solution. This ensures dependencies for all projects are restored. * Reorder restore steps in Azure pipeline workflow Swapped the order of "Package Restore" and "Workload Restore" steps in the Azure pipeline YAML. "Workload Restore" now runs before "Package Restore" to improve build step sequencing. No other changes were made. * Corrected API Readme MD Syntax * Simplify .NET build workflow in Azure pipeline Removed separate restore and build steps from the workflow. The publish step now performs the build directly by omitting the "--no-build" flag, streamlining the deployment process, and skipping some weird state problems. * Updated SWA workflow, naming of workflows, and added OIDC based func workflow * Tweaking SWA workflow to conform more closely to func * fixing version scheme * incorrect param syntax * Replace SWA flow auth with OIDC * permission correction * Changing OIDC method * swa fixes (f u github) * replace SWA flow with MS Learn example * Update SWA deployment workflow --- .github/workflows/func-deploy.yml | 87 +++++++++++++ ...ngo-coast-0420e6310.yml => swa-deploy.yml} | 116 +++++++++++------- Bezalu.ProjectReporting.API/README.md | 28 ++++- 3 files changed, 182 insertions(+), 49 deletions(-) create mode 100644 .github/workflows/func-deploy.yml rename .github/workflows/{azure-static-web-apps-mango-coast-0420e6310.yml => swa-deploy.yml} (59%) diff --git a/.github/workflows/func-deploy.yml b/.github/workflows/func-deploy.yml new file mode 100644 index 0000000..cd8b750 --- /dev/null +++ b/.github/workflows/func-deploy.yml @@ -0,0 +1,87 @@ +name: Build and deploy .NET project to Azure Function App using OIDC + +# CONFIGURATION +# +# This workflow can be used to deploy your .NET project to a function app on any hosting plan, except for Container Apps (which uses functions-container-action). +# +# For an overview of using GitHub workflows with Azure Functions, see https://learn.microsoft.com/azure/azure-functions/functions-how-to-github-actions +# +# 1. Configure a federated identity credential to your GitHub branch on an Azure user-assigned managed identity. +# For instructions, follow the README at https://github.com/Azure/functions-action#use-oidc-recommended +# +# 2. Add the following values from the managed identity to your repo's variables: +# AZURE_CLIENT_ID +# AZURE_TENANT_ID +# AZURE_SUBSCRIPTION_ID +# For instructions on creating repo variables, see https://docs.github.com/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#defining-configuration-variables-for-multiple-workflows +# +# 3. Ensure your workflow is triggered by your desired event. By default, it is triggered when a push is made to main, and it can be manually run. +# For guidance on event triggers, see https://docs.github.com/actions/writing-workflows/choosing-when-your-workflow-runs/triggering-a-workflow#using-events-to-trigger-workflows + +on: + push: + branches: [ main ] + workflow_dispatch: + +env: + AZURE_FUNCTIONAPP_NAME: ${{ vars.FUNCTION_APP_NAME }} + AZURE_FUNCTIONAPP_PROJECT_PATH: 'Bezalu.ProjectReporting.API' + DOTNET_VERSION: '10.0.x' + BUILD_ARTIFACT_NAME: 'Bezalu.ProjectReporting.API' + +jobs: + build: + runs-on: ubuntu-latest # Assumes your target function app is Linux-based + permissions: + id-token: write # Required for OIDC + contents: read # Required for actions/checkout + defaults: + run: + shell: bash + working-directory: ${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }} + steps: + - name: 'Checkout repository' + uses: actions/checkout@v6 + + - name: 'Set up .NET version: ${{ env.DOTNET_VERSION }}' + uses: actions/setup-dotnet@v5 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + + # Perform additional steps such as running tests, if needed + + - name: 'Build and prepare .NET project for deployment' + run: dotnet publish --configuration Release --output ./output + + - name: Upload artifact for the deployment job + uses: actions/upload-artifact@v4 + with: + name: ${{ env.BUILD_ARTIFACT_NAME }} + path: ${{ env.AZURE_FUNCTIONAPP_PROJECT_PATH }}/output + include-hidden-files: true # Required for .NET projects + + deploy: + runs-on: ubuntu-latest # Assumes your target function app is Linux-based + needs: build + permissions: + id-token: write # Required for OIDC + steps: + - name: 'Download artifact from build job' + uses: actions/download-artifact@v4 + with: + name: ${{ env.BUILD_ARTIFACT_NAME }} + path: ./downloaded-artifact + + - name: 'Log in to Azure with AZ CLI' + uses: azure/login@v2 + with: + client-id: ${{ vars.AZURE_CLIENT_ID }} + tenant-id: ${{ vars.AZURE_TENANT_ID }} + subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }} + + - name: 'Run the Azure Functions action' + uses: Azure/functions-action@v1 + id: deploy-to-function-app + with: + app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }} + package: ./downloaded-artifact diff --git a/.github/workflows/azure-static-web-apps-mango-coast-0420e6310.yml b/.github/workflows/swa-deploy.yml similarity index 59% rename from .github/workflows/azure-static-web-apps-mango-coast-0420e6310.yml rename to .github/workflows/swa-deploy.yml index 82a30f5..ac7fc00 100644 --- a/.github/workflows/azure-static-web-apps-mango-coast-0420e6310.yml +++ b/.github/workflows/swa-deploy.yml @@ -1,46 +1,70 @@ -name: Azure Static Web Apps CI/CD - -on: - push: - branches: - - dev - pull_request: - types: [opened, synchronize, reopened, closed] - branches: - - dev - -jobs: - build_and_deploy_job: - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') - runs-on: ubuntu-latest - name: Build and Deploy Job - steps: - - uses: actions/checkout@v3 - with: - submodules: true - lfs: false - - name: Build And Deploy - id: builddeploy - uses: Azure/static-web-apps-deploy@v1 - with: - azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_MANGO_COAST_0420E6310 }} - repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments) - action: "upload" - ###### Repository/Build Configurations - These values can be configured to match your app requirements. ###### - # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig - app_location: "/Bezalu.ProjectReporting.Web" # App source code path - api_location: "Bezalu.ProjectReporting.API" # Api source code path - optional - output_location: "wwwroot" # Built app content directory - optional - ###### End of Repository/Build Configurations ###### - - close_pull_request_job: - if: github.event_name == 'pull_request' && github.event.action == 'closed' - runs-on: ubuntu-latest - name: Close Pull Request Job - steps: - - name: Close Pull Request - id: closepullrequest - uses: Azure/static-web-apps-deploy@v1 - with: - azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_MANGO_COAST_0420E6310 }} - action: "close" +name: Azure Static Web Apps CI/CD + +on: + push: + branches: + - main + pull_request: + types: [opened, synchronize, reopened, closed] + branches: + - main + +jobs: + build_and_deploy_job: + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') + runs-on: ubuntu-latest + name: Build and Deploy Job + steps: + - uses: actions/checkout@v6 + with: + submodules: true + lfs: false + + - name: Setup .NET 10.0 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 10.0.x + + - name: Install Workloads + run: dotnet workload restore + + - name: Restore + run: dotnet restore + + - name: .NET Publish + run: dotnet publish Bezalu.ProjectReporting.Web -c Release -o Bezalu.ProjectReporting.Web/publish + + - name: List publish output for debugging + run: ls -al ./Bezalu.ProjectReporting.Web/publish/wwwroot + + - name: Build And Deploy + id: builddeploy + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }} + repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments) + action: "upload" + app_location: 'Bezalu.ProjectReporting.Web/publish/wwwroot' + skip_api_build: true + skip_app_build: true + + close_pull_request_job: + if: github.event_name == 'pull_request' && github.event.action == 'closed' + runs-on: ubuntu-latest + name: Close Pull Request Job + steps: + - name: Close Pull Request + id: closepullrequest + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }} + action: "close" + + + + + + + + + diff --git a/Bezalu.ProjectReporting.API/README.md b/Bezalu.ProjectReporting.API/README.md index 326e01a..c739a88 100644 --- a/Bezalu.ProjectReporting.API/README.md +++ b/Bezalu.ProjectReporting.API/README.md @@ -10,6 +10,7 @@ Full solution providing interactive project completion reporting for ConnectWise - PDF generation via QuestPDF using already fetched report payload (no regeneration). ## End-to-End Flow + 1. User enters Project ID and triggers `POST /api/reports/project-completion`. 2. API aggregates ConnectWise data, builds `ProjectCompletionReportResponse`, calls Azure OpenAI for AI summary, returns JSON. 3. Front-end displays report (timeline, budget, phases, tickets, AI summary rendered as Markdown). @@ -19,17 +20,22 @@ Full solution providing interactive project completion reporting for ConnectWise ## Primary API Endpoints ### POST /api/reports/project-completion + Request body: -``` + +```json { "projectId":12345 } ``` + Response: `ProjectCompletionReportResponse` (see docs/contract.md). ### POST /api/reports/project-completion/pdf + Request body: full `ProjectCompletionReportResponse` previously returned by the first endpoint. Response: `application/pdf` file. ## Report Object Highlights + - Summary (status, dates, manager, company) - TimelineAnalysis (planned vs actual days, variance, adherence, performance %) - BudgetAnalysis (estimated vs actual hours, variance, adherence) @@ -38,55 +44,70 @@ Response: `application/pdf` file. - AiGeneratedSummary (markdown rendered client-side with Markdig) ## Operability Notes + - PDF endpoint expects complete report payload; front-end must retain JSON until download. - AI call cost avoided for PDF generation due to reuse of existing summary. - Truncation applied to notes for AI prompt and PDF to control size. ## Local Development + Prerequisites: + - .NET SDK - Azure Functions Core Tools - Valid ConnectWise + Azure OpenAI credentials in `local.settings.json` (excluded from source control). Run API: -``` + +```bash func start ``` + Run front-end: -``` + +```bash dotnet run --project Bezalu.ProjectReporting.Web ``` + Front-end will proxy to API according to Static Web Apps configuration/emulator or manual CORS settings if needed. ## Azure Deployment Overview + - Deploy Blazor WebAssembly output (Release) to Azure Static Web Apps. - Deploy Azure Functions project to same Static Web Apps resource (api folder) or separate Functions App (configure SWA `api_location`). - Set configuration (App Settings) for ConnectWise and Azure OpenAI keys; prefer Key Vault references in production. Required App Settings: + - `ConnectWise:BaseUrl`, `ConnectWise:CompanyId`, `ConnectWise:PublicKey`, `ConnectWise:PrivateKey`, `ConnectWise:ClientId` - `AzureOpenAI:Endpoint`, `AzureOpenAI:DeploymentName` (credential via `DefaultAzureCredential` in code; ensure managed identity / RBAC permissions) ## Performance & Size + - WASM project uses trimming + AOT for faster runtime once cached; consider disabling AOT in Debug for faster builds. - AI prompt size limited by truncation strategies in service. ## Error Handling + -400 invalid project id or invalid report payload for PDF endpoint. -404 project not found. -500 unexpected processing errors. ## Security + - Function auth level currently `Function`; set keys or add front-end auth (e.g., Entra ID) before production. - Do not send sensitive data inside report payload for PDF endpoint; only project analysis data. ## Extensibility + - Add cached layer to reuse raw data for multiple exports. - Extend PDF sections (charts) by computing aggregates client-side and passing them in extended DTO. - Add Excel export by introducing another POST /api/reports/project-completion/excel endpoint using a spreadsheet library server-side. ## Documentation + See `/docs` for deeper details: + - architecture.md (layer & data flow) - contract.md (DTO shapes) - pdf.md (PDF composition logic) @@ -94,4 +115,5 @@ See `/docs` for deeper details: - frontend.md (UI behaviors) --- + This README targets the operational overview; for detailed structures consult docs directory. From 36935b9c5198c9d76db14f9ab486fff89194810e Mon Sep 17 00:00:00 2001 From: Logan Cook <2997336+MWG-Logan@users.noreply.github.com> Date: Tue, 23 Dec 2025 16:39:10 -0500 Subject: [PATCH 13/16] Update Bezalu.ProjectReporting.API/README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Bezalu.ProjectReporting.API/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Bezalu.ProjectReporting.API/README.md b/Bezalu.ProjectReporting.API/README.md index c739a88..434136e 100644 --- a/Bezalu.ProjectReporting.API/README.md +++ b/Bezalu.ProjectReporting.API/README.md @@ -89,9 +89,9 @@ Required App Settings: ## Error Handling --400 invalid project id or invalid report payload for PDF endpoint. --404 project not found. --500 unexpected processing errors. +- 400 invalid project id or invalid report payload for PDF endpoint. +- 404 project not found. +- 500 unexpected processing errors. ## Security From cfd5f2773d5a10963312d29cb18f3bcead9a4e81 Mon Sep 17 00:00:00 2001 From: Logan Cook <2997336+MWG-Logan@users.noreply.github.com> Date: Tue, 23 Dec 2025 16:39:30 -0500 Subject: [PATCH 14/16] Update .github/workflows/swa-deploy.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/workflows/swa-deploy.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/swa-deploy.yml b/.github/workflows/swa-deploy.yml index ac7fc00..42c56f7 100644 --- a/.github/workflows/swa-deploy.yml +++ b/.github/workflows/swa-deploy.yml @@ -59,12 +59,3 @@ jobs: with: azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }} action: "close" - - - - - - - - - From 7884e0e4fe97b06dae4fb723d3270e17a9858346 Mon Sep 17 00:00:00 2001 From: Logan Cook <2997336+MWG-Logan@users.noreply.github.com> Date: Tue, 23 Dec 2025 16:40:21 -0500 Subject: [PATCH 15/16] Update Bezalu.ProjectReporting.Web/wwwroot/staticwebapp.config.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Bezalu.ProjectReporting.Web/wwwroot/staticwebapp.config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Bezalu.ProjectReporting.Web/wwwroot/staticwebapp.config.json b/Bezalu.ProjectReporting.Web/wwwroot/staticwebapp.config.json index 97f7b2e..3eeff23 100644 --- a/Bezalu.ProjectReporting.Web/wwwroot/staticwebapp.config.json +++ b/Bezalu.ProjectReporting.Web/wwwroot/staticwebapp.config.json @@ -8,7 +8,7 @@ "route": "/login", "rewrite": "/.auth/login/aad" } - ], + ], "responseOverrides": { "401": { "redirect": "/.auth/login/aad?post_login_redirect_uri=.referrer", From 703286ecb19e0481cbc8751e30028cfbd9c33879 Mon Sep 17 00:00:00 2001 From: Logan Cook <2997336+MWG-Logan@users.noreply.github.com> Date: Tue, 23 Dec 2025 16:47:22 -0500 Subject: [PATCH 16/16] Update workflow to include permissions Add permissions for contents and pull-requests --- .github/workflows/swa-deploy.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/swa-deploy.yml b/.github/workflows/swa-deploy.yml index 42c56f7..ecbe8b3 100644 --- a/.github/workflows/swa-deploy.yml +++ b/.github/workflows/swa-deploy.yml @@ -1,4 +1,7 @@ name: Azure Static Web Apps CI/CD +permissions: + contents: read + pull-requests: write on: push: