mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			118 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			118 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| const fs = require('fs');
 | |
| const path = require('path');
 | |
| 
 | |
| const baseConfig = require('./jest.config.js');
 | |
| 
 | |
| const CODEOWNERS_MANIFEST_FILENAMES_BY_TEAM_PATH = 'codeowners-manifest/filenames-by-team.json';
 | |
| 
 | |
| const teamName = process.env.TEAM_NAME;
 | |
| if (!teamName) {
 | |
|   console.error('ERROR: TEAM_NAME environment variable is required');
 | |
|   process.exit(1);
 | |
| }
 | |
| 
 | |
| const outputDir = `./coverage/by-team/${createOwnerDirectory(teamName)}`;
 | |
| 
 | |
| const codeownersFilePath = path.join(__dirname, CODEOWNERS_MANIFEST_FILENAMES_BY_TEAM_PATH);
 | |
| 
 | |
| if (!fs.existsSync(codeownersFilePath)) {
 | |
|   console.error(`Codeowners file not found at ${codeownersFilePath} ...`);
 | |
|   console.error('Please run: yarn codeowners-manifest first to generate the mapping file');
 | |
|   process.exit(1);
 | |
| }
 | |
| 
 | |
| const codeownersData = JSON.parse(fs.readFileSync(codeownersFilePath, 'utf8'));
 | |
| const teamFiles = codeownersData[teamName] || [];
 | |
| 
 | |
| if (teamFiles.length === 0) {
 | |
|   console.error(`ERROR: No files found for team "${teamName}"`);
 | |
|   console.error('Available teams:', Object.keys(codeownersData).join(', '));
 | |
|   process.exit(1);
 | |
| }
 | |
| 
 | |
| const sourceFiles = teamFiles.filter((file) => {
 | |
|   const ext = path.extname(file);
 | |
|   return (
 | |
|     ['.ts', '.tsx', '.js', '.jsx'].includes(ext) &&
 | |
|     !file.includes('.test.') &&
 | |
|     !file.includes('.spec.') &&
 | |
|     !file.includes('.story.') &&
 | |
|     !file.includes('.gen.ts') &&
 | |
|     !file.includes('.d.ts') &&
 | |
|     !file.endsWith('/types.ts')
 | |
|   );
 | |
| });
 | |
| 
 | |
| const testFiles = teamFiles.filter((file) => {
 | |
|   const ext = path.extname(file);
 | |
|   return ['.ts', '.tsx', '.js', '.jsx'].includes(ext) && (file.includes('.test.') || file.includes('.spec.'));
 | |
| });
 | |
| 
 | |
| if (testFiles.length === 0) {
 | |
|   console.log(`No test files found for team ${teamName}`);
 | |
|   process.exit(0);
 | |
| }
 | |
| 
 | |
| console.log(
 | |
|   `🧪 Collecting coverage for ${sourceFiles.length} testable files and running ${testFiles.length} test files of ${teamFiles.length} files owned by ${teamName}.`
 | |
| );
 | |
| 
 | |
| module.exports = {
 | |
|   ...baseConfig,
 | |
| 
 | |
|   collectCoverage: true,
 | |
|   collectCoverageFrom: sourceFiles.map((file) => `<rootDir>/${file}`),
 | |
|   coverageReporters: ['none'],
 | |
|   coverageDirectory: '/tmp/jest-coverage-ignore',
 | |
| 
 | |
|   coverageProvider: 'v8',
 | |
|   reporters: [
 | |
|     'default',
 | |
|     [
 | |
|       'jest-monocart-coverage',
 | |
|       {
 | |
|         name: `Coverage Report - ${teamName} owned files`,
 | |
|         outputDir: outputDir,
 | |
|         reports: ['console-summary', 'v8', 'json', 'lcov'],
 | |
|         sourceFilter: (coveredFile) => sourceFiles.includes(coveredFile),
 | |
|         all: {
 | |
|           dir: ['./packages', './public'],
 | |
|           filter: (filePath) => {
 | |
|             const relativePath = filePath.replace(process.cwd() + '/', '');
 | |
|             return sourceFiles.includes(relativePath);
 | |
|           },
 | |
|         },
 | |
|         cleanCache: true,
 | |
|         onEnd: (coverageResults) => {
 | |
|           console.log(`📄 Coverage report saved to file://${path.resolve(outputDir)}/index.html`);
 | |
|           // TODO: Emit coverage metrics https://github.com/grafana/grafana/issues/111208
 | |
|         },
 | |
|       },
 | |
|     ],
 | |
|   ],
 | |
| 
 | |
|   testRegex: undefined,
 | |
| 
 | |
|   testMatch: testFiles.map((file) => `<rootDir>/${file}`),
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Create a filesystem-safe directory structure for different owner types
 | |
|  * @param {string} owner - CODEOWNERS owner (username, team, or email)
 | |
|  * @returns {string} Directory path relative to coverage/by-team/
 | |
|  */
 | |
| function createOwnerDirectory(owner) {
 | |
|   if (owner.includes('@') && owner.includes('/')) {
 | |
|     // Example: @grafana/dataviz-squad
 | |
|     const [org, team] = owner.substring(1).split('/');
 | |
|     return `teams/${org}/${team}`;
 | |
|   } else if (owner.startsWith('@')) {
 | |
|     // Example: @jesdavpet
 | |
|     return `users/${owner.substring(1)}`;
 | |
|   } else {
 | |
|     // Example: user@domain.tld
 | |
|     const [user, domain] = owner.split('@');
 | |
|     return `emails/${user}-at-${domain}`;
 | |
|   }
 | |
| }
 |