Last active
November 29, 2022 05:41
-
-
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
This file contains 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 | |
/* | |
!! 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