Skip to content

Instantly share code, notes, and snippets.

@drye
Last active February 17, 2023 13:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drye/9cb1c96b35e20a15d42fa9f9e88099c8 to your computer and use it in GitHub Desktop.
Save drye/9cb1c96b35e20a15d42fa9f9e88099c8 to your computer and use it in GitHub Desktop.
Enrich Jira tickets with markdown links with descriptions
#!/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 = 'youremail@yourcompany.com';
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?");
}
@drye
Copy link
Author

drye commented Feb 17, 2023

Installation

Put the script into your Raycast Scripts folder. To install dependencies:

npm install got clipboardy --save

Usage

  1. Copy text which includes Jira tickets into the clipboard.
  2. Run the script.
  3. The text in the clipboard will now contain original text, with Jira tickets replaced with markdown links and descriptions. Note that it will replace the entire line once it finds a ticket name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment