Created
July 23, 2026 18:46
-
-
Save eliranmal/e07a516e79e27d27553df58a9ab584ad to your computer and use it in GitHub Desktop.
generates a slack formatted message with your current open github PRs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env node | |
| const p = require('child_process'); | |
| const resolveTitle = pr => { | |
| const prTitle = pr.title.replace(/OCMUI-\d+: /, ''); | |
| // <url|text> is link notation in slack messages | |
| // (but it only works if you disable rich formatting!) | |
| // return `<${pr.url}|#${pr.number} - ${prTitle}>` | |
| return `${pr.url} #${pr.number} - ${prTitle}` | |
| } | |
| const resolvePriority = pr => { | |
| // keys: PR label, values: slack-emoji suffix | |
| const priorityTable = [ | |
| ['high priority', 'high'], | |
| ['medium priority', 'medium'], | |
| ['low priority', 'low'], | |
| ]; | |
| const priorityLabels = pr.labels | |
| .map(l => l.name) | |
| .filter(n => n.includes('priority')); | |
| const priorityKey = priorityTable.find(([l]) => ( | |
| priorityLabels.includes(l) | |
| ))?.[1] ?? 'medium'; | |
| return `priority: :priority-${priorityKey}:` | |
| } | |
| const resolveEffort = pr => { | |
| // keys: slack-emoji suffix, values: bracket ceiling | |
| const sizeBracketTable = [ | |
| ['xl', Infinity], | |
| ['l', 20], | |
| ['m', 12], | |
| ['s', 5], | |
| ['xs', 1], | |
| ]; | |
| const sizeKey = sizeBracketTable | |
| .reduce((acc, [k, v]) => ( | |
| pr.files.length <= v ? k : acc | |
| ), ''); | |
| return `effort: :size-${sizeKey}:`; | |
| } | |
| const resolveReviewers = pr => ( | |
| `reviewers: ${pr.reviewRequests.map(r => `@${r.login}`).join(', ')}` | |
| ) | |
| const buildPrItemContent = pr => ( | |
| [ | |
| resolveTitle(pr), | |
| resolvePriority(pr), | |
| resolveEffort(pr), | |
| resolveReviewers(pr), | |
| ].join(' | ') | |
| ) | |
| const buildPrItem = (pr, prListSize) => ( | |
| [ | |
| // generate a list item if needed | |
| prListSize > 1 ? '- ' : '', | |
| buildPrItemContent(pr), | |
| ].join('') | |
| ) | |
| const buildPrList = prListData => ( | |
| prListData | |
| .map((pr, i, arr) => ( | |
| buildPrItem(pr, arr.length) | |
| )) | |
| .join('\n') | |
| ) | |
| const getPrListRawData = () => ( | |
| p.execSync( | |
| `gh pr list \ | |
| --search '(author:@me OR assignee:@me) draft:false' \ | |
| --json 'number,title,reviewRequests,files,url,labels'` | |
| ) | |
| ) | |
| const parsePrListData = prListRawData => ( | |
| JSON.parse(prListRawData.toString()) | |
| ) | |
| const getPrListData = () => ( | |
| parsePrListData(getPrListRawData()) | |
| ) | |
| const buildMessage = () => { | |
| const prListData = getPrListData(); | |
| if (!prListData.length) { | |
| return 'no open PRs found'; | |
| } | |
| return [ | |
| ':git:', | |
| buildPrList(prListData), | |
| ':octocat:', | |
| ].join('\n\n') | |
| } | |
| const main = () => ( | |
| console.log(` | |
| ${buildMessage()} | |
| `) | |
| ) | |
| main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment