Skip to content
This repository has been archived by the owner on May 20, 2023. It is now read-only.

Commit

Permalink
Merge pull request #169 from scribblemaniac/whitelisting
Browse files Browse the repository at this point in the history
Add whitelist support
  • Loading branch information
tcbyrd committed Mar 20, 2019
2 parents 3d00226 + 34963c3 commit e3c53eb
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 6 deletions.
5 changes: 4 additions & 1 deletion README.md
Expand Up @@ -24,6 +24,9 @@ daysUntilStale: 60
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 7

# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
onlyLabels: []

# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
- pinned
Expand Down Expand Up @@ -87,7 +90,7 @@ To avoid triggering abuse prevention mechanisms on GitHub, only 30 issues and pu

## How long will it take?

The app runs on a scheduled basis and in batches in order to avoid hitting rate limit ceilings.
The app runs on a scheduled basis and in batches in order to avoid hitting rate limit ceilings.

This means that even after you initially install the GitHub configuration and add the `stale.yml` file, you may not see it act immediately.

Expand Down
2 changes: 1 addition & 1 deletion index.js
Expand Up @@ -39,7 +39,7 @@ module.exports = async app => {
context.payload.label.name === stale.config.staleLabel

if (stale.hasStaleLabel(type, issue) && issue.state !== 'closed' && !staleLabelAdded) {
stale.unmark(type, issue)
stale.unmarkIssue(type, issue)
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions lib/schema.js
Expand Up @@ -8,6 +8,9 @@ const fields = {
.error(() => '"daysUntilClose" must be a number or false')
.description('Number of days of inactivity before a stale Issue or Pull Request is closed. If disabled, issues still need to be closed manually, but will remain marked as stale.'),

onlyLabels: Joi.alternatives().try(Joi.any().valid(null), Joi.array().single())
.description('Only issues or pull requests with all of these labels are checked for staleness. Set to `[]` to disable'),

exemptLabels: Joi.alternatives().try(Joi.any().valid(null), Joi.array().single())
.description('Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable'),

Expand Down Expand Up @@ -43,6 +46,7 @@ const fields = {
const schema = Joi.object().keys({
daysUntilStale: fields.daysUntilStale.default(60),
daysUntilClose: fields.daysUntilClose.default(7),
onlyLabels: fields.onlyLabels.default([]),
exemptLabels: fields.exemptLabels.default(['pinned', 'security']),
exemptProjects: fields.exemptProjects.default(false),
exemptMilestones: fields.exemptMilestones.default(false),
Expand Down
15 changes: 12 additions & 3 deletions lib/stale.js
Expand Up @@ -32,14 +32,21 @@ module.exports = class Stale {
const limitPerRun = this.getConfigValue(type, 'limitPerRun') || maxActionsPerRun
this.remainingActions = Math.min(limitPerRun, maxActionsPerRun)

await this.mark(type)
await this.sweep(type)
}

async mark (type) {
await this.ensureStaleLabelExists(type)

const staleItems = (await this.getStale(type)).data.items

await Promise.all(staleItems.filter(issue => !issue.locked).map(issue => {
return this.mark(type, issue)
return this.markIssue(type, issue)
}))
}

async sweep (type) {
const { owner, repo } = this.config
const daysUntilClose = this.getConfigValue(type, 'daysUntilClose')

Expand All @@ -56,13 +63,15 @@ module.exports = class Stale {
}

getStale (type) {
const onlyLabels = this.getConfigValue(type, 'onlyLabels')
const staleLabel = this.getConfigValue(type, 'staleLabel')
const exemptLabels = this.getConfigValue(type, 'exemptLabels')
const exemptProjects = this.getConfigValue(type, 'exemptProjects')
const exemptMilestones = this.getConfigValue(type, 'exemptMilestones')
const exemptAssignees = this.getConfigValue(type, 'exemptAssignees')
const labels = [staleLabel].concat(exemptLabels)
const queryParts = labels.map(label => `-label:"${label}"`)
queryParts.concat(onlyLabels.map(label => `label:"${label}"`))
queryParts.push(Stale.getQueryTypeRestriction(type))

queryParts.push(exemptProjects ? 'no:project' : '')
Expand Down Expand Up @@ -103,7 +112,7 @@ module.exports = class Stale {
return this.github.search.issues(params)
}

async mark (type, issue) {
async markIssue (type, issue) {
if (this.remainingActions === 0) {
return
}
Expand Down Expand Up @@ -148,7 +157,7 @@ module.exports = class Stale {
}
}

async unmark (type, issue) {
async unmarkIssue (type, issue) {
const { owner, repo } = this.config
const perform = this.getConfigValue(type, 'perform')
const staleLabel = this.getConfigValue(type, 'staleLabel')
Expand Down
5 changes: 5 additions & 0 deletions test/schema.test.js
Expand Up @@ -3,6 +3,10 @@ const schema = require('../lib/schema')
const validConfigs = [
[{ daysUntilClose: false }],
[{ daysUntilClose: 1 }],
[{ onlyLabels: ['foo'] }],
[{ onlyLabels: 'foo' }, { onlyLabels: ['foo'] }],
[{ onlyLabels: null }],
[{ onlyLabels: [] }],
[{ exemptLabels: ['foo'] }],
[{ exemptLabels: 'foo' }, { exemptLabels: ['foo'] }],
[{ exemptLabels: null }],
Expand Down Expand Up @@ -58,6 +62,7 @@ describe('schema', () => {
expect(schema.validate({}).value).toEqual({
daysUntilStale: 60,
daysUntilClose: 7,
onlyLabels: [],
exemptLabels: ['pinned', 'security'],
exemptProjects: false,
exemptMilestones: false,
Expand Down
2 changes: 1 addition & 1 deletion test/stale.test.js
Expand Up @@ -48,7 +48,7 @@ describe('stale', () => {

for (const type of ['pulls', 'issues']) {
try {
await stale.unmark(type, { number: 123 })
await stale.unmarkIssue(type, { number: 123 })
} catch (_) {
throw new Error('Should not have thrown an error')
}
Expand Down

0 comments on commit e3c53eb

Please sign in to comment.