diff --git a/README.md b/README.md index d3004f9..129b9cb 100644 --- a/README.md +++ b/README.md @@ -8,15 +8,15 @@ that locks closed issues and pull requests after a period of inactivity. ## Supporting the Project -Lock Threads is an MIT-licensed open source project. Its ongoing -development is made possible thanks to the support of awesome backers. -If you'd like to join them, please consider contributing with -[Patreon](https://goo.gl/qRhKSW), [PayPal](https://goo.gl/5FnBaw) -or [Bitcoin](https://goo.gl/uJUAaU). +The continued development of Lock Threads is made possible +thanks to the support of awesome backers. If you'd like to join them, +please consider contributing with [Patreon](https://goo.gl/qRhKSW), +[PayPal](https://goo.gl/5FnBaw) or [Bitcoin](https://goo.gl/uJUAaU). ## Usage 1. **[Install the GitHub App](https://github.com/apps/lock)** + for the required repositories 2. Create `.github/lock.yml` based on the template below 3. It will start scanning for closed issues and/or pull requests within an hour diff --git a/assets/app-description.md b/assets/app-description.md index 62d5105..455db5d 100644 --- a/assets/app-description.md +++ b/assets/app-description.md @@ -4,7 +4,7 @@ A GitHub App that locks closed issues and pull requests after a period of inacti ## Usage -1. **[Install the GitHub App](https://github.com/apps/lock)** +1. **[Install the GitHub App](https://github.com/apps/lock)** for the required repositories 2. Create `.github/lock.yml` based on the template below 3. It will start scanning for closed issues and/or pull requests within an hour @@ -45,4 +45,4 @@ lockComment: > ## Supporting the Project -Lock Threads is an MIT-licensed open source project. Its ongoing development is made possible thanks to the support of awesome backers. If you'd like to join them, please consider contributing with [Patreon](https://goo.gl/qRhKSW), [PayPal](https://goo.gl/5FnBaw) or [Bitcoin](https://goo.gl/uJUAaU). +The continued development of Lock Threads is made possible thanks to the support of awesome backers. If you'd like to join them, please consider contributing with [Patreon](https://goo.gl/qRhKSW), [PayPal](https://goo.gl/5FnBaw) or [Bitcoin](https://goo.gl/uJUAaU). diff --git a/package.json b/package.json index d957e48..e9ef9cc 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,8 @@ "dependencies": { "joi": "^13.3.0", "probot": "^6.2.0", - "probot-scheduler": "^1.1.0" + "probot-scheduler": "^1.1.0", + "uuid": "^3.2.1" }, "devDependencies": { "nodemon": "1.17.5", diff --git a/src/index.js b/src/index.js index 112c5c2..bbb0b03 100644 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,4 @@ +const uuidV4 = require('uuid/v4'); const createScheduler = require('probot-scheduler'); const App = require('./lock'); @@ -7,39 +8,37 @@ module.exports = robot => { scheduler = createScheduler(robot); robot.on('schedule.repository', async context => { - const app = await getApp(context); + const logger = robot.log.child({task: uuidV4()}); + const app = await getApp(context, logger); if (app) { - const {only: type} = app.config; - if (type) { - await app.lock(type); - } else { - await app.lock('issues'); - await app.lock('pulls'); - } + await app.lockThreads(); } }); - async function getApp(context) { - const config = await getConfig(context); - if (config) { - return new App(context, config, robot.log); + async function getApp(context, logger = robot.log) { + const config = await getConfig(context, logger); + if (config && config.perform) { + return new App(context, config, logger); } } - async function getConfig(context) { - const {owner, repo} = context.issue(); + async function getConfig(context, logger) { let config; + const configFile = 'lock.yml'; + const repo = context.repo(); try { - const repoConfig = await context.config('lock.yml'); - if (repoConfig) { - const {error, value} = schema.validate(repoConfig); - if (error) { - throw error; - } - config = value; + const repoConfig = await context.config(configFile); + if (!repoConfig) { + logger.warn({repo, configFile}, 'Missing config'); + repoConfig = {perform: false}; } + const {error, value} = schema.validate(repoConfig); + if (error) { + throw error; + } + config = value; } catch (err) { - robot.log.warn({err: new Error(err), owner, repo}, 'Invalid config'); + logger.warn({err: new Error(err), repo, configFile}, 'Invalid config'); } return config; diff --git a/src/lock.js b/src/lock.js index a8538e4..6df4676 100644 --- a/src/lock.js +++ b/src/lock.js @@ -2,42 +2,47 @@ module.exports = class Lock { constructor(context, config, logger) { this.context = context; this.config = config; - this.logger = logger; + this.log = logger; + } + + async lockThreads() { + const {only: type} = this.config; + if (type) { + await this.lock(type); + } else { + await this.lock('issues'); + await this.lock('pulls'); + } } async lock(type) { - const {owner, repo} = this.context.repo(); + const repo = this.context.repo(); const lockLabel = this.getConfigValue(type, 'lockLabel'); const lockComment = this.getConfigValue(type, 'lockComment'); - const issues = await this.getLockableIssues(type); - for (const issue of issues) { - const issueUrl = `${owner}/${repo}/issues/${issue.number}`; + const results = await this.getLockableIssues(type); + for (const result of results) { + const issue = {...repo, number: result.number}; + if (lockComment) { - this.logger.info(`[${issueUrl}] Commenting`); + this.log.info({issue}, 'Commenting'); await this.context.github.issues.createComment({ - owner, - repo, - number: issue.number, + ...issue, body: lockComment }); } if (lockLabel) { - this.logger.info(`[${issueUrl}] Labeling`); + this.log.info({issue}, 'Labeling'); await this.context.github.issues.addLabels({ - owner, - repo, - number: issue.number, + ...issue, labels: [lockLabel] }); } - this.logger.info(`[${issueUrl}] Locking`); + this.log.info({issue}, 'Locking'); await this.context.github.issues.lock({ - owner, - repo, - number: issue.number, + ...issue, lock_reason: 'resolved', headers: { accept: 'application/vnd.github.sailor-v-preview+json' @@ -66,7 +71,7 @@ module.exports = class Lock { query += ' is:pr'; } - this.logger.info(`[${owner}/${repo}] Searching ${type}`); + this.log.info({repo: {owner, repo}}, `Searching ${type}`); return this.context.github.search.issues({ q: query, sort: 'updated', diff --git a/src/schema.js b/src/schema.js index 7beb395..b8aecc8 100644 --- a/src/schema.js +++ b/src/schema.js @@ -38,7 +38,8 @@ const schema = Joi.object().keys({ .valid('issues', 'pulls') .description('Limit to only `issues` or `pulls`'), pulls: Joi.object().keys(fields), - issues: Joi.object().keys(fields) + issues: Joi.object().keys(fields), + perform: Joi.boolean().default(!process.env.DRY_RUN) }); module.exports = schema; diff --git a/yarn.lock b/yarn.lock index 8c178c4..51e1448 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4181,6 +4181,10 @@ uuid@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" +uuid@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" + validate-npm-package-license@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc"