diff --git a/.github/workflows/schedule-fri-0700.yml b/.github/workflows/schedule-fri-0700.yml index dab21e0e03..bdebdb2386 100644 --- a/.github/workflows/schedule-fri-0700.yml +++ b/.github/workflows/schedule-fri-0700.yml @@ -12,11 +12,8 @@ jobs: steps: - uses: actions/checkout@v4 - uses: actions/github-script@v7 - env: - HACKFORLA_ADMIN_TOKEN: ${{ secrets.HACKFORLA_ADMIN_TOKEN }} with: - github-token: ${{ secrets.HACKFORLA_GRAPHQL_TOKEN }} + github-token: ${{ secrets.HACKFORLA_GRAPHQL_TOKEN }} script: | - const HACKFORLA_ADMIN_TOKEN = process.env.HACKFORLA_ADMIN_TOKEN; const script = require('./github-actions/trigger-schedule/add-update-label-weekly/add-label.js'); - script({ g: github, c: context }, HACKFORLA_ADMIN_TOKEN); + script({ g: github, c: context }); diff --git a/github-actions/trigger-schedule/add-update-label-weekly/add-label.js b/github-actions/trigger-schedule/add-update-label-weekly/add-label.js index dd065ce0ba..e7816e3f59 100644 --- a/github-actions/trigger-schedule/add-update-label-weekly/add-label.js +++ b/github-actions/trigger-schedule/add-update-label-weekly/add-label.js @@ -1,9 +1,9 @@ /// Import modules const fs = require("fs"); -const https = require("https"); const queryIssueInfo = require("../../utils/query-issue-info"); const findLinkedIssue = require('../../utils/find-linked-issue'); const getTimeline = require('../../utils/get-timeline'); +const minimizeIssueComment = require('../../utils/hide-issue-comment'); // Global variables var github; @@ -14,8 +14,8 @@ const toUpdateLabel = 'To Update !'; const inactiveLabel = '2 weeks inactive'; const updatedByDays = 3; // If last update update 3 days, the issue is considered updated -const commentByDays = 7; // If last update between 7 and 14 days ago, the issue is outdated, assignee needs 'To Update !' it -const inactiveUpdatedByDays = 14; // If last update greater than 14 days ago, the issue is considered '2 weeks inactive' +const commentByDays = 7; // If last update between 7 and 14 days ago, issue outdated, needs 'To Update !' +const inactiveUpdatedByDays = 14; // If last update greater than 14 days ago, issue considered '2 weeks inactive' const threeDayCutoffTime = new Date(); threeDayCutoffTime.setDate(threeDayCutoffTime.getDate() - updatedByDays); @@ -24,27 +24,24 @@ sevenDayCutoffTime.setDate(sevenDayCutoffTime.getDate() - commentByDays); const fourteenDayCutoffTime = new Date(); fourteenDayCutoffTime.setDate(fourteenDayCutoffTime.getDate() - inactiveUpdatedByDays); -var projectBoardToken; - /** - * The main function, which retrieves issues from a specific column in a specific project, before examining the timeline of each issue - * for outdatedness. An update to an issue is either 1.) a comment by the assignee, or 2.) assigning an assignee to the issue. If the - * last update was not between 7 to 14 days ago, apply the appropriate label and request an update. However, if the assignee has submitted - * a PR that will fix the issue regardless of when, all update-related labels should be removed. - + * The main function, which retrieves issues from a specific column in a specific project, before examining + * the timeline of each issue for outdatedness. An update to an issue is either 1.) a comment by the assignee, + * or 2.) assigning an assignee to the issue. If the last update was not between 7 to 14 days ago, apply the + * appropriate label and request an update. However, if the assignee has submitted a PR that will fix the issue + * regardless of when, all update-related labels should be removed. * @param {Object} g - GitHub object from actions/github-script * @param {Object} c - context object from actions/github-script * @param {String} projectBoardToken - the Personal Access Token for the action */ -async function main({ g, c }, pbt) { +async function main({ g, c }) { github = g; context = c; - projectBoardToken = pbt; - + // Retrieve all issue numbers from a repo - const issueNums = await getIssueNumsFromRepo(); // Revised for Projects Beta migration + const issueNums = await getIssueNumsFromRepo(); for await (let issueNum of issueNums) { const timeline = await getTimeline(issueNum, github, context); @@ -91,8 +88,9 @@ async function getIssueNumsFromRepo() { let issueNums = []; let pageNum = 1; let result = []; - + while (true) { + // https://docs.github.com/en/rest/issues/issues?apiVersion=2022-11-28#list-repository-issues const issueData = await github.request('GET /repos/{owner}/{repo}/issues', { owner: context.repo.owner, repo: context.repo.repo, @@ -253,7 +251,7 @@ async function removeLabels(issueNum, ...labels) { */ async function addLabels(issueNum, ...labels) { try { - // https://octokit.github.io/rest.js/v18#issues-add-labels + // https://octokit.github.io/rest.js/v20#issues-add-labels await github.rest.issues.addLabels({ owner: context.repo.owner, repo: context.repo.repo, @@ -273,6 +271,7 @@ async function postComment(issueNum, assignees, labelString) { try { const assigneeString = createAssigneeString(assignees); const instructions = formatComment(assigneeString, labelString); + // https://octokit.github.io/rest.js/v20/#issues-create-comment await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, @@ -353,66 +352,16 @@ function formatComment(assignees, labelString) { function isCommentByBot(data) { let botLogin = "github-actions[bot]"; - return data.actor.login === botLogin; + let hflaBotLogin = "HackforLABot"; + return data.actor.login === botLogin || data.actor.login === hflaBotLogin; } // asynchronously minimize all the comments that are outdated (> 1 week old) async function minimizeComments(comment_node_ids) { for (const node_id of comment_node_ids) { await new Promise((resolve) => { setTimeout(resolve, 1000); }); // wait for 1000ms before doing the GraphQL mutation - await minimizeComment(node_id); + await minimizeIssueComment(github, node_id); } } -async function minimizeComment(node_id) { - const mutation = JSON.stringify({ - query: `mutation HideOutdatedComment($nodeid: ID!){ - minimizeComment(input:{ - classifier:OUTDATED, - subjectId: $nodeid - }) { - clientMutationId - minimizedComment { - isMinimized - minimizedReason - } - } - }`, - variables: { - nodeid: node_id - } - }); - - const options = { - hostname: 'api.github.com', - path: '/graphql', - method: 'post', - headers: { - 'Content-Type': 'application/json', - 'Authorization': 'bearer ' + projectBoardToken, - 'user-agent': 'Add-Update-Label-to-Issues-Weekly' - } - }; - - // copied from https://developer.ibm.com/articles/awb-consuming-graphql-apis-from-plain-javascript/ - const req = https.request(options, (res) => { - let data = ''; - // console.log(`statusCode: ${res}`); - - res.on('data', (d) => { - data += d; - }); - res.on('end', () => { - console.log(`GraphQL output: ${data}`); - }); - }); - - req.on('error', (error) => { - console.error("An error minimizing comments occurred"); - }); - - req.write(mutation); - req.end(); -} - -module.exports = main; +module.exports = main; \ No newline at end of file diff --git a/github-actions/utils/hide-issue-comment.js b/github-actions/utils/hide-issue-comment.js index 86fc7c1094..5eec7be841 100644 --- a/github-actions/utils/hide-issue-comment.js +++ b/github-actions/utils/hide-issue-comment.js @@ -1,26 +1,29 @@ /** - * Hide a comment as OUTDATED on github - * @param {Number} nodeID - the comment to be marked as 'OUTDATED' + * Minimize issue comment as OUTDATED given the comment's node Id + * @param {String} nodeId - node Id of comment to be marked as 'OUTDATED' + * */ +async function minimizeIssueComment(github, nodeId) { -async function hideComment(github, nodeID) { - const reason = "OUTDATED" - try { - const resp = await github.graphql(` - mutation { - minimizeComment(input: {classifier: ${reason}, subjectId: "${nodeID}"}) { - minimizedComment { - isMinimized - } - } + const mutation = `mutation($nodeId: ID!) { + minimizeComment(input: {classifier: OUTDATED, subjectId: $nodeId}) { + clientMutationId + minimizedComment { + isMinimized + minimizedReason } - `) - if (resp.errors) { - throw new Error(`${resp.errors[0].message}`) } - } catch (err) { - throw new Error(err) + }`; + + const variables = { + nodeId: nodeId, + }; + + try { + await github.graphql(mutation, variables); + } catch (error) { + throw new Error(`Error in minimizeIssueComment() function: ${error}`); } } -module.exports = hideComment +module.exports = minimizeIssueComment; diff --git a/github-actions/utils/mutate-issue-status.js b/github-actions/utils/mutate-issue-status.js index a300484c61..9abbd58cd5 100644 --- a/github-actions/utils/mutate-issue-status.js +++ b/github-actions/utils/mutate-issue-status.js @@ -1,8 +1,8 @@ /** * Changes the 'Status' of an issue (with the corresponding itemId) to a newStatusValue - * @param {String} itemId - GraphQL item Id for the issue + * @param {String} itemId - GraphQL item Id for the issue * @param {String} newStatusValue - GraphQL Id value of the 'Status' field that the issue is moving to - * + * */ async function mutateIssueStatus(github, context, itemId, newStatusValue) { @@ -34,9 +34,9 @@ async function mutateIssueStatus(github, context, itemId, newStatusValue) { try { await github.graphql(mutation, variables); - } catch(error) { - throw new Error("Error in mutateItemStatus() function: " + error); - } + } catch (error) { + throw new Error(`Error in mutateItemStatus() function: ${error}`); + } } -module.exports = mutateIssueStatus; +module.exports = mutateIssueStatus; \ No newline at end of file