Skip to content

Conversation

@moconnell
Copy link
Owner

@moconnell moconnell commented Dec 23, 2025

Summary by CodeRabbit

  • New Features

    • Added production alerting for function failures, exceptions, and timer-trigger issues with email notifications.
  • Documentation

    • Added comprehensive logging guidance, troubleshooting steps, and monitoring/alerts setup.
    • Removed an outdated deployment guide.
  • Configuration

    • Improved logging defaults and extended scheduling settings.
    • Increased function timeout and unified resource tagging.
  • Chores

    • Updated CI workflows: branch handling, deploy gating for production alerts, Dependabot test behavior, and resource cleanup improvements.

✏️ Tip: You can customize this high-level summary in your review settings.

@moconnell moconnell self-assigned this Dec 23, 2025
@moconnell moconnell added bug Something isn't working enhancement New feature or request Azure labels Dec 23, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 23, 2025

📝 Walkthrough

Walkthrough

This PR adds Bicep-based alerting for the Function App, updates Function App infrastructure and CI/CD workflows to support alert deployment and tag-based resource operations, introduces structured logging and timeout settings for the Functions runtime, and adds comprehensive logging and monitoring documentation while removing an existing DEPLOYMENT doc.

Changes

Cohort / File(s) Summary
Alerting infra
.azure/alert-rules.bicep
New Bicep module creating an email Action Group and three alert rules plus one metric alert (Function Execution Failures, Exceptions, Timer Trigger Failures), referencing the Function App and Application Insights; exposes four outputs (actionGroupId, functionFailureAlertId, exceptionAlertId, timerTriggerAlertId).
Function app IaC
.azure/function-app.bicep
Replaces explicit Key Vault ID with dynamic keyVaultUri by env suffix; merges resourceTags (Environment, ManagedBy, FunctionApp) and applies to resources; adds schedule app settings for strategies; adds storageAccountName output.
CI/CD: deploy workflow
.github/workflows/deploy-azure-functions.yml
Switches to repository vars for RG/location, adds Dependabot skip logic, updates branch pattern handling, adds path triggers, and adds production-only Deploy Alert Rules steps that invoke the new alert-rules Bicep.
CI/CD: cleanup workflow
.github/workflows/cleanup-azure-functions.yml
Changes storage account discovery to tag-based filtering (Environment, FunctionApp), simplifies deletion logic and logging, retains Function App and Plan deletion.
CI/CD: dotnet workflow
.github/workflows/dotnet.yml
Adds workflow permissions and Dependabot-aware test steps (skip integration tests for Dependabot PRs) and a post-merge comment step when tests are skipped.
App config
src/YoloFunk/host.json
Disables Request sampling (isEnabled: false), adds global logLevel defaults, and sets functionTimeout to 00:10:00.
App config
src/YoloFunk/appsettings.json
Adds logging categories YoloFunk, YoloTrades, YoloBroker (Information) and ApplicationInsights LogLevel config.
Documentation — logging/monitoring
docs/AZURE-LOGGING-QUERIES.md, docs/AZURE-LOGGING-TROUBLESHOOT.md, docs/AZURE-MONITORING-ALERTS.md
New comprehensive docs: KQL queries and logging guidance, troubleshooting steps for missing logs, and detailed alert setup/deployment guidance including GitHub variable ALERT_EMAIL and evaluation windows.
Documentation — removed
src/YoloFunk/docs/DEPLOYMENT.md
Deleted the existing Azure Functions deployment guide.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant GitHubActions as GitHub Actions
participant Bicep as Bicep deployment
participant AzureRG as Resource Group
participant FunctionApp as Function App
participant AppInsights as Application Insights
participant ActionGroup as Email Action Group
participant Alerting as Azure Monitor Alerts
GitHubActions->>Bicep: deploy alert-rules.bicep (prod, ALERT_EMAIL)
Bicep->>AzureRG: provision/patch resources
Bicep->>FunctionApp: reference existing Function App
Bicep->>AppInsights: reference existing App Insights
Bicep->>ActionGroup: create email Action Group
Bicep->>Alerting: create metric & scheduled query alerts (link Action Group, Function/AppInsights)
Alerting->>ActionGroup: bind alerts to action group
Note over ActionGroup,Alerting: Alerts now notify email on trigger

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested labels

documentation

"I’m a little rabbit, nose all a-twitch,
I wired the alarms and I fixed up the switch,
I dug through the logs and I stitched every thread,
Now alerts hop to inboxes while carrots I head 🥕🐇"

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main focus of the changeset, which introduces Azure monitoring alerts (alert-rules.bicep) and improves logging configuration across multiple files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

🚀 Deployed to Azure Functions

Environment: pr-88
Function App: yolo-funk-pr-88
URL: https://yolo-funk-pr-88.azurewebsites.net
Network: testnet

This environment will be automatically cleaned up when the PR is closed.

- logs not appearing in App Insights
@github-actions
Copy link

🚀 Deployed to Azure Functions

Environment: pr-88
Function App: yolo-funk-pr-88
URL: https://yolo-funk-pr-88.azurewebsites.net
Network: testnet

This environment will be automatically cleaned up when the PR is closed.

@moconnell moconnell marked this pull request as ready for review December 23, 2025 11:41
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (8)
.github/workflows/dotnet.yml (1)

49-60: Consider duplicate comment prevention.

The step will run on every Dependabot PR workflow execution. If the PR has multiple pushes or re-runs, this could create duplicate comments.

🔎 Optional: Add duplicate comment check
      - name: Comment on Dependabot PR
        if: github.actor == 'dependabot[bot]' && github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
+           // Check for existing comment to avoid duplicates
+           const comments = await github.rest.issues.listComments({
+             issue_number: context.issue.number,
+             owner: context.repo.owner,
+             repo: context.repo.repo
+           });
+           const hasComment = comments.data.some(c => 
+             c.user.login === 'github-actions[bot]' && 
+             c.body.includes('Build Successful (Dependabot)')
+           );
+           if (hasComment) return;
+           
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `### ✅ Build Successful (Dependabot)\n\n**Note:** Integration tests requiring secrets were skipped for security.\n\n- ✅ Build completed\n- ✅ Unit tests passed\n- ⏭️ Integration tests skipped (no secrets)\n- ⏭️ Azure deployment skipped\n\nOnce merged, full integration tests and deployment will run automatically.`
            })
docs/AZURE-LOGGING-QUERIES.md (2)

26-28: Add language specifier to fenced code blocks.

Per static analysis (markdownlint MD040), these navigation path code blocks should have a language specifier. Using text is appropriate for plain text content.

🔎 Suggested fix
-```
+```text
 Function App → Monitoring → Log stream

Apply similar fix to lines 34 and 262.
</details>


Also applies to: 34-36, 262-264

---

`279-281`: **Consider updating deprecated instrumentation key reference.**

`APPINSIGHTS_INSTRUMENTATIONKEY` is being deprecated in favor of `APPLICATIONINSIGHTS_CONNECTION_STRING`. Consider updating the troubleshooting guidance to mention both, with the connection string as the primary reference.



<details>
<summary>🔎 Suggested update</summary>

