Docs Change Watcher
Every 15 minutes lists files under /docs in a repo, compares SHAs against a cached snapshot; if any doc changed, posts the file name and author in a Teams 'docs-changes' channel.
Overview
Every 15 minutes lists every file under a configurable path inside a GitHub repository (default /docs), compares each file's SHA against a cached snapshot held in a SharePoint list, and posts a notification to a Microsoft Teams channel for every file that is new or has a changed SHA. Same iteration upserts the snapshot. Built on HTTP — not the GitHub connector — because the connector does not expose a list-files-from-a-path operation.
**State:** Stopped
Use Case
Documentation drifts silently — engineers ship code, edit READMEs, the docs team finds out a sprint later. This flow gives docs near-real-time feed of every change inside a watched path so reviews happen while the change is still fresh.
**Key Benefits:** 15-min detection latency; SHA comparison = zero false positives; snapshot in SharePoint is auditable; one env var re-targets the watcher; HTTP sidesteps the connector's missing operation.
Flow Architecture
Trigger: **Recurrence — every 15 minutes**.
1. Init 8 vars (owner, repo, token, path, SP site, list name, Teams group + channel)
2. List_Repo_Path (HTTP GET /repos/.../contents/{path} with bearer)
3. Filter_Files_Only (Query: type == 'file')
4. Get_Existing_Snapshot (SP GetItems $top=5000 against snapshot list)
5. **Apply_to_each_File**:
- Find_In_Snapshot (Query: Title == path)
- If_SHA_Changed: Teams post + nested If_Row_Exists upserts SP via PatchItem or PostItemEnvironment Variables
| Variable | Schema Name | Type | Default | Purpose |
|---|---|---|---|---|
| GitHub Owner | flowlibs_GitHubOwner | String | (none) | GitHub org or user that owns the watched repo |
| GitHub Repository | flowlibs_GitHubRepository | String | (none) | Repository name within that owner |
| GitHub API Token | flowlibs_GitHubApiToken | Secret | (none) | PAT with repo scope (bearer) |
| Docs Watcher Path | flowlibs_DocsWatcherPath | String | docs | Folder inside the repo to watch |
| SharePoint Site URL | flowlibs_SharePointSiteURL | String | (none) | SharePoint site that hosts the snapshot list |
| Docs Snapshot List Name | flowlibs_DocsSnapshotListName | String | FlowLibs - Docs SHA Snapshot | SharePoint list used as SHA cache |
| Teams Group ID | flowlibs_TeamsGroupId | String | (none) | Team GUID that owns the docs-changes channel |
| Teams Docs Channel ID | flowlibs_TeamsDocsChannelId | String | (none) | Channel ID for change notifications |
Connectors & Connections
| Connector | API Name | Connection Format | Usage |
|---|---|---|---|
| HTTP (built-in) | shared_http | Bearer token via env var | GET /repos/{owner}/{repo}/contents/{path} |
| SharePoint | shared_sharepointonline | FlowLibs SP service account | GetItems + PatchItem + PostItem — read/upsert SHA snapshot |
| Microsoft Teams | shared_teams | FlowLibs Teams account | PostMessageToConversation — change alerts |
| GitHub (connection ref only) | shared_github | FlowLibs GitHub PAT | Connection ref shipped for future ops; HTTP does the listing today |
Customization Guide
1. Create the SHA snapshot SP list with Title (file path) + SHA (single line text) columns.
2. Set 8 env vars; bind connection refs.
3. Open flow → re-select list on Create/Update Snapshot Row → bind Title → @items('Apply_to_each_File')?['path'] and SHA → @items('Apply_to_each_File')?['sha'].
4. Turn on.
**Common Modifications:** watch multiple paths via JSON array env var; add deletion alerts (query snapshot for missing files); tighter cadence (5 min); Slack instead of Teams; adaptive cards; per-author routing via GitHub commit author.
Key Expressions
- @concat('https://api.github.com/repos/', variables('varOwner'), '/', variables('varRepo'), '/contents/', variables('varPath')) — list-contents URL
- @equals(item()?['type'], 'file') — files only
- @if(equals(length(body('Find_In_Snapshot')),0),'_NEW_',first(body('Find_In_Snapshot'))?['SHA']) — stored SHA fallback
- @not(equals(outputs('Compose_Stored_SHA'), items('Apply_to_each_File')?['sha'])) — SHA changed test