mohamedradwan.com - Nothing can beat experience
Post
Cancel

Publishing Results Natively in Azure DevOps: Dashboards, Markdown Widgets, and REST Automation

Publishing Results Natively in Azure DevOps

Dashboards, Markdown Widgets, and REST Automation

In the previous posts, we covered data retrieval and status evaluation. Once a KPI value is calculated and its RAG status is determined, the final step is publication. Publication is not a cosmetic step. It completes the KPI lifecycle.

If KPI logic runs correctly but results are copied manually into dashboards, the solution is only partially automated. True KPI-as-code requires automated publication into Azure DevOps itself, without external tools and without manual intervention.

This post explains how dashboards and Markdown widgets can be managed programmatically using Azure DevOps REST APIs.

Why Native Publication Matters

Many organizations export KPI results to external reporting tools. While that approach can work, it introduces additional governance layers and operational complexity.

In a constrained environment where extensions and external integrations are limited, publishing directly into Azure DevOps dashboards provides several advantages:

  • No external dependencies
  • Immediate visibility for delivery teams
  • Consistent permission model
  • Full traceability through pipeline execution

The dashboard becomes the natural output surface of the KPI framework.

Understanding Azure DevOps Dashboards

Azure DevOps dashboards are scoped at the team level. Each dashboard contains a collection of widgets arranged on a grid.

Widgets include built-in types such as charts, query tiles, and Markdown widgets. The Markdown widget is particularly powerful because it allows structured, formatted KPI output without requiring a custom extension.

Dashboards and widgets are accessible via REST APIs. This makes them manageable through automation scripts.

REST API Pattern for Dashboard Management

To manage dashboards and widgets programmatically, the KPI framework uses the Dashboard REST API.

For example, to list dashboards:

1
GET https://dev.azure.com/{organization}/{project}/{team}/_apis/dashboard/dashboards

To list widgets within a dashboard:

1
GET https://dev.azure.com/{organization}/{project}/{team}/_apis/dashboard/dashboards/{dashboardId}/widgets

To create a Markdown widget, you must provide:

  • Widget name
  • Contribution ID (Markdown widget type)
  • Position and size
  • Markdown content

This is handled entirely through REST.

Publishing Markdown Content from Script

Your approved PowerShell script includes the function responsible for creating a Markdown widget:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function New-MarkdownWidget {
  param(
    [Parameter(Mandatory)] $OrgUrl,
    [Parameter(Mandatory)] $Project,
    [Parameter(Mandatory)] $Team,
    [Parameter(Mandatory)] $DashboardId,
    [Parameter(Mandatory)] $WidgetName,
    [Parameter(Mandatory)] $MarkdownContent,
    [Parameter(Mandatory)] [int] $Row,
    [Parameter(Mandatory)] [int] $Column,
    [Parameter(Mandatory)] [int] $RowSpan,
    [Parameter(Mandatory)] [int] $ColumnSpan,
    [Parameter(Mandatory)] $Headers
  )

  $ContributionId = "ms.vss-dashboards-web.Microsoft.VisualStudioOnline.Dashboards.MarkdownWidget"
  $teamEnc = [uri]::EscapeDataString($Team)
  $createUrl = "$OrgUrl/$Project/$teamEnc/_apis/dashboard/dashboards/$DashboardId/widgets?api-version=7.1-preview.2"

  $body = @{
    name            = $WidgetName
    contributionId  = $ContributionId
    position        = @{ row = $Row; column = $Column }
    size            = @{ rowSpan = $RowSpan; columnSpan = $ColumnSpan }
    settings        = $MarkdownContent
    settingsVersion = @{ major = 1; minor = 0; patch = 0 }
  }

  Invoke-Ado POST $createUrl $Headers $body
}

This function demonstrates how KPI output transitions from computed value to visible dashboard artifact.

The Markdown content itself is generated earlier in the pipeline and passed into this function as a fully structured string.

Idempotent Dashboard Behavior

A key design consideration is idempotency. If the pipeline runs multiple times, it must not create duplicate widgets or corrupt dashboard layout.

Your script addresses this by:

  • Checking if a widget already exists.
  • Deleting and recreating it if necessary.
  • Preserving its original position and size when recreating.

This ensures:

  • Stable dashboard layout.
  • Predictable automation behavior.
  • No manual cleanup required.

Automation must not degrade the dashboard experience over time.

Example: Commitment Ratio Widget Output

The Markdown output generated by the framework might look like:

1
2
3
4
5
6
7
## Commitment Ratio

| Metric | Sprint 10 | Sprint 11 | Sprint 12 |
|--------|-----------|-----------|-----------|
| Planned Stories | 20 | 18 | 22 |
| Completed Stories | 14 | 15 | 19 |
| Commitment Ratio | 🟠 70% | 🟢 83% | 🟢 86% |

This content is injected directly into the Markdown widget through REST. No manual editing is required.

Because the pipeline owns the content, the dashboard becomes an extension of the codebase.

Security and Identity Considerations

Publishing dashboards requires appropriate permissions. In a governed environment, this must be done using a scoped service account.

The service account must:

  • Have permission to edit dashboards in the target team.
  • Have access only to required projects.
  • Follow credential rotation and retention policies.

The publication step should not rely on elevated administrative privileges. It should align with least privilege principles established earlier.

Completing the KPI Lifecycle

At this stage, the KPI lifecycle becomes complete:

  1. Retrieve data correctly.
  2. Apply formula deterministically.
  3. Evaluate thresholds via governed logic.
  4. Publish results natively into dashboards.

No spreadsheets.
No external tools.
No manual copying.

The KPI exists entirely inside Azure DevOps as version-controlled logic executed by pipelines and rendered on dashboards.

What Comes Next

In the next post, we will examine the Commitment Ratio KPI as a full end-to-end case study, walking through the complete journey from raw data retrieval to final dashboard visualization.

Featured Blog Posts
Disclaimer
The postings on this site are my own.
Contents
Trending Tags