```diff
 **Logs not appearing:**
 
-- Check Application Insights connection string is configured
-- Verify `APPINSIGHTS_INSTRUMENTATIONKEY` in function app settings
+- Check `APPLICATIONINSIGHTS_CONNECTION_STRING` is configured in function app settings
+- (Legacy) Verify `APPINSIGHTS_INSTRUMENTATIONKEY` if using older setup
 - Wait 2-3 minutes for logs to appear in Application Insights
.azure/function-app.bicep (1)

84-90: Consider using managed identity for storage access.

The storage connection strings use account keys, which is the standard pattern. When feasible, consider migrating to managed identity-based access (AzureWebJobsStorage__accountName) to eliminate key rotation concerns.

This is a future improvement opportunity, not a blocker for this PR.

.github/workflows/cleanup-azure-functions.yml (1)

95-105: Consider logging when storage accounts are found but have unexpected tags.

If the deployment fails partway through or tags aren't applied correctly, storage accounts might exist without the expected tags. The current logic handles this gracefully, but a debug log could aid troubleshooting.

🔎 Optional: Add debug logging for all storage accounts
+           # Debug: List all storage accounts for visibility
+           echo "All storage accounts in resource group:"
+           az storage account list \
+             --resource-group ${{ env.AZURE_RESOURCE_GROUP }} \
+             --query "[].{name:name, env:tags.Environment, func:tags.FunctionApp}" \
+             --output table || true
+
            if [ -n "$STORAGE_ACCOUNTS" ]; then
              for STORAGE in $STORAGE_ACCOUNTS; do
docs/AZURE-MONITORING-ALERTS.md (1)

34-36: Consider using placeholder email in documentation.

The example uses what appears to be a real email address. Consider using a generic placeholder like alerts@example.com or your-email@example.com.

🔎 Suggested change
-4. Value: Your email address (e.g., `matthew.oconnell@gmail.com`)
+4. Value: Your email address (e.g., `alerts@example.com`)
.azure/alert-rules.bicep (2)

16-18: Consider parameterizing the Application Insights name.

The Application Insights name is hard-coded as 'yolo-funk-insights'. If your naming convention changes or you deploy to different environments with different insights instances, this will cause issues.

🔎 Proposed refactor to add parameter
 @description('Resource location')
 param location string = resourceGroup().location
+
+@description('Application Insights name')
+param appInsightsName string = 'yolo-funk-insights'

 // Get existing Application Insights
 resource appInsights 'Microsoft.Insights/components@2020-02-02' existing = {
-  name: 'yolo-funk-insights'
+  name: appInsightsName
 }

137-142: Timer trigger failure detection is heuristic-based.

The query searches for "Timer trigger" with "error" or "failed" in trace messages. This is a reasonable heuristic but may:

  • Miss failures with different error message formats
  • Generate false positives if "error" or "failed" appear in non-failure contexts

Consider supplementing this with additional telemetry or custom logging for more reliable timer trigger monitoring.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fdb8e68 and 037138d.

📒 Files selected for processing (12)
  • .azure/alert-rules.bicep
  • .azure/function-app.bicep
  • .github/workflows/cleanup-azure-functions.yml
  • .github/workflows/deploy-azure-functions.yml
  • .github/workflows/dotnet.yml
  • docs/AZURE-LOGGING-QUERIES.md
  • docs/AZURE-LOGGING-TROUBLESHOOT.md
  • docs/AZURE-MONITORING-ALERTS.md
  • docs/STRATEGY-ARCHITECTURE.md
  • src/YoloFunk/appsettings.json
  • src/YoloFunk/docs/DEPLOYMENT.md
  • src/YoloFunk/host.json
💤 Files with no reviewable changes (1)
  • src/YoloFunk/docs/DEPLOYMENT.md
🧰 Additional context used
🪛 markdownlint-cli2 (0.18.1)
docs/AZURE-LOGGING-QUERIES.md

26-26: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


34-34: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


262-262: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (14)
.github/workflows/dotnet.yml (3)

5-7: LGTM!

The permissions are appropriately scoped - contents: read for checkout and pull-requests: write for commenting on Dependabot PRs.


11-12: LGTM!

Good approach to conditionally skip the environment requirement for Dependabot PRs, as they cannot access repository secrets.


25-37: LGTM!

Clean implementation of conditional test execution - full tests with secrets for regular PRs, filtered unit tests for Dependabot. The Category!=Integration filter correctly excludes integration tests.

docs/AZURE-LOGGING-QUERIES.md (1)

1-300: LGTM! Comprehensive logging guide.

Well-structured documentation covering log locations, KQL queries, structured logging patterns, and troubleshooting. The guidance on disabling sampling (line 85) aligns with the host.json changes in this PR.

.azure/function-app.bicep (2)

31-36: LGTM! Clean tag management.

Using union() to merge tags ensures environment-specific tags take precedence while preserving any custom tags passed in. This aligns well with the tag-based cleanup logic in the workflow.


173-180: LGTM! Schedule settings now persisted in infrastructure.

Good fix for the environment variable persistence issue. The NCRONTAB expressions are valid Azure Functions format (6 fields: second minute hour day month day-of-week).

src/YoloFunk/appsettings.json (1)

6-16: LGTM! Well-structured logging configuration.

Adding explicit categories for YoloFunk, YoloTrades, and YoloBroker enables granular log filtering. The ApplicationInsights section ensures consistent log levels when writing to Application Insights.

src/YoloFunk/host.json (2)

5-7: Good fix: Disabling sampling prevents log loss.

Setting isEnabled: false ensures all logs reach Application Insights. This is the correct fix for the "only seeing framework logs" issue mentioned in the documentation.


17-17: Verify timeout aligns with function execution needs.

The 10-minute timeout is the maximum for Consumption plan. Ensure your rebalance operations complete well within this window, or consider Premium plan if longer execution is needed.

.github/workflows/cleanup-azure-functions.yml (1)

89-105: LGTM! Tag-based cleanup is more reliable.

Using tags.Environment and tags.FunctionApp for storage account discovery is a robust improvement over name-based matching. This aligns with the resourceTags implementation in function-app.bicep.

docs/AZURE-MONITORING-ALERTS.md (1)

1-140: LGTM! Clear and actionable documentation.

Good explanation of the environment variable persistence issue, with concrete steps for setting up email alerts. The troubleshooting section covers common issues effectively.

docs/AZURE-LOGGING-TROUBLESHOOT.md (1)

1-113: LGTM! Excellent quick-reference troubleshooting guide.

This document provides actionable steps for the most common logging issue. The quick reference table (lines 99-106) and common issues checklist (lines 107-113) are particularly useful for rapid diagnosis.

.azure/alert-rules.bicep (1)

79-118: LGTM! Exception alert implementation looks solid.

The scheduled query rule correctly filters exceptions by cloud_RoleName and alerts on any exception count. The 5-minute evaluation frequency with a 15-minute window provides good balance between responsiveness and noise reduction.

.github/workflows/deploy-azure-functions.yml (1)

65-70: LGTM! Dependabot skip logic is correct.

Properly prevents deployment failures for Dependabot PRs that lack access to secrets. This is a best practice for workflows requiring authenticated Azure operations.

@moconnell moconnell changed the title Various YoloFunk Fixes (2025-12-23) Azure monitoring alerts and logging improvements Dec 23, 2025
@github-actions
Copy link

github-actions bot commented Jan 9, 2026

🚀 Deployed to Azure Functions

Environment: pr-88
Function App: yolo-funk-pr-88
URL: https://yolo-funk-pr-88.azurewebsites.net
Network: testnet

This environment will be automatically cleaned up when the PR is closed.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.github/workflows/deploy-azure-functions.yml (2)

120-133: Don’t suppress all errors on role assignment creation—this can mask real permission/tenant failures.
2>/dev/null || echo "…failed" will let the job continue even when the role assignment wasn’t created and doesn’t already exist.

Proposed diff
           az role assignment create \
             --assignee-object-id $SP_OBJECT_ID \
             --assignee-principal-type ServicePrincipal \
             --role "User Access Administrator" \
             --scope /subscriptions/${{ secrets.AZURE_SUBSCRIPTION_ID }}/resourceGroups/${{ vars.AZURE_RESOURCE_GROUP }} \
-            2>/dev/null || echo "Role assignment already exists or failed (may already be assigned)"
+          || {
+            echo "Role assignment create failed. Existing assignments (if any):"
+            az role assignment list \
+              --assignee-object-id "$SP_OBJECT_ID" \
+              --scope "/subscriptions/${{ secrets.AZURE_SUBSCRIPTION_ID }}/resourceGroups/${{ vars.AZURE_RESOURCE_GROUP }}" \
+              -o table || true
+            exit 1
+          }

152-177: Quote JSON parsing to avoid word-splitting issues (echo $OUTPUT | jq …).
This is a reliability footgun if the JSON ever contains whitespace/newlines.

Proposed diff
-          FUNCTION_APP_NAME=$(echo $OUTPUT | jq -r '.functionAppName.value')
-          PRINCIPAL_ID=$(echo $OUTPUT | jq -r '.principalId.value')
+          FUNCTION_APP_NAME=$(jq -r '.functionAppName.value' <<<"$OUTPUT")
+          PRINCIPAL_ID=$(jq -r '.principalId.value' <<<"$OUTPUT")
🤖 Fix all issues with AI agents
In @.github/workflows/deploy-azure-functions.yml:
- Around line 8-12: Replace the overly-broad branch glob 'feat*/**' in the
workflow's branches list with the documented pattern 'feature/*' so only
branches named feature/<name> trigger feature deployments; update the branches
array entry in the deploy-azure-functions.yml workflow (where 'branches:'
contains 'master', 'develop', and 'feat*/**') to use 'feature/*' instead.
🧹 Nitpick comments (4)
.github/workflows/deploy-azure-functions.yml (4)

63-77: Dependabot deploy skip is correct; consider logging the reason into job summary for visibility.
Right now it prints to stdout only; adding a $GITHUB_STEP_SUMMARY line can make it easier to diagnose “why didn’t this deploy?” from the UI.


91-100: Feature env naming can collide across branches; add a short SHA (or PR number) to avoid accidental shared deployments.
With cut -c1-20, two branches with the same first 20 sanitized chars will deploy to the same Azure resources.

Proposed diff
           # Extract branch name and sanitize for Azure naming
           # Handles both feat/* and feature/* patterns
-          BRANCH_NAME=$(echo "${{ github.ref }}" | sed 's/refs\/heads\/feat[^\/]*\///' | sed 's/[^a-zA-Z0-9-]/-/g' | cut -c1-20)
+          BRANCH_NAME=$(echo "${{ github.ref }}" | sed 's/refs\/heads\/feat[^\/]*\///' | sed 's/[^a-zA-Z0-9-]/-/g' | cut -c1-12)
+          SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7)
-          ENV="feat-$BRANCH_NAME"
+          ENV="feat-$BRANCH_NAME-$SHORT_SHA"

134-140: Fail fast if required GitHub Variables are missing (AZURE_RESOURCE_GROUP, AZURE_LOCATION).
Otherwise the Azure CLI calls will fail later with less obvious errors.

Proposed diff
       - name: Ensure Resource Group exists
         run: |
+          if [ -z "${{ vars.AZURE_RESOURCE_GROUP }}" ] || [ -z "${{ vars.AZURE_LOCATION }}" ]; then
+            echo "Missing required variables: vars.AZURE_RESOURCE_GROUP and/or vars.AZURE_LOCATION"
+            exit 1
+          fi
           az group create \
             --name ${{ vars.AZURE_RESOURCE_GROUP }} \
             --location ${{ vars.AZURE_LOCATION }} \
             --tags Environment=${{ needs.determine-environment.outputs.environment }} ManagedBy=GitHub

197-209: Alert rules deployment gating (prod + ALERT_EMAIL) is good; consider a stable deployment name to reduce RG deployment clutter.
Since it’s production-only, a fixed --name "alert-rules" is typically sufficient unless you rely on historical deployment records.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 037138d and a67c4b3.

📒 Files selected for processing (2)
  • .azure/alert-rules.bicep
  • .github/workflows/deploy-azure-functions.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .azure/alert-rules.bicep
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build-and-deploy
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (3)
.github/workflows/deploy-azure-functions.yml (3)

12-24: Good: workflow now triggers on solution/props changes that affect build output.


141-150: vars.* migration here looks consistent.
If you see intermittent creation attempts, consider capturing and checking the exact exit code instead of relying on 2>/dev/null (but current behavior is likely fine).


253-262: Good: Function URL lookup now consistently uses vars.AZURE_RESOURCE_GROUP.

Comment on lines 8 to 12
branches:
- master
- develop
- "feature/**"
- "feat*/**"
paths:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n .github/workflows/deploy-azure-functions.yml | head -20

Repository: moconnell/yolo

Length of output: 567


🌐 Web query:

GitHub Actions workflow branch filtering glob pattern syntax feat*/**

💡 Result:

Short answer: feat*/** matches branch names that start with "feat" plus zero-or-more non-/ characters, followed by a slash, then anything (including additional slashes). In other words it matches branches like:

  • feat/one
  • feature/one/two
  • featsomething/anything/more

It does NOT match a branch with no slash after the "feat..." part (e.g. featbranch with no /). This follows GitHub Actions' filter rules: * does not match /, while ** matches any characters including /. [1][2]

Sources:

  • GitHub Actions workflow syntax (filter pattern cheat sheet). [1]
  • Triggering a workflow / branches examples. [2]

🏁 Script executed:

# Check for branch naming conventions in repo docs
fd -t f -e md -e txt | xargs grep -l "branch" | head -5

Repository: moconnell/yolo

Length of output: 124


🏁 Script executed:

cat -n docs/DEPLOYMENT.md | head -100

Repository: moconnell/yolo

Length of output: 3995


🏁 Script executed:

cat -n docs/DEPLOYMENT.md | sed -n '19,30p'

Repository: moconnell/yolo

Length of output: 918


Branch glob feat*/** is overly broad and contradicts documented deployment strategy.

The pattern feat*/** matches any branch starting with "feat" followed by a slash (e.g., feather/..., featsomething/...), but the deployment documentation (DEPLOYMENT.md line 28) explicitly specifies that only feature/* branches should trigger feature deployments. Narrow the pattern to match the documented intent.

Proposed diff
     branches:
       - master
       - develop
-      - "feat*/**"
+      - "feature/**"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
branches:
- master
- develop
- "feature/**"
- "feat*/**"
paths:
branches:
- master
- develop
- "feature/**"
paths:
🤖 Prompt for AI Agents
In @.github/workflows/deploy-azure-functions.yml around lines 8 - 12, Replace
the overly-broad branch glob 'feat*/**' in the workflow's branches list with the
documented pattern 'feature/*' so only branches named feature/<name> trigger
feature deployments; update the branches array entry in the
deploy-azure-functions.yml workflow (where 'branches:' contains 'master',
'develop', and 'feat*/**') to use 'feature/*' instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Azure bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants