Skip to content

Instantly share code, notes, and snippets.

@renanmav
Created June 15, 2020 14:53
Show Gist options
  • Save renanmav/73893917939609b39da5481c23b6b129 to your computer and use it in GitHub Desktop.
Save renanmav/73893917939609b39da5481c23b6b129 to your computer and use it in GitHub Desktop.
import fs from 'fs';
import path from 'path';
import { danger, warn, schedule } from 'danger';
import jest from 'danger-plugin-jest';
import spellcheck from 'danger-plugin-spellcheck';
import todos from 'danger-plugin-todos';
import yarn from 'danger-plugin-yarn';
// Setup
const pr = danger.github.pr;
const modified = danger.git.modified_files;
const bodyAndTitle = (pr.body + pr.title).toLowerCase();
const prIsClosingAnyIssue = /(close|fix|resolve)\w*:?\s#\d*/.test(bodyAndTitle);
// Custom modifiers for people submitting PRs to be able to say "skip this"
const acceptedNoTests = bodyAndTitle.includes('#skip_new_tests');
const typescriptOnly = (file: string) => file.includes('.ts');
const filesOnly = (file: string) => fs.existsSync(file) && fs.lstatSync(file).isFile();
// Modified or Created can be treated the same a lot of the time
const touchedFiles = modified.concat(danger.git.created_files).filter(filesOnly);
const createdFiles = danger.git.created_files.filter(filesOnly);
const appOnlyFilter = (filename: string) =>
filename.includes('packages/') &&
!filename.includes('__tests__') &&
!filename.includes('__mocks__') &&
typescriptOnly(filename);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const touchedAppOnlyFiles = touchedFiles.filter(appOnlyFilter);
const createdAppOnlyFiles = createdFiles.filter(appOnlyFilter);
// Rules
if (!prIsClosingAnyIssue) {
warn('This PR is not closing any issue.');
}
// Check that every file created has a corresponding test file
const correspondingTestsForAppFiles = createdAppOnlyFiles.map((f) => {
const newPath = path.dirname(f);
const name = path.basename(f).replace('.ts', '.test.ts');
return `${newPath}/__tests__/${name}`;
});
// New app files should get new test files
// Allow warning instead of failing if you say "Skip New Tests" inside the body, make it explicit.
const testFilesThatDontExist = correspondingTestsForAppFiles
.filter((f) => !f.includes('__stories__')) // skip stories
.filter((f) => !f.includes('/test/')) // skip test setup files
.filter((f) => !fs.existsSync(f));
if (testFilesThatDontExist.length > 0) {
const callout = acceptedNoTests ? warn : fail;
const output = `Missing Test Files:
${testFilesThatDontExist.map((f) => `- \`${f}\``).join('\n')}
If these files are supposed to not exist, please update your PR body to include "#skip_new_tests".`;
callout(output);
}
// Show Jest fails in the PR
if (fs.existsSync('test-results.json')) {
jest({ testResultsJsonPath: 'test-results.json' });
}
// Do spell check
spellcheck();
// Search for todos
schedule(todos());
// Dependecy check
yarn();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment