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}`;
|
||
|
}
|
||
|
}
|