Skip to content

Commit

Permalink
Resolve issue 2155 to add a comment reminding new issue assignees to …
Browse files Browse the repository at this point in the history
…add their ETA and availability (#2962)
  • Loading branch information
usaboo authored Jun 24, 2022
1 parent 3ab2b0f commit b485020
Show file tree
Hide file tree
Showing 4 changed files with 250 additions and 5 deletions.
40 changes: 35 additions & 5 deletions .github/workflows/issue-trigger.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Issue Trigger
on:
issues:
types: [opened]
types: [opened, assigned]

jobs:
Add-Missing-Labels-To-Issues:
Expand All @@ -25,7 +25,37 @@ jobs:
uses: actions/github-script@v4
id: post-comment
with:
script: |
const results = ${{ steps.check-labels.outputs.result }}
const script = require('./github-actions/trigger-issue/add-missing-labels-to-issues/post-labels-comment.js')
script({g: github, c:context}, results)
script: |
const results = ${{ steps.check-labels.outputs.result }}
const script = require('./github-actions/trigger-issue/add-missing-labels-to-issues/post-labels-comment.js')
script({g: github, c:context}, results)
#Asking for preliminary update when issue is assigned
Ask-For-Preliminary-update:
runs-on: ubuntu-latest
#Triggers when the issue is newly assigned
if: ${{ github.event_name == 'issues' && github.event.action == 'assigned'}}
steps:
- uses: actions/checkout@v2

# Check if the issue has the required roles
- name: Check Labels Prelim
uses: actions/github-script@v4
id: check-labels-prelim
with:
script: |
const script = require('./github-actions/trigger-issue/add-preliminary-comment/check-label-preliminary-update.js')
const checklabels = script({g: github, c: context})
return checklabels
# Post the comment based on the result of the previous step
- name: Post assigning issue comment
id: assigned-comment
uses: actions/github-script@v4
with:
script: |
const results = ${{ steps.check-labels-prelim.outputs.result }}
const script = require('./github-actions/trigger-issue/add-preliminary-comment/preliminary-update-comment.js')
script({g: github, c:context},results)
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Global variables
var github
var context

/**
* @description - entry point of the whole javascript file, finds out whether we need to post the comment or not and returns in the boolean variable shouldpost.
* @param {Object} github - github object
* @param {Object} context - context object
* @returns {object} - An object deciding whether we need to post the comment in the next action or not
*/

function main({g, c}){
github = g
context = c
const issueNum = context.payload.issue.number
//Find out what the existing labels in the issue are:-
var existingLabels = obtainLabels()

//With the existing labels we see if we are to post the comment or not(based on whether there exists a relevant role tag or not) and return it as a boolean
var shouldPost = postComment(existingLabels)

return({shouldPost,issueNum})
}

/**
* @description - this function gets the current label names and returns it in the array nameOfCurrentLabels
* @returns {array} - return an array of just label names
*/

function obtainLabels(){
var currentLabels = context.payload.issue.labels
//from the labels we currently have we extract the name property of each of them and return it in an array
var namesOfCurrentLabels = currentLabels.map(label => label.name)
return namesOfCurrentLabels
}


/**
* @description - this function returns a boolean depending on whether the existing labels contain a relevant role tag
* @param {array} existingLabels - takes in as an argument the array of role tags returned by obtainLabels function
* @returns - A boolean which tells whether we are supposed to post a preliminary update based on the given issue checks
*/

function postComment(existingLabels){
//issue states that we are to post the comment if--> there is a role: back end/devOps tag...(continued on next comment)
if(existingLabels.includes("role: back end/devOps")){
return true
}

// or if there is a role: front end tag
else if(existingLabels.includes("role: front end")){
return true
}

//or if there is a role: design tag
else if(existingLabels.includes("role: design")){
return true
}

//or if there is a role: user research
else if(existingLabels.includes("role: user research")){
return true
}

//otherwise we return a false
return false
}

module.exports = main
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
var fs = require("fs")

// Global variables
var github
var context

/**
* @description - This function is the entry point into the javascript file, it formats the md file based on the result of the previous step and then posts it to the issue
* @param {Object} g - github object
* @param {Object} c - context object
* @param {Boolean} actionResult - the previous gh-action's result
* @param {Number} issueNum - the number of the issue where the post will be made
*/

async function main({ g, c }, { shouldPost, issueNum }){
github = g
context = c
// If the previous action returns a false, stop here
if(shouldPost === false){
console.log('No need to post comment.')
return
}
//Else we make the comment with the issuecreator's github handle instead of the placeholder.
else{
const instructions = await makeComment()
if(instructions !== null){
// the actual creation of the comment in github
await postComment(issueNum, instructions)
}
}
}

/**
* Function that returns the timeline of an issue.
* @param {Number} issueNum the issue's number
* @returns an Array of Objects containing the issue's timeline of events
*/

async function getTimeline(issueNum){
let history = []
let page = 1
while (true) {
try {
const results = await github.issues.listEventsForTimeline({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNum,
per_page: 100,
page: page,
});
if (results.data.length){
history = history.concat(results.data);
} else {
break
}
} catch (err){
console.log(error);
continue
}
finally{
page++
}
}
return history
}

/**
* @description - This function makes the comment with the issue assignee's github handle using the raw preliminary.md file
* @returns {string} - Comment to be posted with the issue assignee's name in it!!!
*/

async function makeComment(){
// Setting all the variables which formatComment is to be called with
var issueAssignee = context.payload.issue.assignee.login
const eventdescriptions = await getTimeline(context.payload.issue.number)
console.log(eventdescriptions.length)
//adding the code to find out the latest person assigned the issue
for(var i = eventdescriptions.length - 1 ; i>=0; i-=1){
if(eventdescriptions[i].event == 'assigned'){
issueAssignee = eventdescriptions[i].assignee.login
break
}
}


const commentObject = {
replacementString: issueAssignee,
placeholderString: '${issueAssignee}',
filePathToFormat: './github-actions/trigger-issue/add-preliminary-comment/preliminary-update.md',
textToFormat: null
}

// creating the comment with issue assignee's name and returning it!
const commentWithIssueAssignee = formatComment(commentObject)
return commentWithIssueAssignee
}


/**
* @description - This function is called by makeComment() and it formats the comment to be posted based on an object input.
* @param {String} replacementString - the string to replace the placeholder in the md file
* @param {String} placeholderString - the placeholder to be replaced in the md file
* @param {String} filePathToFormat - the path of the md file to be formatted
* @param {String} textToFormat - the text to be formatted. If null, use the md file provided in the path. If provided, format that text
* @returns {String} - returns a formatted comment to be posted on github
*/

function formatComment({ replacementString, placeholderString, filePathToFormat, textToFormat }){
const text = textToFormat === null ? fs.readFileSync(filePathToFormat).toString('utf-8') : textToFormat
const commentToPost = text.replace(placeholderString, replacementString)
return commentToPost
}


/**
* @description - this function is called by main() with the result of makeComment() as the comment argument and it does the actual posting of the comment.
* @param {Number} issueNum - the issue number where the comment should be posted
* @param {String} comment - the comment to be posted
*/

async function postComment(issueNum, comment){
try{
await github.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNum,
body: comment,
})
}
catch(err){
throw new Error(err);
}
}

module.exports = main
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- Template for a user to add their availability, and the estimated time for completion of the issue they have taken up-->

Hi @${issueAssignee}, thank you for taking up this issue! Hfla appreciates you :)

Do let fellow developers know about your:-
i. **Availability:** (When are you available to work on the issue/answer questions other programmers might have about your issue?)
ii. **ETA:** (When do you expect this issue to be completed?)

You're awesome!

P.S. - You may not take up another issue until this issue gets merged (or closed). Thanks again :)

0 comments on commit b485020

Please sign in to comment.