Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support 'issue_comment' event as trigger for actions #754

Merged
merged 1 commit into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion __fixtures__/unit/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ module.exports = {
},
requestReviewers: jest.fn().mockReturnValue(options.requestReviewers || 'request review success'),
merge: jest.fn().mockReturnValue(options.merge || 'merged'),
get: jest.fn()
get: jest.fn().mockReturnValue({ data: { head: { ref: 'test', sha: 'sha1' } } })
},
paginate: jest.fn(async (fn, cb) => {
return fn.then(cb)
Expand Down
33 changes: 25 additions & 8 deletions __tests__/unit/actions/assign.test.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
const Assign = require('../../../lib/actions/assign')
const Helper = require('../../../__fixtures__/unit/helper')

test.each([
undefined,
'pull_request',
'issues',
'issue_comment'
])('check that assign is called for %s events', async (eventName) => {
const settings = {
assignees: []
}

const assign = new Assign()
const context = createMockContext(eventName)

await assign.afterValidate(context, settings)
expect(context.octokit.issues.addAssignees.mock.calls.length).toBe(1)
})

test('check that assignees are added when afterValidate is called with proper parameter', async () => {
const settings = {
assignees: ['testuser1', 'testuser2']
}

const comment = new Assign()
const assign = new Assign()
const context = createMockContext()

await comment.afterValidate(context, settings)
await assign.afterValidate(context, settings)
expect(context.octokit.issues.addAssignees.mock.calls.length).toBe(1)
expect(context.octokit.issues.addAssignees.mock.calls[0][0].assignees[0]).toBe('testuser1')
expect(context.octokit.issues.addAssignees.mock.calls[0][0].assignees[1]).toBe('testuser2')
Expand All @@ -20,10 +37,10 @@ test('check that creator is added when assignee is @author', async () => {
assignees: ['@author']
}

const comment = new Assign()
const assign = new Assign()
const context = createMockContext()

await comment.afterValidate(context, settings)
await assign.afterValidate(context, settings)
expect(context.octokit.issues.addAssignees.mock.calls.length).toBe(1)
expect(context.octokit.issues.addAssignees.mock.calls[0][0].assignees[0]).toBe('creator')
})
Expand All @@ -33,7 +50,7 @@ test('check only authorized users are added as assignee ', async () => {
assignees: ['testuser1', 'testuser2']
}

const comment = new Assign()
const assign = new Assign()
const context = createMockContext()

context.octokit.issues.checkUserCanBeAssigned = (input) => {
Expand All @@ -45,14 +62,14 @@ test('check only authorized users are added as assignee ', async () => {
})
}

await comment.afterValidate(context, settings)
await assign.afterValidate(context, settings)
expect(context.octokit.issues.addAssignees.mock.calls.length).toBe(1)
expect(context.octokit.issues.addAssignees.mock.calls[0][0].assignees[0]).toBe('testuser1')
expect(context.octokit.issues.addAssignees.mock.calls[0][0].assignees[1]).toBeUndefined()
})

const createMockContext = () => {
const context = Helper.mockContext()
const createMockContext = (eventName = undefined) => {
const context = Helper.mockContext({ eventName })

context.octokit.issues.addAssignees = jest.fn()
return context
Expand Down
37 changes: 33 additions & 4 deletions __tests__/unit/actions/checks.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,43 @@ const MetaData = require('../../../lib/metaData')
const Checks = require('../../../lib/actions/checks')
const Helper = require('../../../__fixtures__/unit/helper')

test('run', async () => {
test.each([
undefined,
'pull_request',
'pull_request_review',
'issue_comment'
])('that checks is called for %s events', async (eventName) => {
const checks = new Checks()
const context = createMockContext(eventName)
const result = {}
const settings = {
payload: {},
state: 'completed',
status: 'success'
}

const name = undefined

checks.checkRunResult = new Map()

checks.checkRunResult.set(name, {
data: {
id: '3'
}
})

await checks.afterValidate(context, settings, name, result)
expect(context.octokit.checks.update.mock.calls.length).toBe(1)
})

test('that run calls create api', async () => {
const checks = new Checks()
const context = createMockContext()
await checks.run({ context, payload: {} })
expect(context.octokit.checks.create.mock.calls.length).toBe(1)
})

test('check that checks created when doPostAction is called with proper parameter', async () => {
test('that checks created when doPostAction is called with proper parameter', async () => {
const checks = new Checks()
const context = createMockContext()
const settings = { name: 'test' }
Expand Down Expand Up @@ -183,8 +212,8 @@ test('that correct name is used afterValidate payload', async () => {
expect(MetaData.exists(output.text)).toBe(true)
})

const createMockContext = () => {
const context = Helper.mockContext()
const createMockContext = (eventName = undefined) => {
const context = Helper.mockContext({ eventName })
context.payload.action = 'actionName'
context.octokit.checks.create = jest.fn()
context.octokit.checks.update = jest.fn()
Expand Down
22 changes: 22 additions & 0 deletions __tests__/unit/actions/close.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,28 @@
const Close = require('../../../lib/actions/close')
const Helper = require('../../../__fixtures__/unit/helper')

test.each([
undefined,
'pull_request',
'issues',
'issue_comment',
'schedule'
])('check that close is called for %s events', async (eventName) => {
const close = new Close()
const context = Helper.mockContext({ eventName: eventName })
const schedulerResult = {
validationSuites: [{
schedule: {
issues: [{ number: 1, user: { login: 'scheduler' } }],
pulls: []
}
}]
}

await close.afterValidate(context, {}, '', schedulerResult)
expect(context.octokit.issues.update.mock.calls.length).toBe(1)
})

test('check that issue is closed', async () => {
const close = new Close()
const context = Helper.mockContext()
Expand Down
28 changes: 24 additions & 4 deletions __tests__/unit/actions/comment.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,27 @@ const result = {
}]
}

test.each([
undefined,
'pull_request',
'issues',
'issue_comment',
'schedule'
])('check that comment is called for %s events', async (eventName) => {
const comment = new Comment()
const context = createMockContext([], eventName)
const schedulerResult = { ...result }
schedulerResult.validationSuites = [{
schedule: {
issues: [{ number: 1, user: { login: 'scheduler' } }],
pulls: []
}
}]

await comment.afterValidate(context, settings, '', schedulerResult)
expect(context.octokit.issues.createComment.mock.calls.length).toBe(1)
})

test('check that comment created when afterValidate is called with proper parameter', async () => {
const comment = new Comment()
const context = createMockContext()
Expand All @@ -34,8 +55,7 @@ test('check that comment created when afterValidate is called with proper parame

test('that comment is created three times when result contain three issues found to be acted on', async () => {
const comment = new Comment()
const context = createMockContext([], 'repository')
context.eventName = 'schedule'
const context = createMockContext([], 'schedule', 'repository')
const schedulerResult = { ...result }
schedulerResult.validationSuites = [{
schedule: {
Expand Down Expand Up @@ -236,8 +256,8 @@ test('error handling includes removing old error comments and creating new error
expect(context.octokit.issues.createComment.mock.calls[0][0].body).toBe('creator , do something!')
})

const createMockContext = (listComments, event = undefined) => {
const context = Helper.mockContext({ listComments, event })
const createMockContext = (listComments, eventName = undefined, event = undefined) => {
const context = Helper.mockContext({ listComments, eventName, event })

context.octokit.issues.createComment = jest.fn()
context.octokit.issues.deleteComment = jest.fn()
Expand Down
25 changes: 25 additions & 0 deletions __tests__/unit/actions/labels.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,31 @@ const Labels = require('../../../lib/actions/labels')
const Helper = require('../../../__fixtures__/unit/helper')
const UnSupportedSettingError = require('../../../lib/errors/unSupportedSettingError')

test.each([
undefined,
'pull_request',
'issues',
'issue_comment',
'schedule'
])('check that close is called for %s events', async (eventName) => {
const labels = new Labels()
const context = createMockContext([], eventName)
const settings = {
add: ['a label']
}
const schedulerResult = {
validationSuites: [{
schedule: {
issues: [{ number: 1, user: { login: 'scheduler' } }],
pulls: []
}
}]
}

await labels.afterValidate(context, settings, '', schedulerResult)
expect(context.octokit.issues.setLabels.mock.calls.length).toBe(1)
})

test('check that replace replaces existing labels', async () => {
const labels = new Labels()
const context = createMockContext(['drop_label'])
Expand Down
36 changes: 36 additions & 0 deletions __tests__/unit/configuration/transformers/v2Config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,42 @@ test('pass, fail, error defaults will load when pull_request is mixed with other
expect(transformed.mergeable[0].error).toEqual(constants.DEFAULT_PR_ERROR)
})

test('pass, fail, error defaults will load when issue_comment event is specified.', () => {
const config = `
version: 2
mergeable:
- when: issue_comment.*
validate:
- do: lastComment
must_exclude:
regex: 'wip|work in progress'
`
const transformed = V2Config.transform(yaml.safeLoad(config))

expect(transformed.mergeable[0].pass).toEqual(constants.DEFAULT_PR_PASS)
expect(transformed.mergeable[0].fail).toEqual(constants.DEFAULT_PR_FAIL)
expect(transformed.mergeable[0].error).toEqual(constants.DEFAULT_PR_ERROR)
})

test('pass, fail, error defaults will load when pull_request_review event is specified.', () => {
const config = `
version: 2
mergeable:
- when: pull_request_review.*
validate:
- do: payload
review:
state:
must_exclude:
regex: 'changes_requested'
`
const transformed = V2Config.transform(yaml.safeLoad(config))

expect(transformed.mergeable[0].pass).toEqual(constants.DEFAULT_PR_PASS)
expect(transformed.mergeable[0].fail).toEqual(constants.DEFAULT_PR_FAIL)
expect(transformed.mergeable[0].error).toEqual(constants.DEFAULT_PR_ERROR)
})

test('only pass, fail defaults ignore recipes that are not for pull_requests', () => {
const config = `
version: 2
Expand Down
4 changes: 3 additions & 1 deletion docs/actions/assign.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Assign
^^^^^^^^

You can assign specific people to a pull request or issue.

::

- do: assign
Expand All @@ -9,4 +11,4 @@ Assign
Supported Events:
::

'pull_request.*', 'issues.*'
'pull_request.*', 'issues.*', 'issue_comment.*'
6 changes: 4 additions & 2 deletions docs/actions/check.rst → docs/actions/checks.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Check
Checks
^^^^^^^^

You can add check runs to a pull request to enforce that it can only be merged once all checks returned with success.

.. note::
The logic for whether checks will be added by default is as follows:
1. If no action is provided in either pass, fail or error , add `checks` as default (to be backward compatible)
Expand Down Expand Up @@ -74,4 +76,4 @@ The `pull_request.closed` event is not supported since it does not have meaningf

::

'pull_request.assigned', 'pull_request.auto_merge_disabled', 'pull_request.auto_merge_enabled', 'pull_request.converted_to_draft', 'pull_request.demilestoned', 'pull_request.dequeued', 'pull_request.edited', 'pull_request.enqueued', 'pull_request.labeled', 'pull_request.locked', 'pull_request.milestoned', 'pull_request.opened', 'pull_request.push_synchronize', 'pull_request.ready_for_review', 'pull_request.reopened', 'pull_request.review_request_removed', 'pull_request.review_requested', 'pull_request.synchronize', 'pull_request.unassigned', 'pull_request.unlabeled', 'pull_request.unlocked', 'pull_request_review.dismissed', 'pull_request_review.edited', 'pull_request_review.submitted'
'pull_request.assigned', 'pull_request.auto_merge_disabled', 'pull_request.auto_merge_enabled', 'pull_request.converted_to_draft', 'pull_request.demilestoned', 'pull_request.dequeued', 'pull_request.edited', 'pull_request.enqueued', 'pull_request.labeled', 'pull_request.locked', 'pull_request.milestoned', 'pull_request.opened', 'pull_request.push_synchronize', 'pull_request.ready_for_review', 'pull_request.reopened', 'pull_request.review_request_removed', 'pull_request.review_requested', 'pull_request.synchronize', 'pull_request.unassigned', 'pull_request.unlabeled', 'pull_request.unlocked', 'pull_request_review.dismissed', 'pull_request_review.edited', 'pull_request_review.submitted', 'issue_comment.*'
4 changes: 3 additions & 1 deletion docs/actions/close.rst
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
Close
^^^^^^^^

You can close a pull request or issue.

::

- do: close

Supported Events:
::

'schedule.repository', 'pull_request.*', 'issues.*'
'schedule.repository', 'pull_request.*', 'issues.*', 'issue_comment.*'
4 changes: 3 additions & 1 deletion docs/actions/comment.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Comment
^^^^^^^^

You can add a comment to a pull request or issue.

::

- do: comment
Expand All @@ -12,4 +14,4 @@ Comment
Supported Events:
::

'schedule.repository', 'pull_request.*', 'issues.*'
'schedule.repository', 'pull_request.*', 'issues.*', 'issue_comment.*'
2 changes: 1 addition & 1 deletion docs/actions/labels.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,4 @@ Note that the glob functionality is powered by the minimatch library. Please see
Supported Events:
::

'schedule.repository', 'pull_request.*', 'issues.*'
'schedule.repository', 'pull_request.*', 'issues.*', 'issue_comment.*'
4 changes: 3 additions & 1 deletion docs/actions/merge.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Merge
^^^^^^^^

You can merge a pull request and specify the merge method used.

::

- do: merge
Expand All @@ -14,4 +16,4 @@ Merge
Supported Events:
::

'pull_request.*', 'pull_request_review.*', 'status.*', 'check_suite.*'
'pull_request.*', 'pull_request_review.*', 'status.*', 'check_suite.*', 'issue_comment.*'
2 changes: 1 addition & 1 deletion docs/actions/request_review.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Request Review
^^^^^^^^^^^^^^^

You can request specific reviews from specific reviewers, teams, or both
You can request specific reviews from specific reviewers, teams, or both for a pull request.

::

Expand Down
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
CHANGELOG
=====================================
| June 12, 2024: feat: Support `issue_comment` event as trigger for actions `#754 <https://github.com/mergeability/mergeable/pull/754>`_
| June 10, 2024: fix: Docker image not working `#753 <https://github.com/mergeability/mergeable/pull/753>`_
| June 10, 2024: feat: publish multi arch docker image to dockerhub `#751 <https://github.com/mergeability/mergeable/pull/751>`_
| April 29, 2024: fix: Always allow assigning author `#744 <https://github.com/mergeability/mergeable/pull/744>`_
Expand Down
Loading