Skip to content

Instantly share code, notes, and snippets.

@ishaqibrahimbot
Last active November 29, 2022 05:41
Show Gist options
  • Save ishaqibrahimbot/5ae60ad478515ecb4a8e3cb598163bab to your computer and use it in GitHub Desktop.
Save ishaqibrahimbot/5ae60ad478515ecb4a8e3cb598163bab to your computer and use it in GitHub Desktop.
This is a git post-commit hook script that, if you include a JIRA ticket number in the commit message, will: - add the commit message as a comment to that ticket, - (if you add a time portion as well) log time in that ticket
#!/usr/bin/env node
/*
!! README !!
What this is:
A git post-commit hook script that, if you include a ticket number in the commit message, will:
- add the commit message as a comment to that ticket,
- (if you add a time portion as well) log time in that ticket
How to make this work?
1. Run `npm install -g node-fetch@2.2.0 date-fns` to install global dependencies in your machine
2. Make sure the require paths of node-fetch and date-fns in this script point to those globally installed packages
- If you're on a Mac, you probably don't have to change the current path already there on lines 38 and 39
- If you still want to check, run `npm list -g` to find that path
3. Create a file named `post-commit` inside the .git/hooks/ folder of your project
4. Run the following two commands to enable write permissions for the file and make it executable:
- sudo chmod -R 755 post-commit
- sudo chmod +x post-commit
5. Copy the contents of this file to that file and save
6. Get your jira api token from https://id.atlassian.com/manage-profile/security/api-tokens and add it on line 43
7. Add your email (the one you log into jira with) on line 44
8. Set the project key in line 46
That's it! You're all set to try it out now :)
How to use:
1. Just include a ticket number in the commit message to get the message added as a comment, e.g.:
- git commit -m "KOO0001-807 feat: do something"
- git commit -m "PROVSD-334 fix: something"
2. IF you want to log time in the ticket as well, along with including the ticket number in the message,
add a time portion at the end of the commit message after a #t and formatted as {i}d{j}h{k}m, e.g.:
- git commit -m "KOO0001-807 feat: do something #t 2h40m"
- git commit -m "PROVSD-334 fix: something #t 30m"
*/
const { exec } = require('child_process');
const fetch = require('/usr/local/lib/node_modules/node-fetch');
const { parseISO, format } = require('/usr/local/lib/node_modules/date-fns');
exec('git log --oneline -1 HEAD', async (error, stdout, stderr) => {
const domain = 'convertdigital';
const jiraToken = '****************'; // your jira access token here
const email = '*********'; // your email (the one you use to log into jira and view your project tickets)
const timeIdentifier = '#t';
const regExp = /KOO0001-[0-9]*/; // replace 'KOO0001' with the project key, e.g. PROV or PROVSD
const isServiceDesk = false // set this value to true if your project is a client-facing service desk to make sure comments are internal notes
let referencedTicket = stdout.match(regExp);
if (referencedTicket) {
referencedTicket = referencedTicket[0];
const hasTime = stdout.includes(timeIdentifier);
console.log('Pushing commit message to: ', referencedTicket);
const url = new URL(
`https://${domain}.atlassian.net/rest/api/3/issue/${referencedTicket}/comment`
);
const commentBody = {
body: {
type: 'doc',
version: 1,
content: [
{
type: 'paragraph',
content: [
{
text: hasTime ? stdout.split(timeIdentifier)?.[0] : stdout,
type: 'text',
},
],
},
],
},
...(isServiceDesk
? {
properties: [
{
key: 'sd.public.comment',
value: {
internal: true,
},
},
],
}
: {}),
};
try {
const response = await fetch(url.href, {
method: 'POST',
headers: {
Authorization: `Basic ${Buffer.from(`${email}:${jiraToken}`).toString(
'base64'
)}`,
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(commentBody)
});
if (response.ok) {
console.log(`Done! :)`);
}
} catch (err) {
console.log(`Something went wrong while posting comment to the ticket: ${err}`);
}
if (hasTime) {
const timePortion = stdout.split(timeIdentifier)?.[1];
console.log(`\nAdding${timePortion.replace('\n', '')} to ${referencedTicket}`);
let days = timePortion.match(/[0-9]*d/);
let hours = timePortion.match(/[0-9]*h/);
let minutes = timePortion.match(/[0-9]*m/);
days = days ? Number(days[0].replace('d', '')) : 0;
hours = hours ? Number(hours[0].replace('h', '')) : 0;
minutes = minutes ? Number(minutes[0].replace('m', '')) : 0;
const timeSpent = days * 24 * 60 * 60 + hours * 60 * 60 + minutes * 60;
const timeStarted = new Date(Date.now() - timeSpent * 1000).toISOString();
const addWorklogUrl = new URL(
`https://${domain}.atlassian.net/rest/api/3/issue/${referencedTicket}/worklog`
);
const body = {
timeSpentSeconds: timeSpent,
started: format(parseISO(timeStarted), "yyyy-MM-dd'T'HH:mm:ss.SSSXX")
};
try {
const response = await fetch(addWorklogUrl.href, {
method: 'POST',
headers: {
Authorization: `Basic ${Buffer.from(`${email}:${jiraToken}`).toString(
'base64'
)}`,
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
if (response.ok) {
console.log('Done! :)');
}
} catch (err) {
console.log('Something went wrong while trying to add time: ', err);
}
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment