From 05ffea73179b6d9ea591cc3580916c5574139d1f Mon Sep 17 00:00:00 2001 From: devisscher Date: Sat, 25 Jul 2020 14:15:48 -0400 Subject: [PATCH 1/3] feat(#42): add marker for stale PRs --- .github/workflows/pr-reporter-slack.yml | 1 + __tests__/__snapshots__/messages.test.ts.snap | 40 +++++++++++++++++++ __tests__/messages.test.ts | 34 ++++++++++++---- action.yml | 3 ++ package-lock.json | 11 +++++ package.json | 2 + src/message.ts | 23 ++++++++--- 7 files changed, 102 insertions(+), 12 deletions(-) diff --git a/.github/workflows/pr-reporter-slack.yml b/.github/workflows/pr-reporter-slack.yml index ae4390d..7a2372f 100644 --- a/.github/workflows/pr-reporter-slack.yml +++ b/.github/workflows/pr-reporter-slack.yml @@ -15,3 +15,4 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} slack-webhook: ${{ secrets.SLACK_WEBHOOK }} notify-empty: 'false' + stale-pr: 15 diff --git a/__tests__/__snapshots__/messages.test.ts.snap b/__tests__/__snapshots__/messages.test.ts.snap index 07286d2..d83f308 100644 --- a/__tests__/__snapshots__/messages.test.ts.snap +++ b/__tests__/__snapshots__/messages.test.ts.snap @@ -44,3 +44,43 @@ Object { "username": "PR Reporter", } `; + +exports[`stale PR 1`] = ` +Object { + "blocks": Array [ + Object { + "text": Object { + "text": " +*SeanReece/pr-reporter-slack* has 1 PRs ready for review", + "type": "mrkdwn", + }, + "type": "section", + }, + Object { + "type": "divider", + }, + Object { + "text": Object { + "text": " +šŸ‘‰ | *1 approvals* | šŸšØ 6 days ago šŸšØ", + "type": "mrkdwn", + }, + "type": "section", + }, + Object { + "elements": Array [ + Object { + "text": "You have *2* open PRs and *1* ready for review", + "type": "mrkdwn", + }, + ], + "type": "context", + }, + Object { + "type": "divider", + }, + ], + "icon_emoji": ":rolled_up_newspaper:", + "username": "PR Reporter", +} +`; diff --git a/__tests__/messages.test.ts b/__tests__/messages.test.ts index a6310c7..bcd5e78 100644 --- a/__tests__/messages.test.ts +++ b/__tests__/messages.test.ts @@ -1,12 +1,14 @@ -import * as core from '@actions/core' import { format } from 'timeago.js' import { formatSinglePR, formatSlackMessage } from '../src/message' import { PullRequest } from '../src/github' +import { set as setMockDate } from 'mockdate' jest.mock('timeago.js') beforeEach(() => { - (format as jest.Mock).mockImplementationOnce(() => '6 days ago') + jest.clearAllMocks() + setMockDate('2020-03-20T22:40:33Z') // need this semicolon? + ;(format as jest.Mock).mockImplementationOnce(() => '6 days ago') }) const mockPR: PullRequest = { @@ -41,10 +43,10 @@ const mockPR: PullRequest = { labels: { nodes: [ { - name: 'stuff' - } - ] - } + name: 'stuff', + }, + ], + }, } test('formats single PR', () => { @@ -54,6 +56,24 @@ test('formats single PR', () => { test('formats slack message', () => { const formattedPR = formatSinglePR(mockPR) - const formattedSlackMessage = formatSlackMessage('SeanReece/pr-reporter-slack', formattedPR, 2, 1) + const formattedSlackMessage = formatSlackMessage( + 'SeanReece/pr-reporter-slack', + formattedPR, + 2, + 1, + ) + expect(formattedSlackMessage).toMatchSnapshot() +}) + +test('stale PR', () => { + const stalePr = { ...mockPR, createdAt: '2020-03-01T22:40:33Z' } + + const formattedPR = formatSinglePR(stalePr) + const formattedSlackMessage = formatSlackMessage( + 'SeanReece/pr-reporter-slack', + formattedPR, + 2, + 1, + ) expect(formattedSlackMessage).toMatchSnapshot() }) diff --git a/action.yml b/action.yml index 9bd0791..dc3223a 100644 --- a/action.yml +++ b/action.yml @@ -13,6 +13,9 @@ inputs: default: 'true' exclude-labels: description: 'Comma seperated list of labels to exclude from PR reports' + stale-pr: + description: 'Should stale PR's be marked' + default: -15 runs: using: 'node12' main: 'dist/index.js' diff --git a/package-lock.json b/package-lock.json index fbe171c..a3f0c76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1549,6 +1549,11 @@ } } }, + "date-fns": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.15.0.tgz", + "integrity": "sha512-ZCPzAMJZn3rNUvvQIMlXhDr4A+Ar07eLeGsGREoWU19a3Pqf5oYa+ccd+B3F6XVtQY6HANMFdOQ8A+ipFnvJdQ==" + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -4710,6 +4715,12 @@ "minimist": "0.0.8" } }, + "mockdate": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.2.tgz", + "integrity": "sha512-ldfYSUW1ocqSHGTK6rrODUiqAFPGAg0xaHqYJ5tvj1hQyFsjuHpuWgWFTZWwDVlzougN/s2/mhDr8r5nY5xDpA==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", diff --git a/package.json b/package.json index fd7c2ce..54a39fc 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@actions/core": "^1.2.0", "@actions/github": "^2.0.0", "axios": "^0.19.0", + "date-fns": "^2.15.0", "timeago.js": "^4.0.1" }, "devDependencies": { @@ -41,6 +42,7 @@ "jest": "^24.9.0", "jest-circus": "^24.9.0", "js-yaml": "^3.13.1", + "mockdate": "^3.0.2", "prettier": "^1.19.1", "ts-jest": "^24.2.0", "typescript": "^3.6.4" diff --git a/src/message.ts b/src/message.ts index 7605fb0..37e63f7 100644 --- a/src/message.ts +++ b/src/message.ts @@ -1,6 +1,7 @@ import { format } from 'timeago.js' +import * as core from '@actions/core' import * as github from './github' - +import { differenceInCalendarDays } from 'date-fns' export interface BlockMessage { username: string icon_emoji: string @@ -8,7 +9,14 @@ export interface BlockMessage { } export function formatSinglePR(pr: github.PullRequest): string { + const stalePrDays: string = core.getInput('stale-pr') // Number of days before marking a PR as stale let status = '' + let stalePr: boolean + + const createdAt = new Date(pr.createdAt) + if (differenceInCalendarDays(createdAt, Date.now()) <= (stalePrDays || -15)) { + stalePr = true + } if (pr.reviews.totalCount === 0) { status = '*No reviews*' } else if ( @@ -20,10 +28,15 @@ export function formatSinglePR(pr: github.PullRequest): string { } else { status = `*${pr.reviews.totalCount} approvals*` } - return `\nšŸ‘‰ <${pr.url}|${pr.title}> | ${status} | ${format( - pr.createdAt, - 'en_US', - )}` + + const dateString = (): string => { + if (stalePr) { + return `šŸšØ ${format(pr.createdAt, 'en_US')} šŸšØ` + } + return `${format(pr.createdAt, 'en_US')}` + } + + return `\nšŸ‘‰ <${pr.url}|${pr.title}> | ${status} | ${dateString()}` } export function formatSlackMessage( From fed88a4c4debcc0db25867a2e7108bcc174acd3a Mon Sep 17 00:00:00 2001 From: Sean Reece Date: Thu, 19 May 2022 10:07:25 -0400 Subject: [PATCH 2/3] Update src/message.ts --- src/message.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/message.ts b/src/message.ts index 37e63f7..0fcd04e 100644 --- a/src/message.ts +++ b/src/message.ts @@ -10,6 +10,7 @@ export interface BlockMessage { export function formatSinglePR(pr: github.PullRequest): string { const stalePrDays: string = core.getInput('stale-pr') // Number of days before marking a PR as stale + if (stalePrDays > 0) stalePrDays = stalePrDays * -1 let status = '' let stalePr: boolean From cc0108a3946638d6d2846b97747d431e6eb83cf7 Mon Sep 17 00:00:00 2001 From: Sean Reece Date: Thu, 19 May 2022 10:07:35 -0400 Subject: [PATCH 3/3] Update action.yml --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index dc3223a..57662de 100644 --- a/action.yml +++ b/action.yml @@ -15,7 +15,7 @@ inputs: description: 'Comma seperated list of labels to exclude from PR reports' stale-pr: description: 'Should stale PR's be marked' - default: -15 + default: 15 runs: using: 'node12' main: 'dist/index.js'