Skip to content

Commit 0967ca8

Browse files
danielsht86Daniel ShterembergDaniel ShterembergpjeAndrey Lobanovich
authored
Added output (#60)
* Added output * removed formatting changes * more formatting changes * Fix merge conflicts * Small test refactoring * tests are passing * Add a test * Add a small jest mock for addLabels. Not used. * Add tests for more cases * get rid of an unused jest mock * fix review points * rebuild + minor README fix * fix review points * update tests * fix formatting * add tests, fix bug * cleanup --------- Co-authored-by: Daniel Shteremberg <dshteremberg@labelbox.com> Co-authored-by: Daniel Shteremberg <Daniel@Daniel-Shterembergs-MacBook-Pro.local> Co-authored-by: Patrick Ellis <patrick.j.ellis@gmail.com> Co-authored-by: Andrey Lobanovich <andrei.lobanovich@akvelon.com>
1 parent 375538a commit 0967ca8

File tree

5 files changed

+99
-16
lines changed

5 files changed

+99
-16
lines changed

README.md

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,12 @@ jobs:
109109

110110
Various inputs are defined in [`action.yml`](action.yml) to let you configure the labeler:
111111

112-
| Name | Description | Default |
113-
| - | - | - |
114-
| `repo-token` | Token to use to authorize label changes. Typically the `GITHUB_TOKEN` secret, with `contents:read` and `pull-requests:write` access | `github.token` |
115-
| `configuration-path` | The path to the label configuration file | `.github/labeler.yml` |
116-
| `sync-labels` | Whether or not to remove labels when matching files are reverted or no longer changed by the PR | `false` |
117-
| `dot` | Whether or not to auto-include paths starting with dot (e.g. `.github`) | `false` |
112+
| Name | Description | Default |
113+
|----------------------|-------------------------------------------------------------------------------------------------|-----------------------|
114+
| `repo-token` | Token to use to authorize label changes. Typically the GITHUB_TOKEN secret | N/A |
115+
| `configuration-path` | The path to the label configuration file | `.github/labeler.yml` |
116+
| `sync-labels` | Whether or not to remove labels when matching files are reverted or no longer changed by the PR | `false` |
117+
| `dot` | Whether or not to auto-include paths starting with dot (e.g. `.github`) | `false` |
118118

119119
When `dot` is disabled and you want to include _all_ files in a folder:
120120

@@ -131,6 +131,44 @@ label1:
131131
- path/to/folder/**
132132
```
133133

134+
#### Outputs
135+
136+
Labeler provides the following outputs:
137+
138+
| Name | Description |
139+
|--------------|-----------------------------------------------------------|
140+
| `new-labels` | A comma-separated list of all new labels |
141+
| `all-labels` | A comma-separated list of all labels that the PR contains |
142+
143+
The following example performs steps based on the output of labeler:
144+
```yml
145+
name: "My workflow"
146+
on:
147+
- pull_request_target
148+
149+
jobs:
150+
triage:
151+
runs-on: ubuntu-latest
152+
permissions:
153+
contents: read
154+
pull-requests: write
155+
steps:
156+
- id: label-the-PR
157+
uses: actions/labeler@v3
158+
159+
- id: run-frontend-tests
160+
if: contains(fromJson(steps.label-the-PR.outputs.all-labels), 'frontend')
161+
run: |
162+
echo "Running frontend tests..."
163+
# Put your commands for running frontend tests here
164+
165+
- id: run-backend-tests
166+
if: contains(fromJson(steps.label-the-PR.outputs.all-labels), 'backend')
167+
run: |
168+
echo "Running backend tests..."
169+
# Put your commands for running backend tests here
170+
```
171+
134172
## Permissions
135173

136174
In order to add labels to pull requests, the GitHub labeler action requires

__tests__/main.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const reposMock = jest.spyOn(gh.rest.repos, 'getContent');
1313
const paginateMock = jest.spyOn(gh, 'paginate');
1414
const getPullMock = jest.spyOn(gh.rest.pulls, 'get');
1515
const coreWarningMock = jest.spyOn(core, 'warning');
16+
const setOutputSpy = jest.spyOn(core, 'setOutput');
1617

1718
const yamlFixtures = {
1819
'only_pdfs.yml': fs.readFileSync('__tests__/fixtures/only_pdfs.yml')
@@ -50,12 +51,21 @@ describe('run', () => {
5051
await run();
5152

5253
expect(setLabelsMock).toHaveBeenCalledTimes(1);
54+
5355
expect(setLabelsMock).toHaveBeenCalledWith({
5456
owner: 'monalisa',
5557
repo: 'helloworld',
5658
issue_number: 123,
5759
labels: ['touched-a-pdf-file']
5860
});
61+
expect(setOutputSpy).toHaveBeenCalledWith(
62+
'new-labels',
63+
'touched-a-pdf-file'
64+
);
65+
expect(setOutputSpy).toHaveBeenCalledWith(
66+
'all-labels',
67+
'touched-a-pdf-file'
68+
);
5969
});
6070

6171
it('(with dot: true) adds labels to PRs that match our glob patterns', async () => {
@@ -77,6 +87,14 @@ describe('run', () => {
7787
issue_number: 123,
7888
labels: ['touched-a-pdf-file']
7989
});
90+
expect(setOutputSpy).toHaveBeenCalledWith(
91+
'new-labels',
92+
'touched-a-pdf-file'
93+
);
94+
expect(setOutputSpy).toHaveBeenCalledWith(
95+
'all-labels',
96+
'touched-a-pdf-file'
97+
);
8098
});
8199

82100
it('(with dot: false) does not add labels to PRs that do not match our glob patterns', async () => {
@@ -92,6 +110,8 @@ describe('run', () => {
92110
await run();
93111

94112
expect(setLabelsMock).toHaveBeenCalledTimes(0);
113+
expect(setOutputSpy).toHaveBeenCalledWith('new-labels', '');
114+
expect(setOutputSpy).toHaveBeenCalledWith('all-labels', '');
95115
});
96116

97117
it('(with dot: true) does not add labels to PRs that do not match our glob patterns', async () => {
@@ -128,6 +148,8 @@ describe('run', () => {
128148
issue_number: 123,
129149
labels: ['manually-added']
130150
});
151+
expect(setOutputSpy).toHaveBeenCalledWith('new-labels', '');
152+
expect(setOutputSpy).toHaveBeenCalledWith('all-labels', 'manually-added');
131153
});
132154

133155
it('(with sync-labels: false) it issues no delete calls even when there are preexisting PR labels that no longer match the glob pattern', async () => {
@@ -148,6 +170,11 @@ describe('run', () => {
148170
await run();
149171

150172
expect(setLabelsMock).toHaveBeenCalledTimes(0);
173+
expect(setOutputSpy).toHaveBeenCalledWith('new-labels', '');
174+
expect(setOutputSpy).toHaveBeenCalledWith(
175+
'all-labels',
176+
'touched-a-pdf-file,manually-added'
177+
);
151178
});
152179

153180
it('(with sync-labels: false) it only logs the excess labels', async () => {
@@ -178,6 +205,9 @@ describe('run', () => {
178205
'Maximum of 100 labels allowed. Excess labels: touched-a-pdf-file',
179206
{title: 'Label limit for a PR exceeded'}
180207
);
208+
const allLabels: string = existingLabels.map(i => i.name).join(',');
209+
expect(setOutputSpy).toHaveBeenCalledWith('new-labels', '');
210+
expect(setOutputSpy).toHaveBeenCalledWith('all-labels', allLabels);
181211
});
182212
});
183213

action.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ inputs:
1919
default: false
2020
required: false
2121

22+
outputs:
23+
new-labels:
24+
description: 'A comma-separated list of all new labels'
25+
all-labels:
26+
description: 'A comma-separated list of all labels that the PR contains'
2227
runs:
2328
using: 'node16'
2429
main: 'dist/index.js'

dist/index.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ function run() {
6868
core.debug(`fetching changed files for pr #${prNumber}`);
6969
const changedFiles = yield getChangedFiles(client, prNumber);
7070
const labelGlobs = yield getLabelGlobs(client, configPath);
71-
const prLabels = pullRequest.labels.map(label => label.name);
72-
const allLabels = new Set(prLabels);
71+
const preexistingLabels = pullRequest.labels.map(l => l.name);
72+
const allLabels = new Set(preexistingLabels);
7373
for (const [label, globs] of labelGlobs.entries()) {
7474
core.debug(`processing ${label}`);
7575
if (checkGlobs(changedFiles, globs, dot)) {
@@ -79,12 +79,16 @@ function run() {
7979
allLabels.delete(label);
8080
}
8181
}
82-
const labels = [...allLabels].slice(0, GITHUB_MAX_LABELS);
82+
const labelsToAdd = [...allLabels].slice(0, GITHUB_MAX_LABELS);
8383
const excessLabels = [...allLabels].slice(GITHUB_MAX_LABELS);
8484
try {
85-
if (!isListEqual(prLabels, labels)) {
86-
yield setLabels(client, prNumber, labels);
85+
let newLabels = [];
86+
if (!isListEqual(labelsToAdd, preexistingLabels)) {
87+
yield setLabels(client, prNumber, labelsToAdd);
88+
newLabels = labelsToAdd.filter(l => !preexistingLabels.includes(l));
8789
}
90+
core.setOutput('new-labels', newLabels.join(','));
91+
core.setOutput('all-labels', labelsToAdd.join(','));
8892
if (excessLabels.length) {
8993
core.warning(`Maximum of ${GITHUB_MAX_LABELS} labels allowed. Excess labels: ${excessLabels.join(', ')}`, { title: 'Label limit for a PR exceeded' });
9094
}

src/labeler.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ export async function run() {
4343
configPath
4444
);
4545

46-
const prLabels: string[] = pullRequest.labels.map(label => label.name);
47-
const allLabels: Set<string> = new Set(prLabels);
46+
const preexistingLabels = pullRequest.labels.map(l => l.name);
47+
const allLabels: Set<string> = new Set<string>(preexistingLabels);
4848

4949
for (const [label, globs] of labelGlobs.entries()) {
5050
core.debug(`processing ${label}`);
@@ -55,14 +55,20 @@ export async function run() {
5555
}
5656
}
5757

58-
const labels = [...allLabels].slice(0, GITHUB_MAX_LABELS);
58+
const labelsToAdd = [...allLabels].slice(0, GITHUB_MAX_LABELS);
5959
const excessLabels = [...allLabels].slice(GITHUB_MAX_LABELS);
6060

6161
try {
62-
if (!isListEqual(prLabels, labels)) {
63-
await setLabels(client, prNumber, labels);
62+
let newLabels: string[] = [];
63+
64+
if (!isListEqual(labelsToAdd, preexistingLabels)) {
65+
await setLabels(client, prNumber, labelsToAdd);
66+
newLabels = labelsToAdd.filter(l => !preexistingLabels.includes(l));
6467
}
6568

69+
core.setOutput('new-labels', newLabels.join(','));
70+
core.setOutput('all-labels', labelsToAdd.join(','));
71+
6672
if (excessLabels.length) {
6773
core.warning(
6874
`Maximum of ${GITHUB_MAX_LABELS} labels allowed. Excess labels: ${excessLabels.join(

0 commit comments

Comments
 (0)