Sprint Rollover Automation
At sprint-end, calls Update A Milestone to close the current sprint (state=closed, due_on=today), creates the next sprint milestone, and emails PMs rollover stats for unfinished issues.
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
Every other Friday at 17:00 UTC this flow finds the next-due open GitHub milestone in the configured repo, treats it as the current sprint, closes it (state=closed, due_on=utcNow()), pulls every issue still open under that milestone, and emails a styled HTML rollover digest to the configured Project Manager distribution list. Designed for engineering teams that use GitHub milestones as sprint containers and want a zero-touch close every two weeks.
Use Case
Sprint hygiene rots when nobody owns the close ritual — milestones drift open, "carry-over" issues silently accumulate, and the PM finds out at standup that last sprint never officially ended. This flow takes the busywork out: every other Friday it closes the active milestone and hands the PM a clean, ranked list of what didn't ship, so the next-sprint conversation starts with data instead of guesswork.
The flow is ideal for teams that:
- Zero-touch biweekly milestone close — no PM clicks
- HTML digest of unfinished issues with title, assignee, and direct link
- Subject line surfaces the unfinished count for inbox triage
- All env-var driven — drop into any repo with three values
- Defensive coalesce on assignee?.login keeps unassigned issues in the table
- Flow Checker clean on ship (0/0)
Flow Architecture
Recurrence — biweekly Friday 17:00 UTC
RecurrenceEvery 2 weeks, Friday, 17:00 UTC; `timeZone` overridable per environment.
Init_varGitHubOwner
InitializeVariableString, bound to `flowlibs_GitHubOwner`.
Init_varGitHubRepository
InitializeVariableString, bound to `flowlibs_GitHubRepository`.
Init_varPmDigestEmail
InitializeVariableString, bound to `flowlibs_DigestRecipientEmail`.
Get_Open_Milestones
OpenApiConnection (GitHub)`GetMilestones` with `state=open`, `sort=due_on`, `direction=asc`, `per_page=5`.
Compose_Current_Sprint_Milestone_Number
Compose`@first(body('Get_Open_Milestones'))?['number']` — picks the next-due open milestone.
Close_Current_Sprint_Milestone
OpenApiConnection (GitHub)`UpdateMilestone` with `milestoneUpdate/state=closed` and `milestoneUpdate/due_on=@{utcNow()}`.
Get_Unfinished_Issues
OpenApiConnection (GitHub)`GetIssues` with `state=open`, `milestone=<currentNumber>`, `per_page=100`.
Select_Issue_Rows
SelectProjects each issue to an HTML row via `@concat(...)`; `string()` casts the issue number, `coalesce()` falls back to `(unassigned)`.
Compose_Rollover_Email_Body
ComposeWraps `join(body('Select_Issue_Rows'),'')` in a styled Segoe UI table with header, count, and footer.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_GitHubOwner | String | <configure> | GitHub user or org that owns the repo. |
| flowlibs_GitHubRepository | String | <configure> | Repository name within that owner. |
| flowlibs_DigestRecipientEmail | String | <configure> | PM distribution list that receives the rollover digest. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| GitHub | shared_github | GetMilestones (list open milestones, sorted by due date) UpdateMilestone (closes the current sprint milestone) GetIssues (pulls issues still open under the milestone) |
| Office 365 Outlook | shared_office365 | SendEmailV2 (delivers the styled HTML rollover digest) |
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.
- Deploying to another environment
- Import the FlowLibsSprintRolloverAutomation solution, set flowlibs_GitHubOwner, flowlibs_GitHubRepository, and flowlibs_DigestRecipientEmail, bind the GitHub and Outlook connection references, adjust the recurrence timeZone if the PM team prefers local-time delivery, then turn the flow on.
- Different cadence
- Change the Recurrence frequency from 2 weeks to 1 or 3 weeks to match the team's sprint length.
- Auto-create next milestone
- When the GitHub connector ships CreateMilestone, slot it in after Close_Current_Sprint_Milestone to skip the human follow-up step.
- Carry-over auto-reassignment
- Add a Foreach over Get_Unfinished_Issues calling GitHub UpdateIssue to set milestone to the next milestone number.
- Slack instead of email
- Replace SendEmailV2 with the Slack PostMessage action and swap flowlibs_DigestRecipientEmail for a Slack channel ID env var.
- Multi-repo digest
- Replace the two GitHub env vars with a JSON array env var of {owner, repo} and Foreach over it, accumulating rows into a single email.
- Velocity stats
- Add a closed-issues GitHub call to compute completion rate vs. carry-over and surface it in the email header.
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.01Pick current sprint milestone
Used in Compose_Current_Sprint_Milestone_Number; grabs the next-due open milestone from the sorted GetMilestones response.
EXPR.02Close-time stamp
Bound to `milestoneUpdate/due_on` on the UpdateMilestone call so the milestone is closed with today as its due date.
EXPR.03Project issue to HTML row
Used inside Select_Issue_Rows to render each issue as a styled <tr> row; `string()` casts the issue number and `coalesce()` falls back to (unassigned).
EXPR.04Join rows into table body
Concatenates the array of HTML row strings into the table body inside Compose_Rollover_Email_Body.
EXPR.05Unfinished count
Embedded in the subject line so PMs can triage from the inbox.
EXPR.06Header timestamp
Renders the close timestamp in the email header.
Customize & download
Generate a ready-to-import copy of this solution with your environment-variable values baked in — available on Base, Pro, or Team.
Upgrade to customize
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.