Last active
February 17, 2023 13:12
-
-
Save drye/9cb1c96b35e20a15d42fa9f9e88099c8 to your computer and use it in GitHub Desktop.
Enrich Jira tickets with markdown links with descriptions
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 LANG=en_GB.UTF-8 node | |
// Required parameters: | |
// @raycast.schemaVersion 1 | |
// @raycast.title Jira enrich | |
// @raycast.mode silent | |
// Optional parameters: | |
// @raycast.icon 😅 | |
// Documentation: | |
// @raycast.description Enrich Jira ticket descriptions | |
// @raycast.author Primož Verdnik | |
// @raycast.authorURL https://github.com/drye | |
import got from 'got'; | |
import cp from 'child_process'; | |
import clipboard from 'clipboardy'; | |
const JIRA_URL = 'https://yourcompany.atlassian.net'; | |
const JIRA_USER = '[email protected]'; | |
const JIRA_TOKEN = 'yourtoken'; | |
async function getTicketSummary(id) { | |
const {body} = await got(`${JIRA_URL}/rest/agile/1.0/issue/${id}`, { | |
method: 'GET', | |
responseType: 'json', | |
username: JIRA_USER, | |
password: JIRA_TOKEN, | |
}); | |
return `${body.fields.summary}` | |
} | |
function getClipboard() { | |
return clipboard.readSync(); | |
return cp.spawnSync('pbpaste', { | |
encoding: 'utf8' | |
}).stdout; | |
} | |
async function setClipboard(data) { | |
return clipboard.writeSync(data); | |
await Clipboard.copy(data); | |
cp.spawnSync('pbcopy', { | |
// encoding: 'utf8', | |
input: data, | |
}); | |
} | |
async function replaceAsync(str, regex, asyncFn) { | |
const promises = []; | |
str.replace(regex, (match, ...args) => { | |
const promise = asyncFn(match, ...args); | |
promises.push(promise); | |
}); | |
const data = await Promise.all(promises); | |
return str.replace(regex, () => data.shift()); | |
} | |
async function processClipboard() { | |
const data = getClipboard(); | |
const re = /\[?([A-Z]{2,10}-[0-9]{1,6})([^`]*)?(`[^`]*`)?/ | |
const lines = [] | |
let count = 0; | |
for (let line of data.split('\n')) { | |
lines.push( | |
await replaceAsync( | |
line, | |
re, | |
async (match, ticket, oldSummary, comment) => { | |
try { | |
const summary = await getTicketSummary(ticket); | |
count ++; | |
return `[${ticket}](${JIRA_URL}/browse/${ticket}) - ${summary}${comment ? ' ' + comment : ''}`; | |
} catch (err) { | |
console.error(err); | |
return; | |
} | |
}, | |
) | |
) | |
} | |
return [lines.join('\n'), count] | |
} | |
const [results, count] = await processClipboard(); | |
await setClipboard(results); | |
if (count) { | |
console.log(results); | |
console.log(count + ' tickets enriched in clipboard. 💪🏻'); | |
} else { | |
console.log("No tickets enriched 🤔. Are you sure there's anything worth enriching in the clipboard?"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Installation
Put the script into your Raycast Scripts folder. To install dependencies:
Usage