Skip to content

Commit 224d76f

Browse files
authored
Merge pull request #20 from github/add-labels-feature
Add Labels Feature
2 parents fda8056 + 8ce5016 commit 224d76f

File tree

8 files changed

+468
-272
lines changed

8 files changed

+468
-272
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ This Action is customizable so you can use it for your own purposes and it doesn
2424
| `review_required` | Whether or not reviews should be passing to combine the PR - can be `"true"` or `"false"` | `"false"` | `false` |
2525
| `ignore_label` | The label to ignore when combining PRs | `"nocombine"` | `true` |
2626
| `select_label` | The label which marks PRs that should be combined. Leave empty to consider all PRs. | `""` | `false` |
27+
| `labels` | A comma seperated list of labels to add to the combined PR - Example: `dependencies,combined-pr,etc` | `""` | `false` |
2728

2829
## Outputs 📤
2930

__tests__/main.test.js

+138
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ beforeEach(() => {
4242
process.env.INPUT_SELECT_LABEL = ''
4343
process.env.GITHUB_REPOSITORY = 'test-owner/test-repo'
4444
process.env.INPUT_MIN_COMBINE_NUMBER = '2'
45+
process.env.INPUT_LABELS = ''
4546

4647
jest.spyOn(github, 'getOctokit').mockImplementation(() => {
4748
return {
@@ -660,6 +661,143 @@ test('ignore_label and select_label can both be empty', async () => {
660661
expect(await run()).toBe('success')
661662
})
662663

664+
test('successfully runs the action and sets labels', async () => {
665+
jest.spyOn(github, 'getOctokit').mockImplementation(() => {
666+
return {
667+
paginate: jest.fn().mockImplementation(() => {
668+
return [
669+
buildPR(1, 'dependabot-1', ['question']),
670+
buildPR(2, 'dependabot-2'),
671+
buildPR(3, 'dependabot-3', ['nocombine']),
672+
buildPR(4, 'dependabot-4'),
673+
buildPR(5, 'dependabot-5'),
674+
buildPR(6, 'dependabot-6'),
675+
buildPR(7, 'fix-package')
676+
]
677+
}),
678+
graphql: jest.fn().mockImplementation((_query, params) => {
679+
switch (params.pull_number) {
680+
case 1:
681+
case 2:
682+
case 3:
683+
return buildStatusResponse('APPROVED', 'SUCCESS')
684+
case 4:
685+
return buildStatusResponse('APPROVED', 'FAILURE')
686+
case 5:
687+
return buildStatusResponse(null, 'SUCCESS')
688+
case 6:
689+
return buildStatusResponse('REVIEW_REQUIRED', 'SUCCESS')
690+
default:
691+
throw new Error(
692+
`params.pull_number of ${params.pull_number} is not configured.`
693+
)
694+
}
695+
}),
696+
rest: {
697+
issues: {
698+
addLabels: jest.fn().mockReturnValueOnce({
699+
data: {}
700+
})
701+
},
702+
git: {
703+
createRef: jest.fn().mockReturnValueOnce({
704+
data: {}
705+
})
706+
},
707+
repos: {
708+
// mock the first value of merge to be a success and the second to be an exception
709+
merge: jest
710+
.fn()
711+
.mockReturnValueOnce({
712+
data: {
713+
merged: true
714+
}
715+
})
716+
.mockImplementationOnce(() => {
717+
throw new Error('merge error')
718+
})
719+
},
720+
pulls: {
721+
create: jest.fn().mockReturnValueOnce({
722+
data: {
723+
number: 100,
724+
html_url: 'https://github.com/test-owner/test-repo/pull/100'
725+
}
726+
})
727+
}
728+
}
729+
}
730+
})
731+
732+
process.env.INPUT_REVIEW_REQUIRED = 'true'
733+
process.env.INPUT_LABELS = 'label1,label2, label3'
734+
expect(await run()).toBe('success')
735+
expect(infoMock).toHaveBeenCalledWith('Pull for branch: dependabot-1')
736+
expect(infoMock).toHaveBeenCalledWith('Branch matched prefix: dependabot-1')
737+
expect(infoMock).toHaveBeenCalledWith('Checking green status: dependabot-1')
738+
expect(infoMock).toHaveBeenCalledWith('Validating status: SUCCESS')
739+
expect(infoMock).toHaveBeenCalledWith('Validating review decision: APPROVED')
740+
expect(infoMock).toHaveBeenCalledWith('Branch dependabot-1 is approved')
741+
expect(infoMock).toHaveBeenCalledWith('Pull for branch: dependabot-2')
742+
expect(infoMock).toHaveBeenCalledWith('Branch matched prefix: dependabot-2')
743+
expect(infoMock).toHaveBeenCalledWith('Checking green status: dependabot-2')
744+
expect(infoMock).toHaveBeenCalledWith('Validating status: SUCCESS')
745+
expect(infoMock).toHaveBeenCalledWith('Validating review decision: APPROVED')
746+
expect(infoMock).toHaveBeenCalledWith('Branch dependabot-2 is approved')
747+
expect(infoMock).toHaveBeenCalledWith('Pull for branch: dependabot-3')
748+
expect(infoMock).toHaveBeenCalledWith('Branch matched prefix: dependabot-3')
749+
expect(infoMock).toHaveBeenCalledWith('Pull for branch: dependabot-4')
750+
expect(infoMock).toHaveBeenCalledWith('Branch matched prefix: dependabot-4')
751+
expect(infoMock).toHaveBeenCalledWith('Checking green status: dependabot-4')
752+
expect(infoMock).toHaveBeenCalledWith('Validating status: FAILURE')
753+
expect(infoMock).toHaveBeenCalledWith(
754+
'Discarding dependabot-4 with status FAILURE'
755+
)
756+
expect(infoMock).toHaveBeenCalledWith('Branch matched prefix: dependabot-5')
757+
expect(infoMock).toHaveBeenCalledWith('Checking green status: dependabot-5')
758+
expect(infoMock).toHaveBeenCalledWith('Validating status: SUCCESS')
759+
expect(infoMock).toHaveBeenCalledWith('Validating review decision: null')
760+
expect(infoMock).toHaveBeenCalledWith(
761+
'Branch dependabot-5 has no required reviewers - OK'
762+
)
763+
expect(infoMock).toHaveBeenCalledWith('Checking labels: dependabot-1')
764+
expect(infoMock).toHaveBeenCalledWith('Checking ignore_label for: question')
765+
expect(infoMock).toHaveBeenCalledWith('Adding branch to array: dependabot-1')
766+
expect(infoMock).toHaveBeenCalledWith('Checking labels: dependabot-2')
767+
expect(infoMock).toHaveBeenCalledWith('Adding branch to array: dependabot-2')
768+
expect(infoMock).toHaveBeenCalledWith('Checking labels: dependabot-3')
769+
expect(infoMock).toHaveBeenCalledWith('Checking ignore_label for: nocombine')
770+
expect(infoMock).toHaveBeenCalledWith(
771+
'Discarding dependabot-3 with label nocombine because it matches ignore_label'
772+
)
773+
expect(infoMock).toHaveBeenCalledWith('Checking labels: dependabot-4')
774+
expect(infoMock).toHaveBeenCalledWith('Checking labels: dependabot-5')
775+
expect(infoMock).toHaveBeenCalledWith('Checking labels: dependabot-6')
776+
expect(infoMock).toHaveBeenCalledWith('Merged branch dependabot-1')
777+
expect(warningMock).toHaveBeenCalledWith(
778+
'Failed to merge branch dependabot-2'
779+
)
780+
expect(infoMock).toHaveBeenCalledWith('Merged branch dependabot-5')
781+
expect(infoMock).toHaveBeenCalledWith('Creating combined PR')
782+
expect(debugMock).toHaveBeenCalledWith(
783+
'PR body: # Combined PRs ➡️📦⬅️\n\n✅ The following pull requests have been successfully combined on this PR:\n- #1 Update dependency 1\n- #5 Update dependency 5\n\n⚠️ The following PRs were left out due to merge conflicts:\n- #2 Update dependency 2\n\n> This PR was created by the [`github/combine-prs`](https://github.com/github/combine-prs) action'
784+
)
785+
786+
expect(infoMock).toHaveBeenCalledWith(
787+
`Adding labels to combined PR: label1,label2,label3`
788+
)
789+
790+
expect(infoMock).toHaveBeenCalledWith(
791+
'Combined PR url: https://github.com/test-owner/test-repo/pull/100'
792+
)
793+
expect(infoMock).toHaveBeenCalledWith('Combined PR number: 100')
794+
expect(setOutputMock).toHaveBeenCalledWith('pr_number', 100)
795+
expect(setOutputMock).toHaveBeenCalledWith(
796+
'pr_url',
797+
'https://github.com/test-owner/test-repo/pull/100'
798+
)
799+
})
800+
663801
function buildStatusResponse(reviewDecision, ciStatus) {
664802
return {
665803
repository: {

action.yml

+4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ inputs:
4949
description: The label marking PRs that should be combined
5050
required: false
5151
default: ""
52+
labels:
53+
description: A comma seperated list of labels to add to the combined PR
54+
required: false
55+
default: ""
5256
outputs:
5357
pr_url:
5458
description: The pull request URL if a PR was created

0 commit comments

Comments
 (0)