Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5f6f311

Browse files
authored
fix(operations): fail fast the current batch to respect the operations limit (#474)
* fix(operations): fail fast the current batch to respect the operations limitInstead of processing an entire batch of 100 issues before checking the operations left, simply do it before processing an issue so that we respect as expected the limitation of the operations per runFixes#466* test(debug): disable the dry-run for the test by defaultwe will be able to test the operations per run and have more complete logs that could help us debug the workflow* chore(logs): also display the stats when the operations per run stopped the workflow* chore(stats): fix a bad stats related to the consumed operations* test(operations-per-run): add coverage* chore: update index
1 parent8deaf75 commit5f6f311

File tree

5 files changed

+267
-24
lines changed

5 files changed

+267
-24
lines changed

‎__tests__/constants/default-processor-options.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export const DefaultProcessorOptions: IIssuesProcessorOptions = Object.freeze({
2525
anyOfIssueLabels:'',
2626
anyOfPrLabels:'',
2727
operationsPerRun:100,
28-
debugOnly:true,
28+
debugOnly:false,
2929
removeStaleWhenUpdated:false,
3030
removeIssueStaleWhenUpdated:undefined,
3131
removePrStaleWhenUpdated:undefined,

‎__tests__/operations-per-run.spec.ts

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
import{Issue}from'../src/classes/issue';
2+
import{IIssuesProcessorOptions}from'../src/interfaces/issues-processor-options';
3+
import{IsoDateString}from'../src/types/iso-date-string';
4+
import{IssuesProcessorMock}from'./classes/issues-processor-mock';
5+
import{DefaultProcessorOptions}from'./constants/default-processor-options';
6+
import{generateIssue}from'./functions/generate-issue';
7+
8+
describe('operations per run option',():void=>{
9+
letsut:SUT;
10+
11+
beforeEach(():void=>{
12+
sut=newSUT();
13+
});
14+
15+
describe('when one issue should be stale within 10 days and updated 20 days ago',():void=>{
16+
beforeEach(():void=>{
17+
sut.staleIn(10).newIssue().updated(20);
18+
});
19+
20+
describe('when the operations per run option is set to 1',():void=>{
21+
beforeEach(():void=>{
22+
sut.operationsPerRun(1);
23+
});
24+
25+
it('should consume 1 operation (stale label)',async()=>{
26+
expect.assertions(2);
27+
28+
awaitsut.test();
29+
30+
expect(sut.processor.staleIssues).toHaveLength(1);
31+
expect(
32+
sut.processor.operations.getConsumedOperationsCount()
33+
).toStrictEqual(1);
34+
});
35+
});
36+
});
37+
38+
describe('when one issue should be stale within 10 days and updated 20 days ago and a comment should be added when stale',():void=>{
39+
beforeEach(():void=>{
40+
sut.staleIn(10).commentOnStale().newIssue().updated(20);
41+
});
42+
43+
describe('when the operations per run option is set to 2',():void=>{
44+
beforeEach(():void=>{
45+
sut.operationsPerRun(2);
46+
});
47+
48+
it('should consume 2 operations (stale label, comment)',async()=>{
49+
expect.assertions(2);
50+
51+
awaitsut.test();
52+
53+
expect(sut.processor.staleIssues).toHaveLength(1);
54+
expect(
55+
sut.processor.operations.getConsumedOperationsCount()
56+
).toStrictEqual(2);
57+
});
58+
});
59+
60+
// Special case were we continue the issue processing even if the operations per run is reached
61+
describe('when the operations per run option is set to 1',():void=>{
62+
beforeEach(():void=>{
63+
sut.operationsPerRun(1);
64+
});
65+
66+
it('should consume 2 operations (stale label, comment)',async()=>{
67+
expect.assertions(2);
68+
69+
awaitsut.test();
70+
71+
expect(sut.processor.staleIssues).toHaveLength(1);
72+
expect(
73+
sut.processor.operations.getConsumedOperationsCount()
74+
).toStrictEqual(2);
75+
});
76+
});
77+
});
78+
79+
describe('when two issues should be stale within 10 days and updated 20 days ago and a comment should be added when stale',():void=>{
80+
beforeEach(():void=>{
81+
sut.staleIn(10).commentOnStale();
82+
sut.newIssue().updated(20);
83+
sut.newIssue().updated(20);
84+
});
85+
86+
describe('when the operations per run option is set to 3',():void=>{
87+
beforeEach(():void=>{
88+
sut.operationsPerRun(3);
89+
});
90+
91+
it('should consume 4 operations (stale label, comment)',async()=>{
92+
expect.assertions(2);
93+
94+
awaitsut.test();
95+
96+
expect(sut.processor.staleIssues).toHaveLength(2);
97+
expect(
98+
sut.processor.operations.getConsumedOperationsCount()
99+
).toStrictEqual(4);
100+
});
101+
});
102+
103+
describe('when the operations per run option is set to 2',():void=>{
104+
beforeEach(():void=>{
105+
sut.operationsPerRun(2);
106+
});
107+
108+
it('should consume 2 operations (stale label, comment) and stop',async()=>{
109+
expect.assertions(2);
110+
111+
awaitsut.test();
112+
113+
expect(sut.processor.staleIssues).toHaveLength(1);
114+
expect(
115+
sut.processor.operations.getConsumedOperationsCount()
116+
).toStrictEqual(2);
117+
});
118+
});
119+
120+
// Special case were we continue the issue processing even if the operations per run is reached
121+
describe('when the operations per run option is set to 1',():void=>{
122+
beforeEach(():void=>{
123+
sut.operationsPerRun(1);
124+
});
125+
126+
it('should consume 2 operations (stale label, comment) and stop',async()=>{
127+
expect.assertions(2);
128+
129+
awaitsut.test();
130+
131+
expect(sut.processor.staleIssues).toHaveLength(1);
132+
expect(
133+
sut.processor.operations.getConsumedOperationsCount()
134+
).toStrictEqual(2);
135+
});
136+
});
137+
});
138+
});
139+
140+
classSUT{
141+
processor!:IssuesProcessorMock;
142+
private_opts:IIssuesProcessorOptions={
143+
...DefaultProcessorOptions,
144+
staleIssueMessage:''
145+
};
146+
private_testIssueList:Issue[]=[];
147+
private_sutIssues:SUTIssue[]=[];
148+
149+
newIssue():SUTIssue{
150+
constsutIssue:SUTIssue=newSUTIssue();
151+
this._sutIssues.push(sutIssue);
152+
153+
returnsutIssue;
154+
}
155+
156+
staleIn(days:number):SUT{
157+
this._updateOptions({
158+
daysBeforeIssueStale:days
159+
});
160+
161+
returnthis;
162+
}
163+
164+
commentOnStale():SUT{
165+
this._updateOptions({
166+
staleIssueMessage:'Dummy stale issue message'
167+
});
168+
169+
returnthis;
170+
}
171+
172+
operationsPerRun(count:number):SUT{
173+
this._updateOptions({
174+
operationsPerRun:count
175+
});
176+
177+
returnthis;
178+
}
179+
180+
asynctest():Promise<number>{
181+
returnthis._setTestIssueList()._setProcessor();
182+
}
183+
184+
private_updateOptions(opts:Partial<IIssuesProcessorOptions>):SUT{
185+
this._opts={...this._opts, ...opts};
186+
187+
returnthis;
188+
}
189+
190+
private_setTestIssueList():SUT{
191+
this._testIssueList=this._sutIssues.map(
192+
(sutIssue:SUTIssue):Issue=>{
193+
returngenerateIssue(
194+
this._opts,
195+
1,
196+
'My first issue',
197+
sutIssue.updatedAt,
198+
sutIssue.updatedAt,
199+
false
200+
);
201+
}
202+
);
203+
204+
returnthis;
205+
}
206+
207+
privateasync_setProcessor():Promise<number>{
208+
this.processor=newIssuesProcessorMock(
209+
this._opts,
210+
async()=>'abot',
211+
asyncp=>(p===1 ?this._testIssueList :[]),
212+
async()=>[],
213+
async()=>newDate().toDateString()
214+
);
215+
216+
returnthis.processor.processIssues(1);
217+
}
218+
}
219+
220+
classSUTIssue{
221+
updatedAt:IsoDateString='2020-01-01T17:00:00Z';
222+
223+
updated(daysAgo:number):SUTIssue{
224+
consttoday=newDate();
225+
today.setDate(today.getDate()-daysAgo);
226+
this.updatedAt=today.toISOString();
227+
228+
returnthis;
229+
}
230+
}

‎dist/index.js

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ class IssuesProcessor {
255255
this.removedLabelIssues=[];
256256
this.options=options;
257257
this.client=github_1.getOctokit(this.options.repoToken);
258-
this._operations=newstale_operations_1.StaleOperations(this.options);
258+
this.operations=newstale_operations_1.StaleOperations(this.options);
259259
this._logger.info(logger_service_1.LoggerService.yellow(`Starting the stale action process...`));
260260
if(this.options.debugOnly){
261261
this._logger.warning(logger_service_1.LoggerService.yellowBright(`Executing in debug mode!`));
@@ -286,20 +286,24 @@ class IssuesProcessor {
286286
returnissue.isPullRequest ?option_1.Option.ClosePrLabel :option_1.Option.CloseIssueLabel;
287287
}
288288
processIssues(page=1){
289-
var_a,_b;
289+
var_a,_b,_c;
290290
return__awaiter(this,void0,void0,function*(){
291291
// get the next batch of issues
292292
constissues=yieldthis.getIssues(page);
293293
constactor=yieldthis.getActor();
294294
if(issues.length<=0){
295295
this._logger.info(logger_service_1.LoggerService.green(`No more issues found to process. Exiting...`));
296-
(_a=this._statistics)===null||_a===void0 ?void0 :_a.setRemainingOperations(this._operations.getRemainingOperationsCount()).logStats();
297-
returnthis._operations.getRemainingOperationsCount();
296+
(_a=this._statistics)===null||_a===void0 ?void0 :_a.setOperationsCount(this.operations.getConsumedOperationsCount()).logStats();
297+
returnthis.operations.getRemainingOperationsCount();
298298
}
299299
else{
300300
this._logger.info(`${logger_service_1.LoggerService.yellow('Processing the batch of issues')}${logger_service_1.LoggerService.cyan(`#${page}`)}${logger_service_1.LoggerService.yellow('containing')}${logger_service_1.LoggerService.cyan(issues.length)}${logger_service_1.LoggerService.yellow(`issue${issues.length>1 ?'s' :''}...`)}`);
301301
}
302302
for(constissueofissues.values()){
303+
// Stop the processing if no more operations remains
304+
if(!this.operations.hasRemainingOperations()){
305+
break;
306+
}
303307
constissueLogger=newissue_logger_1.IssueLogger(issue);
304308
(_b=this._statistics)===null||_b===void0 ?void0 :_b.incrementProcessedItemsCount(issue);
305309
issueLogger.info(`Found this $$type last updated at:${logger_service_1.LoggerService.cyan(issue.updated_at)}`);
@@ -450,9 +454,10 @@ class IssuesProcessor {
450454
}
451455
IssuesProcessor._endIssueProcessing(issue);
452456
}
453-
if(!this._operations.hasRemainingOperations()){
457+
if(!this.operations.hasRemainingOperations()){
454458
this._logger.warning(logger_service_1.LoggerService.yellowBright(`No more operations left! Exiting...`));
455459
this._logger.warning(`${logger_service_1.LoggerService.yellowBright('If you think that not enough issues were processed you could try to increase the quantity related to the')}${this._logger.createOptionLink(option_1.Option.OperationsPerRun)}${logger_service_1.LoggerService.yellowBright('option which is currently set to')}${logger_service_1.LoggerService.cyan(this.options.operationsPerRun)}`);
460+
(_c=this._statistics)===null||_c===void0 ?void0 :_c.setOperationsCount(this.operations.getConsumedOperationsCount()).logStats();
456461
return0;
457462
}
458463
this._logger.info(`${logger_service_1.LoggerService.green('Batch')}${logger_service_1.LoggerService.cyan(`#${page}`)}${logger_service_1.LoggerService.green('processed.')}`);
@@ -466,7 +471,7 @@ class IssuesProcessor {
466471
return__awaiter(this,void0,void0,function*(){
467472
// Find any comments since date on the given issue
468473
try{
469-
this._operations.consumeOperation();
474+
this.operations.consumeOperation();
470475
(_a=this._statistics)===null||_a===void0 ?void0 :_a.incrementFetchedItemsCommentsCount();
471476
constcomments=yieldthis.client.issues.listComments({
472477
owner:github_1.context.repo.owner,
@@ -487,7 +492,7 @@ class IssuesProcessor {
487492
return__awaiter(this,void0,void0,function*(){
488493
letactor;
489494
try{
490-
this._operations.consumeOperation();
495+
this.operations.consumeOperation();
491496
actor=yieldthis.client.users.getAuthenticated();
492497
}
493498
catch(error){
@@ -503,7 +508,7 @@ class IssuesProcessor {
503508
// generate type for response
504509
constendpoint=this.client.issues.listForRepo;
505510
try{
506-
this._operations.consumeOperation();
511+
this.operations.consumeOperation();
507512
constissueResult=yieldthis.client.issues.listForRepo({
508513
owner:github_1.context.repo.owner,
509514
repo:github_1.context.repo.repo,
@@ -871,7 +876,7 @@ class IssuesProcessor {
871876
});
872877
}
873878
_consumeIssueOperation(issue){
874-
this._operations.consumeOperation();
879+
this.operations.consumeOperation();
875880
issue.operations.consumeOperation();
876881
}
877882
_getDaysBeforeStaleUsedOptionName(issue){
@@ -1283,8 +1288,8 @@ class Statistics {
12831288
}
12841289
returnthis._incrementUndoStaleIssuesCount(increment);
12851290
}
1286-
setRemainingOperations(remainingOperations){
1287-
this._operationsCount=remainingOperations;
1291+
setOperationsCount(operationsCount){
1292+
this._operationsCount=operationsCount;
12881293
returnthis;
12891294
}
12901295
incrementClosedItemsCount(issue,increment=1){
@@ -8892,4 +8897,4 @@ module.exports = require("zlib");;
88928897
/******/// Load entry module and return exports
88938898
/******/return__nccwpck_require__(3109);
88948899
/******/})()
8895-
;
8900+
;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp