Skip to content

Commit 3ac6c73

Browse files
committed
Add functionality to clean up old junit and ctrf reports in S3
1 parent 947f02b commit 3ac6c73

2 files changed

Lines changed: 148 additions & 1 deletion

File tree

bin/cleanup-s3.js

Lines changed: 146 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const {
2121
} = require( './utils' );
2222
const { s3Params, s3client } = require( './s3-client' );
2323
const { Octokit } = require( '@octokit/rest' );
24-
const { PutObjectCommand, DeleteObjectCommand } = require( '@aws-sdk/client-s3' );
24+
const { PutObjectCommand, DeleteObjectCommand, ListObjectsCommand } = require( '@aws-sdk/client-s3' );
2525
const configModule = require( '../src/config.js' );
2626
const config = configModule.default || configModule;
2727
const moment = require( 'moment' );
@@ -46,6 +46,10 @@ const reportsToClean = [];
4646
let testsToDelete = [];
4747
const reportAgeThresholdInDays = 30;
4848
const testsAgeThresholdInDays = 30;
49+
const daysToKeepFiles = {
50+
junit: 7,
51+
ctrf: 2,
52+
};
4953

5054
const plus = String.fromCodePoint( 0x2795 );
5155
const done = String.fromCodePoint( 0x2714 );
@@ -284,6 +288,139 @@ const trash = String.fromCodePoint( 0x1f5d1 );
284288
console.groupEnd();
285289

286290
console.groupEnd();
291+
292+
// region Clean junit queue and processed folders
293+
console.group( '\n', 'Cleaning junit queue and processed folders' );
294+
const junitFolders = [ 'reports/junit/queue/', 'reports/junit/processed/' ];
295+
296+
for ( const folder of junitFolders ) {
297+
console.log( `\nChecking ${ folder }` );
298+
299+
try {
300+
// Collect all files with pagination
301+
const allFiles = [];
302+
let truncated = true;
303+
let marker;
304+
let pageCount = 0;
305+
306+
while ( truncated ) {
307+
pageCount++;
308+
console.log( `Fetching page ${ pageCount } for ${ folder }` );
309+
310+
const listCmd = new ListObjectsCommand( {
311+
Bucket: s3Params.Bucket,
312+
Prefix: folder,
313+
Marker: marker,
314+
} );
315+
const listResponse = await s3client.send( listCmd );
316+
317+
if ( listResponse.Contents && listResponse.Contents.length > 0 ) {
318+
allFiles.push( ...listResponse.Contents );
319+
}
320+
321+
truncated = listResponse.IsTruncated;
322+
if ( truncated ) {
323+
marker = listResponse.Contents[ listResponse.Contents.length - 1 ].Key;
324+
}
325+
}
326+
327+
if ( allFiles.length === 0 ) {
328+
console.log( `No files found in ${ folder }` );
329+
continue;
330+
}
331+
332+
console.log( `Found ${ allFiles.length } files in ${ folder }` );
333+
334+
// Sort by LastModified date ascending (oldest first)
335+
allFiles.sort( ( a, b ) => a.LastModified - b.LastModified );
336+
337+
let removedCount = 0;
338+
for ( const file of allFiles ) {
339+
const fileKey = file.Key;
340+
const lastModified = file.LastModified;
341+
342+
if ( isOld( lastModified, daysToKeepFiles.junit, 'days' ) ) {
343+
console.log( `Removing old file: ${ fileKey }` );
344+
await s3client.send(
345+
new DeleteObjectCommand( { Bucket: s3Params.Bucket, Key: fileKey } )
346+
);
347+
removedCount++;
348+
}
349+
}
350+
351+
console.log( `${ done } Removed ${ removedCount } files from ${ folder }` );
352+
} catch ( err ) {
353+
console.error( `Error processing folder ${ folder }: ${ err.message }` );
354+
}
355+
}
356+
357+
console.groupEnd();
358+
// endregion
359+
360+
// region Clean ctrf folder
361+
console.group( '\n', 'Cleaning ctrf folder' );
362+
const ctrfFolder = 'reports/ctrf/';
363+
364+
console.log( `\nChecking ${ ctrfFolder }` );
365+
366+
try {
367+
// Collect all files with pagination
368+
const allFiles = [];
369+
let truncated = true;
370+
let marker;
371+
let pageCount = 0;
372+
373+
while ( truncated ) {
374+
pageCount++;
375+
console.log( `Fetching page ${ pageCount } for ${ ctrfFolder }` );
376+
377+
const listCmd = new ListObjectsCommand( {
378+
Bucket: s3Params.Bucket,
379+
Prefix: ctrfFolder,
380+
Marker: marker,
381+
} );
382+
const listResponse = await s3client.send( listCmd );
383+
384+
if ( listResponse.Contents && listResponse.Contents.length > 0 ) {
385+
allFiles.push( ...listResponse.Contents );
386+
}
387+
388+
truncated = listResponse.IsTruncated;
389+
if ( truncated ) {
390+
marker = listResponse.Contents[ listResponse.Contents.length - 1 ].Key;
391+
}
392+
}
393+
394+
if ( allFiles.length === 0 ) {
395+
console.log( `No files found in ${ ctrfFolder }` );
396+
} else {
397+
console.log( `Found ${ allFiles.length } files in ${ ctrfFolder }` );
398+
399+
// Sort by LastModified date ascending (oldest first)
400+
allFiles.sort( ( a, b ) => a.LastModified - b.LastModified );
401+
402+
let removedCount = 0;
403+
for ( const file of allFiles ) {
404+
const fileKey = file.Key;
405+
const lastModified = file.LastModified;
406+
407+
if ( isOld( lastModified, daysToKeepFiles.ctrf, 'days' ) ) {
408+
console.log( `Removing old file: ${ fileKey }` );
409+
await s3client.send(
410+
new DeleteObjectCommand( { Bucket: s3Params.Bucket, Key: fileKey } )
411+
);
412+
removedCount++;
413+
}
414+
}
415+
416+
console.log( `${ done } Removed ${ removedCount } files from ${ ctrfFolder }` );
417+
}
418+
} catch ( err ) {
419+
console.error( `Error processing folder ${ ctrfFolder }: ${ err.message }` );
420+
}
421+
422+
console.groupEnd();
423+
// endregion
287424
} )();
288425

289426
async function checkReportAge( report ) {
@@ -457,3 +594,11 @@ function printProgress( line, i, total, interval = 50 ) {
457594
process.stdout.write( `${ line }: ${ progress }%\r` );
458595
}
459596
}
597+
598+
function isOld( date, threshold, timeUnit = 'days' ) {
599+
const duration = moment
600+
.duration( moment.utc().diff( moment.utc( date ) ) )
601+
.as( timeUnit )
602+
.toFixed( 1 );
603+
return duration > threshold;
604+
}

src/config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ const config = {
1313
'jetpack-search-plugin',
1414
'jetpack-videopress-plugin',
1515
'jetpack-protect-plugin',
16+
'ctrf',
17+
'junit',
1618
],
1719
trunkRuns: [
1820
'master',

0 commit comments

Comments
 (0)