@opentermsarchive/engine 2.3.2 → 2.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/reporter/github.js +65 -27
- package/src/reporter/github.test.js +131 -126
- package/src/reporter/index.js +4 -0
package/package.json
CHANGED
package/src/reporter/github.js
CHANGED
|
@@ -28,6 +28,24 @@ export default class GitHub {
|
|
|
28
28
|
const [ owner, repo ] = repository.split('/');
|
|
29
29
|
|
|
30
30
|
this.commonParams = { owner, repo };
|
|
31
|
+
|
|
32
|
+
this.issuesCache = new Map();
|
|
33
|
+
this._issuesPromise = null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
get issues() {
|
|
37
|
+
if (!this._issuesPromise) {
|
|
38
|
+
logger.info('Loading issues from GitHub…');
|
|
39
|
+
this._issuesPromise = this.loadAllIssues();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return this._issuesPromise;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
clearCache() {
|
|
46
|
+
this.issuesCache.clear();
|
|
47
|
+
this._issuesPromise = null;
|
|
48
|
+
logger.info('Issues cache cleared');
|
|
31
49
|
}
|
|
32
50
|
|
|
33
51
|
async initialize() {
|
|
@@ -53,6 +71,33 @@ export default class GitHub {
|
|
|
53
71
|
}
|
|
54
72
|
}
|
|
55
73
|
|
|
74
|
+
async loadAllIssues() {
|
|
75
|
+
try {
|
|
76
|
+
const issues = await this.octokit.paginate('GET /repos/{owner}/{repo}/issues', {
|
|
77
|
+
...this.commonParams,
|
|
78
|
+
state: GitHub.ISSUE_STATE_ALL,
|
|
79
|
+
per_page: 100,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const onlyIssues = issues.filter(issue => !issue.pull_request); // Filter out pull requests since GitHub treats them as a special type of issue
|
|
83
|
+
|
|
84
|
+
onlyIssues.forEach(issue => {
|
|
85
|
+
const cachedIssue = this.issuesCache.get(issue.title);
|
|
86
|
+
|
|
87
|
+
if (!cachedIssue || new Date(issue.created_at) < new Date(cachedIssue.created_at)) { // Only work on the oldest issue if there are duplicates, in order to consolidate the longest history possible
|
|
88
|
+
this.issuesCache.set(issue.title, issue);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
logger.info(`Cached ${onlyIssues.length} issues from the GitHub repository`);
|
|
93
|
+
|
|
94
|
+
return this.issuesCache;
|
|
95
|
+
} catch (error) {
|
|
96
|
+
logger.error(`Failed to load issues: ${error.message}`);
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
56
101
|
async getRepositoryLabels() {
|
|
57
102
|
const { data: labels } = await this.octokit.request('GET /repos/{owner}/{repo}/labels', { ...this.commonParams });
|
|
58
103
|
|
|
@@ -68,6 +113,10 @@ export default class GitHub {
|
|
|
68
113
|
});
|
|
69
114
|
}
|
|
70
115
|
|
|
116
|
+
async getIssue(title) {
|
|
117
|
+
return (await this.issues).get(title);
|
|
118
|
+
}
|
|
119
|
+
|
|
71
120
|
async createIssue({ title, description: body, labels }) {
|
|
72
121
|
const { data: issue } = await this.octokit.request('POST /repos/{owner}/{repo}/issues', {
|
|
73
122
|
...this.commonParams,
|
|
@@ -76,6 +125,8 @@ export default class GitHub {
|
|
|
76
125
|
labels,
|
|
77
126
|
});
|
|
78
127
|
|
|
128
|
+
this.issuesCache.set(issue.title, issue);
|
|
129
|
+
|
|
79
130
|
return issue;
|
|
80
131
|
}
|
|
81
132
|
|
|
@@ -87,19 +138,9 @@ export default class GitHub {
|
|
|
87
138
|
labels,
|
|
88
139
|
});
|
|
89
140
|
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
async getIssue({ title, ...searchParams }) {
|
|
94
|
-
const issues = await this.octokit.paginate('GET /repos/{owner}/{repo}/issues', {
|
|
95
|
-
...this.commonParams,
|
|
96
|
-
per_page: 100,
|
|
97
|
-
...searchParams,
|
|
98
|
-
}, response => response.data);
|
|
99
|
-
|
|
100
|
-
const [issue] = issues.filter(item => item.title === title); // Since only one is expected, use the first one
|
|
141
|
+
this.issuesCache.set(updatedIssue.title, updatedIssue);
|
|
101
142
|
|
|
102
|
-
return
|
|
143
|
+
return updatedIssue;
|
|
103
144
|
}
|
|
104
145
|
|
|
105
146
|
async addCommentToIssue({ issue, comment: body }) {
|
|
@@ -114,25 +155,25 @@ export default class GitHub {
|
|
|
114
155
|
|
|
115
156
|
async closeIssueWithCommentIfExists({ title, comment }) {
|
|
116
157
|
try {
|
|
117
|
-
const
|
|
158
|
+
const issue = await this.getIssue(title);
|
|
118
159
|
|
|
119
|
-
if (!
|
|
160
|
+
if (!issue || issue.state == GitHub.ISSUE_STATE_CLOSED) {
|
|
120
161
|
return;
|
|
121
162
|
}
|
|
122
163
|
|
|
123
|
-
await this.addCommentToIssue({ issue
|
|
124
|
-
|
|
164
|
+
await this.addCommentToIssue({ issue, comment });
|
|
165
|
+
|
|
166
|
+
const updatedIssue = await this.updateIssue(issue, { state: GitHub.ISSUE_STATE_CLOSED });
|
|
125
167
|
|
|
126
|
-
|
|
127
|
-
logger.info(`Closed issue #${openedIssue.number}: ${openedIssue.html_url}`);
|
|
168
|
+
logger.info(`Closed issue with comment #${updatedIssue.number}: ${updatedIssue.html_url}`);
|
|
128
169
|
} catch (error) {
|
|
129
|
-
logger.error(`Failed to
|
|
170
|
+
logger.error(`Failed to close issue with comment "${title}": ${error.stack}`);
|
|
130
171
|
}
|
|
131
172
|
}
|
|
132
173
|
|
|
133
174
|
async createOrUpdateIssue({ title, description, label }) {
|
|
134
175
|
try {
|
|
135
|
-
const issue = await this.getIssue(
|
|
176
|
+
const issue = await this.getIssue(title);
|
|
136
177
|
|
|
137
178
|
if (!issue) {
|
|
138
179
|
const createdIssue = await this.createIssue({ title, description, labels: [label] });
|
|
@@ -148,16 +189,13 @@ export default class GitHub {
|
|
|
148
189
|
return;
|
|
149
190
|
}
|
|
150
191
|
|
|
151
|
-
await this.updateIssue(issue, {
|
|
152
|
-
|
|
153
|
-
labels: [ label, ...labelsNotManagedToKeep ],
|
|
154
|
-
});
|
|
155
|
-
logger.info(`Updated issue #${issue.number}: ${issue.html_url}`);
|
|
192
|
+
const updatedIssue = await this.updateIssue(issue, { state: GitHub.ISSUE_STATE_OPEN, labels: [ label, ...labelsNotManagedToKeep ] });
|
|
193
|
+
|
|
156
194
|
await this.addCommentToIssue({ issue, comment: description });
|
|
157
195
|
|
|
158
|
-
logger.info(`
|
|
196
|
+
logger.info(`Updated issue with comment #${updatedIssue.number}: ${updatedIssue.html_url}`);
|
|
159
197
|
} catch (error) {
|
|
160
|
-
logger.error(`Failed to update issue "${title}": ${error.
|
|
198
|
+
logger.error(`Failed to update issue "${title}": ${error.stack}`);
|
|
161
199
|
}
|
|
162
200
|
}
|
|
163
201
|
}
|
|
@@ -12,10 +12,17 @@ describe('GitHub', function () {
|
|
|
12
12
|
|
|
13
13
|
let MANAGED_LABELS;
|
|
14
14
|
let github;
|
|
15
|
+
const EXISTING_OPEN_ISSUE = { number: 1, title: 'Opened issue', description: 'Issue description', state: GitHub.ISSUE_STATE_OPEN, labels: [{ name: 'location' }] };
|
|
16
|
+
const EXISTING_CLOSED_ISSUE = { number: 2, title: 'Closed issue', description: 'Issue description', state: GitHub.ISSUE_STATE_CLOSED, labels: [{ name: '403' }] };
|
|
15
17
|
|
|
16
|
-
before(() => {
|
|
18
|
+
before(async () => {
|
|
17
19
|
MANAGED_LABELS = require('./labels.json');
|
|
18
20
|
github = new GitHub('owner/repo');
|
|
21
|
+
nock('https://api.github.com')
|
|
22
|
+
.get('/repos/owner/repo/issues')
|
|
23
|
+
.query(true)
|
|
24
|
+
.reply(200, [ EXISTING_OPEN_ISSUE, EXISTING_CLOSED_ISSUE ]);
|
|
25
|
+
await github.clearCache();
|
|
19
26
|
});
|
|
20
27
|
|
|
21
28
|
describe('#initialize', () => {
|
|
@@ -71,77 +78,88 @@ describe('GitHub', function () {
|
|
|
71
78
|
});
|
|
72
79
|
|
|
73
80
|
describe('#createLabel', () => {
|
|
74
|
-
let scope;
|
|
75
81
|
const LABEL = { name: 'new_label', color: 'ffffff' };
|
|
76
82
|
|
|
77
|
-
|
|
78
|
-
|
|
83
|
+
afterEach(nock.cleanAll);
|
|
84
|
+
|
|
85
|
+
it('creates the new label successfully', async () => {
|
|
86
|
+
const scope = nock('https://api.github.com')
|
|
79
87
|
.post('/repos/owner/repo/labels', body => body.name === LABEL.name)
|
|
80
88
|
.reply(200, LABEL);
|
|
81
89
|
|
|
82
90
|
await github.createLabel(LABEL);
|
|
91
|
+
expect(scope.isDone()).to.be.true;
|
|
83
92
|
});
|
|
84
93
|
|
|
85
|
-
|
|
94
|
+
it('throws an error when creating a label fails', async () => {
|
|
95
|
+
nock('https://api.github.com')
|
|
96
|
+
.post('/repos/owner/repo/labels')
|
|
97
|
+
.reply(400, { message: 'Bad Request' });
|
|
86
98
|
|
|
87
|
-
|
|
88
|
-
expect(scope.isDone()).to.be.true;
|
|
99
|
+
await expect(github.createLabel(LABEL)).to.be.rejected;
|
|
89
100
|
});
|
|
90
101
|
});
|
|
91
102
|
|
|
92
103
|
describe('#createIssue', () => {
|
|
93
104
|
let scope;
|
|
94
105
|
let result;
|
|
106
|
+
|
|
95
107
|
const ISSUE = {
|
|
96
108
|
title: 'New Issue',
|
|
97
109
|
description: 'Description of the new issue',
|
|
98
|
-
labels: ['bug'],
|
|
110
|
+
labels: [{ name: 'bug' }],
|
|
99
111
|
};
|
|
100
112
|
const CREATED_ISSUE = { number: 123, ...ISSUE };
|
|
101
113
|
|
|
102
114
|
before(async () => {
|
|
103
115
|
scope = nock('https://api.github.com')
|
|
104
|
-
.post('/repos/owner/repo/issues', request =>
|
|
116
|
+
.post('/repos/owner/repo/issues', request =>
|
|
117
|
+
request.title === ISSUE.title && request.body === ISSUE.description && request.labels[0].name === ISSUE.labels[0].name)
|
|
105
118
|
.reply(200, CREATED_ISSUE);
|
|
106
119
|
|
|
107
120
|
result = await github.createIssue(ISSUE);
|
|
108
121
|
});
|
|
109
122
|
|
|
110
|
-
after(
|
|
123
|
+
after(() => {
|
|
124
|
+
nock.cleanAll();
|
|
125
|
+
github.issuesCache.delete(ISSUE.title);
|
|
126
|
+
});
|
|
111
127
|
|
|
112
128
|
it('creates the new issue', () => {
|
|
113
129
|
expect(scope.isDone()).to.be.true;
|
|
114
130
|
});
|
|
115
131
|
|
|
116
|
-
it('returns the created issue', () => {
|
|
132
|
+
it('returns the newly created issue', () => {
|
|
117
133
|
expect(result).to.deep.equal(CREATED_ISSUE);
|
|
118
134
|
});
|
|
119
|
-
});
|
|
120
135
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
136
|
+
it('throws error when creating issue fails', async () => {
|
|
137
|
+
nock('https://api.github.com')
|
|
138
|
+
.post('/repos/owner/repo/issues')
|
|
139
|
+
.reply(400, { message: 'Bad Request' });
|
|
124
140
|
|
|
125
|
-
|
|
126
|
-
|
|
141
|
+
await expect(github.createIssue(ISSUE)).to.be.rejected;
|
|
142
|
+
});
|
|
143
|
+
});
|
|
127
144
|
|
|
128
|
-
|
|
129
|
-
|
|
145
|
+
describe('#getIssue', () => {
|
|
146
|
+
before(() => {
|
|
147
|
+
nock('https://api.github.com')
|
|
130
148
|
.get('/repos/owner/repo/issues')
|
|
131
149
|
.query(true)
|
|
132
|
-
.reply(200, [
|
|
133
|
-
|
|
134
|
-
result = await github.getIssue({ title: ISSUE.title });
|
|
150
|
+
.reply(200, [ EXISTING_OPEN_ISSUE, EXISTING_CLOSED_ISSUE ]);
|
|
135
151
|
});
|
|
136
152
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
153
|
+
context('when the issue exists in the cache', () => {
|
|
154
|
+
it('returns the cached issue', async () => {
|
|
155
|
+
expect(await github.getIssue(EXISTING_OPEN_ISSUE.title)).to.deep.equal(EXISTING_OPEN_ISSUE);
|
|
156
|
+
});
|
|
141
157
|
});
|
|
142
158
|
|
|
143
|
-
|
|
144
|
-
|
|
159
|
+
context('when the issue does not exist in the cache', () => {
|
|
160
|
+
it('returns undefined', async () => {
|
|
161
|
+
expect(await github.getIssue('Non-existent Issue')).to.be.undefined;
|
|
162
|
+
});
|
|
145
163
|
});
|
|
146
164
|
});
|
|
147
165
|
|
|
@@ -163,35 +181,33 @@ describe('GitHub', function () {
|
|
|
163
181
|
it('adds the comment to the issue', () => {
|
|
164
182
|
expect(scope.isDone()).to.be.true;
|
|
165
183
|
});
|
|
184
|
+
|
|
185
|
+
it('throws an error when adding a comment fails', async () => {
|
|
186
|
+
nock('https://api.github.com')
|
|
187
|
+
.post(`/repos/owner/repo/issues/${ISSUE_NUMBER}/comments`)
|
|
188
|
+
.reply(400, { message: 'Bad Request' });
|
|
189
|
+
|
|
190
|
+
await expect(github.addCommentToIssue({ issue: { number: ISSUE_NUMBER }, comment: COMMENT })).to.be.rejected;
|
|
191
|
+
});
|
|
166
192
|
});
|
|
167
193
|
|
|
168
194
|
describe('#closeIssueWithCommentIfExists', () => {
|
|
169
195
|
after(nock.cleanAll);
|
|
170
196
|
|
|
171
197
|
context('when the issue exists and is open', () => {
|
|
172
|
-
const ISSUE = {
|
|
173
|
-
number: 123,
|
|
174
|
-
title: 'Open Issue',
|
|
175
|
-
state: GitHub.ISSUE_STATE_OPEN,
|
|
176
|
-
};
|
|
177
198
|
let addCommentScope;
|
|
178
199
|
let closeIssueScope;
|
|
179
200
|
|
|
180
201
|
before(async () => {
|
|
181
|
-
nock('https://api.github.com')
|
|
182
|
-
.get('/repos/owner/repo/issues')
|
|
183
|
-
.query(true)
|
|
184
|
-
.reply(200, [ISSUE]);
|
|
185
|
-
|
|
186
202
|
addCommentScope = nock('https://api.github.com')
|
|
187
|
-
.post(`/repos/owner/repo/issues/${
|
|
203
|
+
.post(`/repos/owner/repo/issues/${EXISTING_OPEN_ISSUE.number}/comments`)
|
|
188
204
|
.reply(200);
|
|
189
205
|
|
|
190
206
|
closeIssueScope = nock('https://api.github.com')
|
|
191
|
-
.patch(`/repos/owner/repo/issues/${
|
|
207
|
+
.patch(`/repos/owner/repo/issues/${EXISTING_OPEN_ISSUE.number}`, { state: GitHub.ISSUE_STATE_CLOSED })
|
|
192
208
|
.reply(200);
|
|
193
209
|
|
|
194
|
-
await github.closeIssueWithCommentIfExists({ title:
|
|
210
|
+
await github.closeIssueWithCommentIfExists({ title: EXISTING_OPEN_ISSUE.title, comment: 'Closing comment' });
|
|
195
211
|
});
|
|
196
212
|
|
|
197
213
|
it('adds comment to the issue', () => {
|
|
@@ -204,29 +220,19 @@ describe('GitHub', function () {
|
|
|
204
220
|
});
|
|
205
221
|
|
|
206
222
|
context('when the issue exists and is closed', () => {
|
|
207
|
-
const ISSUE = {
|
|
208
|
-
number: 123,
|
|
209
|
-
title: 'Closed Issue',
|
|
210
|
-
state: GitHub.ISSUE_STATE_CLOSED,
|
|
211
|
-
};
|
|
212
223
|
let addCommentScope;
|
|
213
224
|
let closeIssueScope;
|
|
214
225
|
|
|
215
226
|
before(async () => {
|
|
216
|
-
nock('https://api.github.com')
|
|
217
|
-
.get('/repos/owner/repo/issues')
|
|
218
|
-
.query(true)
|
|
219
|
-
.reply(200, []);
|
|
220
|
-
|
|
221
227
|
addCommentScope = nock('https://api.github.com')
|
|
222
|
-
.post(`/repos/owner/repo/issues/${
|
|
228
|
+
.post(`/repos/owner/repo/issues/${EXISTING_CLOSED_ISSUE.number}/comments`)
|
|
223
229
|
.reply(200);
|
|
224
230
|
|
|
225
231
|
closeIssueScope = nock('https://api.github.com')
|
|
226
|
-
.patch(`/repos/owner/repo/issues/${
|
|
232
|
+
.patch(`/repos/owner/repo/issues/${EXISTING_CLOSED_ISSUE.number}`, { state: GitHub.ISSUE_STATE_CLOSED })
|
|
227
233
|
.reply(200);
|
|
228
234
|
|
|
229
|
-
await github.closeIssueWithCommentIfExists({ title:
|
|
235
|
+
await github.closeIssueWithCommentIfExists({ title: EXISTING_CLOSED_ISSUE.title, comment: 'Closing comment' });
|
|
230
236
|
});
|
|
231
237
|
|
|
232
238
|
it('does not add comment', () => {
|
|
@@ -243,11 +249,6 @@ describe('GitHub', function () {
|
|
|
243
249
|
let closeIssueScope;
|
|
244
250
|
|
|
245
251
|
before(async () => {
|
|
246
|
-
nock('https://api.github.com')
|
|
247
|
-
.get('/repos/owner/repo/issues')
|
|
248
|
-
.query(true)
|
|
249
|
-
.reply(200, []);
|
|
250
|
-
|
|
251
252
|
addCommentScope = nock('https://api.github.com')
|
|
252
253
|
.post(/\/repos\/owner\/repo\/issues\/\d+\/comments/)
|
|
253
254
|
.reply(200);
|
|
@@ -270,12 +271,8 @@ describe('GitHub', function () {
|
|
|
270
271
|
});
|
|
271
272
|
|
|
272
273
|
describe('#createOrUpdateIssue', () => {
|
|
273
|
-
before(
|
|
274
|
-
|
|
275
|
-
.get('/repos/owner/repo/labels')
|
|
276
|
-
.reply(200, MANAGED_LABELS);
|
|
277
|
-
|
|
278
|
-
await github.initialize();
|
|
274
|
+
before(() => {
|
|
275
|
+
github.MANAGED_LABELS = require('./labels.json');
|
|
279
276
|
});
|
|
280
277
|
|
|
281
278
|
context('when the issue does not exist', () => {
|
|
@@ -287,11 +284,6 @@ describe('GitHub', function () {
|
|
|
287
284
|
};
|
|
288
285
|
|
|
289
286
|
before(async () => {
|
|
290
|
-
nock('https://api.github.com')
|
|
291
|
-
.get('/repos/owner/repo/issues')
|
|
292
|
-
.query(true)
|
|
293
|
-
.reply(200, []); // Simulate that there is no issues on the repository
|
|
294
|
-
|
|
295
287
|
createIssueScope = nock('https://api.github.com')
|
|
296
288
|
.post('/repos/owner/repo/issues', {
|
|
297
289
|
title: ISSUE_TO_CREATE.title,
|
|
@@ -303,48 +295,38 @@ describe('GitHub', function () {
|
|
|
303
295
|
await github.createOrUpdateIssue(ISSUE_TO_CREATE);
|
|
304
296
|
});
|
|
305
297
|
|
|
298
|
+
afterEach(() => {
|
|
299
|
+
github.issuesCache.delete(ISSUE_TO_CREATE.title);
|
|
300
|
+
});
|
|
301
|
+
|
|
306
302
|
it('creates the issue', () => {
|
|
307
303
|
expect(createIssueScope.isDone()).to.be.true;
|
|
308
304
|
});
|
|
309
305
|
});
|
|
310
306
|
|
|
311
307
|
context('when the issue already exists', () => {
|
|
312
|
-
const ISSUE = {
|
|
313
|
-
title: 'Existing Issue',
|
|
314
|
-
description: 'New comment',
|
|
315
|
-
label: 'location',
|
|
316
|
-
};
|
|
317
|
-
|
|
318
308
|
context('when issue is closed', () => {
|
|
319
309
|
let updateIssueScope;
|
|
320
310
|
let addCommentScope;
|
|
321
311
|
|
|
322
|
-
const GITHUB_RESPONSE_FOR_EXISTING_ISSUE = {
|
|
323
|
-
number: 123,
|
|
324
|
-
title: ISSUE.title,
|
|
325
|
-
description: ISSUE.description,
|
|
326
|
-
labels: [{ name: 'selectors' }],
|
|
327
|
-
state: GitHub.ISSUE_STATE_CLOSED,
|
|
328
|
-
};
|
|
329
|
-
|
|
330
312
|
before(async () => {
|
|
331
|
-
nock('https://api.github.com')
|
|
332
|
-
.get('/repos/owner/repo/issues')
|
|
333
|
-
.query(true)
|
|
334
|
-
.reply(200, [GITHUB_RESPONSE_FOR_EXISTING_ISSUE]);
|
|
335
|
-
|
|
336
313
|
updateIssueScope = nock('https://api.github.com')
|
|
337
|
-
.patch(`/repos/owner/repo/issues/${
|
|
314
|
+
.patch(`/repos/owner/repo/issues/${EXISTING_CLOSED_ISSUE.number}`, { state: GitHub.ISSUE_STATE_OPEN, labels: ['location'] })
|
|
338
315
|
.reply(200);
|
|
339
316
|
|
|
340
317
|
addCommentScope = nock('https://api.github.com')
|
|
341
|
-
.post(`/repos/owner/repo/issues/${
|
|
318
|
+
.post(`/repos/owner/repo/issues/${EXISTING_CLOSED_ISSUE.number}/comments`, { body: EXISTING_CLOSED_ISSUE.description })
|
|
342
319
|
.reply(200);
|
|
343
320
|
|
|
344
|
-
await github.createOrUpdateIssue(
|
|
321
|
+
await github.createOrUpdateIssue({ title: EXISTING_CLOSED_ISSUE.title, description: EXISTING_CLOSED_ISSUE.description, label: 'location' });
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
after(() => {
|
|
325
|
+
github.issuesCache.delete(EXISTING_CLOSED_ISSUE.title);
|
|
326
|
+
github.issuesCache.set(EXISTING_CLOSED_ISSUE.title, EXISTING_CLOSED_ISSUE);
|
|
345
327
|
});
|
|
346
328
|
|
|
347
|
-
it('reopens the issue and its labels', () => {
|
|
329
|
+
it('reopens the issue and updates its labels', () => {
|
|
348
330
|
expect(updateIssueScope.isDone()).to.be.true;
|
|
349
331
|
});
|
|
350
332
|
|
|
@@ -354,40 +336,63 @@ describe('GitHub', function () {
|
|
|
354
336
|
});
|
|
355
337
|
|
|
356
338
|
context('when issue is already opened', () => {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
.
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
.
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
.
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
it("updates the issue's labels", () => {
|
|
386
|
-
expect(updateIssueScope.isDone()).to.be.true;
|
|
339
|
+
context('when the reason is new', () => {
|
|
340
|
+
let addCommentScope;
|
|
341
|
+
let updateIssueScope;
|
|
342
|
+
|
|
343
|
+
before(async () => {
|
|
344
|
+
updateIssueScope = nock('https://api.github.com')
|
|
345
|
+
.patch(`/repos/owner/repo/issues/${EXISTING_OPEN_ISSUE.number}`, { state: GitHub.ISSUE_STATE_OPEN, labels: ['404'] })
|
|
346
|
+
.reply(200);
|
|
347
|
+
|
|
348
|
+
addCommentScope = nock('https://api.github.com')
|
|
349
|
+
.post(`/repos/owner/repo/issues/${EXISTING_OPEN_ISSUE.number}/comments`, { body: EXISTING_OPEN_ISSUE.description })
|
|
350
|
+
.reply(200);
|
|
351
|
+
|
|
352
|
+
await github.createOrUpdateIssue({ title: EXISTING_OPEN_ISSUE.title, description: EXISTING_OPEN_ISSUE.description, label: '404' });
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
after(() => {
|
|
356
|
+
github.issuesCache.delete(EXISTING_OPEN_ISSUE.title);
|
|
357
|
+
github.issuesCache.set(EXISTING_OPEN_ISSUE.title, EXISTING_OPEN_ISSUE);
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
it("updates the issue's labels", () => {
|
|
361
|
+
expect(updateIssueScope.isDone()).to.be.true;
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
it('adds a comment to the issue', () => {
|
|
365
|
+
expect(addCommentScope.isDone()).to.be.true;
|
|
366
|
+
});
|
|
387
367
|
});
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
368
|
+
context('when the reason did not change', () => {
|
|
369
|
+
let addCommentScope;
|
|
370
|
+
let updateIssueScope;
|
|
371
|
+
|
|
372
|
+
before(async () => {
|
|
373
|
+
updateIssueScope = nock('https://api.github.com')
|
|
374
|
+
.patch(`/repos/owner/repo/issues/${EXISTING_OPEN_ISSUE.number}`, { state: GitHub.ISSUE_STATE_OPEN, labels: EXISTING_OPEN_ISSUE.labels })
|
|
375
|
+
.reply(200);
|
|
376
|
+
|
|
377
|
+
addCommentScope = nock('https://api.github.com')
|
|
378
|
+
.post(`/repos/owner/repo/issues/${EXISTING_OPEN_ISSUE.number}/comments`, { body: EXISTING_OPEN_ISSUE.description })
|
|
379
|
+
.reply(200);
|
|
380
|
+
|
|
381
|
+
await github.createOrUpdateIssue({ title: EXISTING_OPEN_ISSUE.title, description: EXISTING_OPEN_ISSUE.description, label: EXISTING_OPEN_ISSUE.labels[0].name });
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
after(() => {
|
|
385
|
+
github.issuesCache.delete(EXISTING_OPEN_ISSUE.title);
|
|
386
|
+
github.issuesCache.set(EXISTING_OPEN_ISSUE.title, EXISTING_OPEN_ISSUE);
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
it('does not attempt to updates the issue’s labels', () => {
|
|
390
|
+
expect(updateIssueScope.isDone()).to.be.false;
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
it('does not attempt to add any comment to the issue', () => {
|
|
394
|
+
expect(addCommentScope.isDone()).to.be.false;
|
|
395
|
+
});
|
|
391
396
|
});
|
|
392
397
|
});
|
|
393
398
|
});
|
package/src/reporter/index.js
CHANGED
|
@@ -49,6 +49,10 @@ export default class Reporter {
|
|
|
49
49
|
return this.github.initialize();
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
onTrackingStarted() {
|
|
53
|
+
return this.github.clearCache();
|
|
54
|
+
}
|
|
55
|
+
|
|
52
56
|
async onVersionRecorded(version) {
|
|
53
57
|
await this.github.closeIssueWithCommentIfExists({
|
|
54
58
|
title: Reporter.generateTitleID(version.serviceId, version.termsType),
|