ADO Stale Branch Cleanup Reminder
Weekly flow queries all Git branches across Azure DevOps repos, identifies branches with no commits in 30+ days that aren't linked to active PRs or work items, then sends a Teams alert and an Outlook summary to the repo admin with total stale branch count per repo.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
Weekly scheduled flow that queries all Git repositories in an Azure DevOps project, identifies branches with no commits in 30+ days that are not linked to active pull requests, and sends notifications to the repo admin via Outlook email and a Teams channel alert with a per-repository stale branch count summary.
Use Case
Stale branches accumulate in Azure DevOps repositories over time, cluttering the branch list and making it harder to find active work. This flow automates the detection of branches that haven't received commits in a configurable number of days and are not associated with active pull requests. The weekly digest gives repo admins visibility into cleanup opportunities without requiring manual repo-by-repo inspection.
Flow Architecture
Recurrence Weekly Monday
RecurrenceFires every Monday at 8:00 AM Eastern Standard Time.
Init varAdoOrganization
Initialize variableReads flowlibs_AdoOrganization env var (ADO org name).
Init varAdoProject
Initialize variableReads flowlibs_AdoProject env var (ADO project name).
Init varStaleBranchThresholdDays
Initialize variableReads flowlibs_StaleBranchThresholdDays env var, cast to integer via int(parameters(...)).
Init varTeamsGroupId
Initialize variableReads flowlibs_TeamsGroupId env var.
Init varTeamsChannelId
Initialize variableReads flowlibs_TeamsChannelId env var.
Init varDigestRecipientEmail
Initialize variableReads flowlibs_DigestRecipientEmail env var.
Init varDigestSubjectPrefix
Initialize variableReads flowlibs_DigestSubjectPrefix env var.
Init varAdminCcEmail
Initialize variableReads flowlibs_AdminCcEmail env var.
Initialize varStaleBranchReport
Initialize variableEmpty array used to accumulate per-repo stale branch data.
Compose Stale Cutoff Date
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_AdoOrganization | String | <configure> | Azure DevOps organization name (e.g. your-org). |
| flowlibs_AdoProject | String | <configure> | Azure DevOps project name to scan for repositories. |
| flowlibs_StaleBranchThresholdDays | String | 30 | Days without commits before a branch is considered stale. Cast to integer at runtime — any positive whole number works. |
| flowlibs_TeamsGroupId | String | <configure> | Microsoft 365 Group ID for Teams notifications. |
| flowlibs_TeamsChannelId | String | <configure> | Teams channel ID for posting the stale branch alert. |
| flowlibs_DigestRecipientEmail | String | you@yourcompany.com | Primary email recipient for the stale branch report. |
| flowlibs_DigestSubjectPrefix | String | <configure> | Prefix added to the email subject line, e.g. "[ADO Stale Branches]". |
| flowlibs_AdminCcEmail | String | alerts@yourcompany.com | CC recipient for admin visibility on the digest email. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Azure DevOps | shared_visualstudioteamservices | HttpRequest (List repositories, get branches (refs), and get active pull requests via the connector's generic HttpRequest operation.) |
| Office 365 Outlook | shared_office365 | SendEmailV2 (Sends the stale branch HTML report to the digest recipient.) |
| Microsoft Teams | shared_teams | PostMessageToConversation (Posts the stale branch alert to the configured Teams channel.) |
Note — All connections are referenced as solution connection references; the flow is portable between environments as long as a connection is mapped at import time.
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Adjusting the stale threshold
- Update flowlibs_StaleBranchThresholdDays in the solution's environment variables. The flow casts it to integer at runtime — any positive whole number works.
- Changing notification recipients
- Update flowlibs_DigestRecipientEmail for the primary recipient and flowlibs_AdminCcEmail for the CC. The Teams channel is controlled by flowlibs_TeamsGroupId and flowlibs_TeamsChannelId.
- Targeting a different ADO project
- Update flowlibs_AdoOrganization and flowlibs_AdoProject to point to any Azure DevOps organization and project. The flow dynamically enumerates all repos in the specified project.
- Adding branch owner DMs
- To send individual Teams DMs to branch owners, add an inner Apply to each inside the Foreach that iterates the stale branches array, resolves the branch creator via ADO REST API, and uses Teams PostMessageToConversation with location: "Chat" instead of "Channel".
- Excluding specific branches
- Add a Filter Array after Filter Stale Branches that removes branches matching exclusion patterns (e.g. main, develop, release/*) stored in an additional env var.
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Stale cutoff date
Computes the cutoff timestamp used to decide whether a branch's last commit is old enough to be flagged.
EXPR.02Integer cast from String env var
Power Platform env vars are typed as String, so the threshold is cast to an integer before being passed to subtractFromTime.
EXPR.03Active PR branch exclusion
Used inside Filter Stale Branches to drop any branch whose name appears in the list of active PR source branches.
EXPR.04HTML table triple-replace unwrap
Strips the {"html":"..."} JSON wrapping that Select emits so the rows can be inlined into the report's HTML table.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.