From 315596b0738cd437c6b63c200889400ea776948f Mon Sep 17 00:00:00 2001 From: Lennart Date: Tue, 26 Nov 2019 15:43:04 +0100 Subject: [PATCH] feat: Use "Stale" GitHub action (#19628) * remove peril stale stuff * disable dry run and remove all excempt labels except 'not stale' * update tag on action --- .github/workflows/schedule-stale.yml | 7 +- peril.settings.json | 7 -- peril/rules/not-stale.ts | 31 ------ peril/rules/run-stale-immediately.ts | 10 -- peril/tasks/stale.ts | 138 --------------------------- peril/tests/not-stale.test.ts | 49 ---------- peril/tests/stale.test.ts | 23 ----- 7 files changed, 1 insertion(+), 264 deletions(-) delete mode 100644 peril/rules/not-stale.ts delete mode 100644 peril/rules/run-stale-immediately.ts delete mode 100644 peril/tasks/stale.ts delete mode 100644 peril/tests/not-stale.test.ts delete mode 100644 peril/tests/stale.test.ts diff --git a/.github/workflows/schedule-stale.yml b/.github/workflows/schedule-stale.yml index a828eff675ddb..09d928da56b51 100644 --- a/.github/workflows/schedule-stale.yml +++ b/.github/workflows/schedule-stale.yml @@ -9,12 +9,11 @@ jobs: steps: - name: stale id: stale - uses: gatsbyjs/stale@gatsby-repo-test + uses: gatsbyjs/stale@0.1.0 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} DAYS_BEFORE_STALE: 20 DAYS_BEFORE_CLOSE: 10 - DRY_RUN: true OPERATIONS_PER_RUN: 5000 STALE_ISSUE_MESSAGE: | Hiya! @@ -36,10 +35,6 @@ jobs: Thanks again for being part of the Gatsby community! 💪💜 EXEMPT_ISSUE_LABELS: | not stale - important - good first issue - no triage - status: confirmed - name: Post slack report uses: pullreminders/slack-action@v1.0.7 env: diff --git a/peril.settings.json b/peril.settings.json index c183352a8bb28..4c996569f0f1f 100644 --- a/peril.settings.json +++ b/peril.settings.json @@ -6,7 +6,6 @@ "modules": ["@slack/client", "joi", "js-yaml", "date-fns"] }, "rules": { - "issue_comment": ["peril/rules/not-stale.ts"], "issues.opened": ["peril/rules/emptybody.ts", "peril/rules/labeler.ts"], "pull_request.closed (pull_request.merged == true)": [ "peril/rules/invite-collaborator.ts" @@ -40,11 +39,5 @@ "gatsbyjs/gatsby@peril/rules/pull-request-on-starter.ts" ] } - }, - "tasks": { - "stale": "peril/tasks/stale.ts" - }, - "scheduler": { - "daily": "stale" } } diff --git a/peril/rules/not-stale.ts b/peril/rules/not-stale.ts deleted file mode 100644 index 2a5c39c6bc463..0000000000000 --- a/peril/rules/not-stale.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { danger } from "danger" -import { IssueComment } from "github-webhook-event-types" - -export const STALE_LABEL = `stale?` - -export const notStale = async () => { - const gh = (danger.github as any) as IssueComment - const repo = gh.repository - const labels = gh.issue.labels.map(i => i.name) - const opts = { - owner: repo.owner.login, - repo: repo.name, - number: gh.issue.number, - name: encodeURIComponent(STALE_LABEL), - } as any - - if (labels.includes(STALE_LABEL)) { - try { - await danger.github.api.issues.removeLabel(opts) - } catch (error) { - console.log( - `Could not run issues.removeLabel with options: ${JSON.stringify(opts)}` - ) - console.log(error) - } - } -} - -export default async () => { - await notStale() -} diff --git a/peril/rules/run-stale-immediately.ts b/peril/rules/run-stale-immediately.ts deleted file mode 100644 index 84d30bf10a3f9..0000000000000 --- a/peril/rules/run-stale-immediately.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { danger, peril } from "danger" - -// Trigger this rule to run in order to check a scheduled task immediately -// example config: -// "issue_comment.edited": ["rules/run-stale-immediately.ts"], -export default async () => { - console.log("Running stale task in 1 second") - await peril.runTask("stale", "in 1 second", {}) - console.log("Stale task finished") -} diff --git a/peril/tasks/stale.ts b/peril/tasks/stale.ts deleted file mode 100644 index 55f472ffb22b0..0000000000000 --- a/peril/tasks/stale.ts +++ /dev/null @@ -1,138 +0,0 @@ -import { danger, peril } from "danger" -import * as endOfToday from "date-fns/end_of_today" -import * as subDays from "date-fns/sub_days" -import * as format from "date-fns/format" -import { IssueComment } from "github-webhook-event-types" - -const owner = `gatsbyjs` - -const STALE_LABEL = `stale?` -const EXEMPT_LABEL = `not stale` -const DAYS_TO_STALE = 20 -const DAYS_TO_CLOSE = 10 -const MAX_ACTIONS = 20 -const CONTRIBUTION_GUIDE_LINK = `https://www.gatsbyjs.org/contributing/how-to-contribute/` -const STALE_MESSAGE = `Hiya! - -This issue has gone quiet. Spooky quiet. 👻 - -We get a lot of issues, so we currently close issues after ${DAYS_TO_STALE + - DAYS_TO_CLOSE} days of inactivity. It’s been at least ${DAYS_TO_STALE} days since the last update here. - -If we missed this issue or if you want to keep it open, please reply here. You can also add the label "${EXEMPT_LABEL}" to keep this issue open! - -As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out [gatsby.dev/contribute](${CONTRIBUTION_GUIDE_LINK}) for more information about opening PRs, triaging issues, and contributing! - -Thanks for being a part of the Gatsby community! 💪💜` - -const CLOSE_MESSAGE = `Hey again! - -It’s been ${DAYS_TO_STALE + - DAYS_TO_CLOSE} days since anything happened on this issue, so our friendly neighborhood robot (that’s me!) is going to close it. - -Please keep in mind that I’m only a robot, so if I’ve closed this issue in error, I’m \`HUMAN_EMOTION_SORRY\`. Please feel free to reopen this issue or create a new one if you need anything else. - -As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out [gatsby.dev/contribute](${CONTRIBUTION_GUIDE_LINK}) for more information about opening PRs, triaging issues, and contributing! - -Thanks again for being part of the Gatsby community!` - -export const dateDaysAgo = (today: Date, days: number): string => { - const daysAgo = subDays(today, days) - return format(daysAgo, "YYYY-MM-DD") -} - -interface ApiError { - action: string - opts: object - error: any -} - -const logApiError = ({ action, opts, error }: ApiError) => { - const msg = `Could not run ${action} with options ${JSON.stringify( - opts - )}\n Error was ${error}\nSet env var DEBUG=octokit:rest* for extended logging info.` - console.warn(msg) -} - -// url format is "https://api.github.com/repos//" -// See https://api.github.com/search/issues?q=-label:%22not%20stale%22 for examples -// TODO: hit the url and parse the name from the response, with error handling -const getRepoFromUrl = (url: string) => url.split("/").pop() - -const search = async (days: number, query: string) => { - const api = danger.github.api - const timestamp = dateDaysAgo(endOfToday(), days) - const q = `-label:"${EXEMPT_LABEL}" org:${owner} type:issue state:open archived:false updated:<${timestamp} ${query}` - const searchResponse = await api.search.issues({ - q, - order: "asc", - sort: "updated", - per_page: MAX_ACTIONS, - }) - const items = searchResponse.data.items - return items.slice(0, Math.min(items.length, MAX_ACTIONS)) -} - -const makeItStale = async (issue: { - number: number - repository_url: string -}) => { - let opts: any // any :( - const api = danger.github.api - const repo = getRepoFromUrl(issue.repository_url) - const defaultOpts = { owner, repo, number: issue.number } - - opts = { ...defaultOpts, labels: [STALE_LABEL] } - try { - await api.issues.addLabels(opts) - } catch (error) { - logApiError({ action: `issues.addLabels`, opts, error }) - } - - opts = { ...defaultOpts, body: STALE_MESSAGE } - try { - await api.issues.createComment(opts) - } catch (error) { - logApiError({ action: `issues.createComment`, opts, error }) - } -} - -const makeItClosed = async (issue: { - number: number - repository_url: string -}) => { - let opts: any // any :( - const api = danger.github.api - const repo = getRepoFromUrl(issue.repository_url) - const defaultOpts = { owner, repo, number: issue.number } - - opts = { ...defaultOpts, body: CLOSE_MESSAGE } - try { - await api.issues.createComment(opts) - } catch (error) { - logApiError({ action: `issues.createComment`, opts, error }) - } - - opts = { ...defaultOpts, state: "closed" } - try { - await api.issues.edit(opts) - } catch (error) { - logApiError({ action: `issues.edit`, opts, error }) - } -} - -export default async () => { - console.log("Stale task: init") - - // mark old issues as stale - const toLabel = await search(DAYS_TO_STALE, `-label:"${STALE_LABEL}"`) - console.log(`Stale task: found ${toLabel.length} issues to label`) - await Promise.all(toLabel.map(makeItStale)) - console.log("Stale task: labelled stale issues") - - // close out untouched stale issues - const toClose = await search(DAYS_TO_CLOSE, `label:"${STALE_LABEL}"`) - console.log(`Stale task: found ${toClose.length} issues to close`) - await Promise.all(toClose.map(makeItClosed)) - console.log("Stale task: closed issues") -} diff --git a/peril/tests/not-stale.test.ts b/peril/tests/not-stale.test.ts deleted file mode 100644 index f66d0b8e24120..0000000000000 --- a/peril/tests/not-stale.test.ts +++ /dev/null @@ -1,49 +0,0 @@ -jest.mock("danger", () => jest.fn()) -import { IssueComment } from "github-webhook-event-types" -import * as danger from "danger" -const dm = danger as any - -import { notStale, STALE_LABEL } from "../rules/not-stale" - -beforeEach(() => { - const github = ({ - repository: { - name: "gatsby", - owner: { - login: "gatsbyjs", - }, - }, - issue: { - labels: [], - number: 100, - }, - api: { - issues: { - removeLabel: jest.fn(), - }, - }, - } as any) as IssueComment - dm.danger = { github } -}) - -describe("a new issue comment", () => { - it("removes stale? label", async () => { - dm.danger.github.issue.labels = [ - { name: "foo" }, - { name: "stale?" }, - { name: "bar" }, - ] - await notStale() - expect(dm.danger.github.api.issues.removeLabel).toBeCalledWith({ - repo: "gatsby", - owner: "gatsbyjs", - number: 100, - name: encodeURIComponent(STALE_LABEL), - }) - }) - it("does nothing without a stale? label", () => { - return notStale().then(() => { - expect(dm.danger.github.api.issues.removeLabel).not.toHaveBeenCalled() - }) - }) -}) diff --git a/peril/tests/stale.test.ts b/peril/tests/stale.test.ts deleted file mode 100644 index edc24b8ab5c9e..0000000000000 --- a/peril/tests/stale.test.ts +++ /dev/null @@ -1,23 +0,0 @@ -jest.mock("danger", () => jest.fn()) - -import { dateDaysAgo } from "../tasks/stale" - -describe("date handling", () => { - it("subtracts one day", () => { - const dateToday = new Date(2015, 4, 21) - const formatted = dateDaysAgo(dateToday, 1) - expect(formatted).toEqual(`2015-05-20`) - }) - it("subtracts across months", () => { - const dateToday = new Date(2015, 4, 21) - const formatted = dateDaysAgo(dateToday, 22) - expect(formatted).toEqual(`2015-04-29`) - }) - it("subtracts across years", () => { - const dateToday = new Date(2015, 0, 21) - const formatted = dateDaysAgo(dateToday, 21) - expect(formatted).toEqual(`2014-12-31`) - }) -}) - -// test for quotes around labels