GitHub Label Change to Approval Flow
When a GitHub issue is labeled 'needs-approval', kick off a Power Automate approval and update the issue based on the outcome.
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
This flow demonstrates how to bridge GitHub's issue tracker with Microsoft Power Automate's native Approvals platform. Every hour the flow polls GitHub for any open issues that have been labeled with the configured trigger label (default needs-approval), launches a blocking Power Automate approval for each one, and then updates the GitHub issue based on the outcome — adding either an approved or rejected label, optionally closing the issue, posting a confirmation comment via the GitHub REST API, and emailing the requester with a styled HTML summary of the decision.
Use Case
A common pattern in engineering teams is to gate work on lightweight human review before allowing a contributor to start coding (or before letting a feature land in the changelog). GitHub Projects and Issues are the natural place to track that work, but GitHub itself does not ship a built-in approval workflow. This flow uses the Power Automate Approvals connector — which already handles email notifications, a mobile-friendly approver UI, audit history, and re-routing — and ties its outcome back to the originating GitHub issue. Developers see a single label change as their signal; reviewers receive a real Approvals card; the flow closes the loop on both sides automatically.
Flow Architecture
Recurrence_Hourly_Label_Sweep
Recurrence (1 hour)Polls GitHub once per hour. The shared_github connector ships only 4 triggers (none for label changes), so a recurrence-driven sweep is the standard pattern for label-event detection.
Init_varGitHubOwner
Initialize VariableBinds the `flowlibs_GitHubOwner` env var to a string variable.
Init_varGitHubRepository
Initialize VariableBinds `flowlibs_GitHubRepository`.
Init_varApproverEmail
Initialize VariableBinds `flowlibs_ApprovalAdminEmail`.
Init_varTriggerLabel
Initialize VariableBinds `flowlibs_LabelChangeTriggerLabel` (default `needs-approval`).
Init_varApprovedLabel
Initialize VariableBinds `flowlibs_LabelChangeApprovedLabel` (default `approved`).
Init_varRejectedLabel
Initialize VariableBinds `flowlibs_LabelChangeRejectedLabel` (default `rejected`).
Init_varNotifyEmail
Initialize VariableBinds `flowlibs_LabelChangeNotifyEmail` (outcome email recipient).
Init_varGitHubPAT
Initialize VariableBinds `flowlibs_LabelChangeGitHubPAT` — the GitHub PAT used by the HTTP comment action. Replace the placeholder before turning the flow on.
Get_Open_Issues_With_Approval_Label
GitHub GetIssues (OpenApiConnection)Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_GitHubOwner | String | your-org | GitHub repository owner (org or user). |
| flowlibs_GitHubRepository | String | flowlibs-demo | GitHub repository name. |
| flowlibs_ApprovalAdminEmail | String | you@yourcompany.com | Email of the approval reviewer. |
| flowlibs_LabelChangeTriggerLabel | String | needs-approval | Label that gates issues for approval. |
| flowlibs_LabelChangeApprovedLabel | String | approved | Label applied on approval. |
| flowlibs_LabelChangeRejectedLabel | String | rejected | Label applied on rejection. |
| flowlibs_LabelChangeNotifyEmail | String | you@yourcompany.com | Recipient of the outcome HTML email. |
| flowlibs_LabelChangeGitHubPAT | String | <configure> | GitHub PAT for the HTTP comment action. Set to a fine-grained PAT scoped to Issues: write on the target repo. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| GitHub | shared_github | GetIssues (list open issues with trigger label) UpdateIssueNum (apply approved/rejected label, set state) |
| Approvals | shared_approvals | StartAndWaitForAnApproval (Approve/Reject blocking approval) |
| Office 365 Outlook | shared_office365 | SendEmailV2 (styled HTML outcome notification) |
| HTTP (built-in) | n/a | HTTP POST (POST /repos/{owner}/{repo}/issues/{number}/comments) |
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.
- Change the trigger label
- Update the flowlibs_LabelChangeTriggerLabel environment variable. Any open issue carrying that label will be picked up on the next sweep — no JSON edit required.
- Change the recurrence frequency
- Edit the Recurrence_Hourly_Label_Sweep trigger. Frequency Hour/Minute/Day and any positive interval are supported. Power Automate's free tier minimum is 5 minutes for standard polling.
- Route approvals to a different reviewer
- Update flowlibs_ApprovalAdminEmail. The Approvals card will render with that account as the assigned approver and that account as the requestor (the demo points both at the same user).
- Change approve/reject labels
- Update flowlibs_LabelChangeApprovedLabel / flowlibs_LabelChangeRejectedLabel. The labels must already exist in the target GitHub repository.
- Change the outcome notification recipient
- Update flowlibs_LabelChangeNotifyEmail. Multiple recipients can be supplied as a semicolon-separated string.
- Wire to a real GitHub webhook (optional)
- For true event-driven behavior, replace the Recurrence trigger with a manual Request trigger and configure a GitHub repo webhook on issues events that POSTs to the trigger URL. Filter on action == 'labeled' and label.name == @{parameters('flowlibs_LabelChangeTriggerLabel')} inside the flow.
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.01Issue list filter (GitHub GetIssues)
Single label string; comma-separate for multi-label AND filtering.
EXPR.02Outcome branching (Switch expression)
Approvals connector returns `Approve` or `Reject` strings.
EXPR.03Label replacement on approval
UpdateIssueNum replaces the entire label set on a PATCH; createArray() wraps a single label as a string-array.
EXPR.04Label replacement on rejection
Same pattern as approval, applied with state=closed and state_reason=not_planned.
EXPR.05Comment URL build
Builds the GitHub REST API comments endpoint URL for the current issue.
EXPR.06HTTP auth header
GitHub's REST API accepts both `token <PAT>` and `Bearer <PAT>`; `token` is preferred for classic PATs.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.