Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CI] Add Danger #14964

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
; Ignore the website subdir
<PROJECT_ROOT>/website/.*

; Ignore the Dangerfile
<PROJECT_ROOT>/danger/dangerfile.js

; Ignore "BUCK" generated dirs
<PROJECT_ROOT>/\.buckd/

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ local.properties
node_modules
*.log
.nvm
/danger/node_modules/

# OS X
.DS_Store
Expand Down
7 changes: 6 additions & 1 deletion circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,15 @@ dependencies:
- npm install
# for eslint bot
- npm install github@0.2.4
# for website, danger
- cd website && npm install
- cd danger && npm install
cache_directories:
- "ReactAndroid/build/downloads"
- "/home/ubuntu/buck"
- "website/node_modules"
- "node_modules"
- "danger/node_modules"

test:
pre:
Expand All @@ -49,7 +52,9 @@ test:
- source scripts/circle-ci-android-setup.sh && waitForAVD

override:
# eslint bot. This GitHub token grants public_repo access scope.
# Run Danger against PRs. This GitHub token grants public_repo access scope. The associated account has no privileged access to the React Native repo. The token must be split in this manner to avoid revocation by GitHub.
- cd danger && DANGER_GITHUB_API_TOKEN="e622517d9f1136ea8900""07c6373666312cdfaa69" npm run danger
# eslint bot. This GitHub token grants public_repo access scope. The token must be split in this manner to avoid revocation by GitHub.
- cat <(echo eslint; npm run lint --silent -- --format=json; echo flow; npm run flow --silent -- check --json) | GITHUB_TOKEN="af6ef0d15709bc91d""06a6217a5a826a226fb57b7" CI_USER=$CIRCLE_PROJECT_USERNAME CI_REPO=$CIRCLE_PROJECT_REPONAME PULL_REQUEST_NUMBER=$CIRCLE_PR_NUMBER node bots/code-analysis-bot.js
# JS tests for dependencies installed with npm3
- npm run flow -- check
Expand Down
1 change: 1 addition & 0 deletions danger/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
12 changes: 12 additions & 0 deletions danger/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
If you'd like to make changes to the Dangerfile, find an existing PR and copy the URL.

Then run from the React Native root:

```
cd danger
npm install
..
node danger/node_modules/.bin/danger pr https://github.com/facebook/react-native/pull/1
```

And you will get the responses from parsing the Dangerfile.
91 changes: 91 additions & 0 deletions danger/dangerfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

const fs = require('fs');
const includes = require('lodash.includes');

const isDocsFile = path => includes(path, 'docs/');
const editsDocs = danger.git.modified_files.filter(isDocsFile).length > 0;
const addsDocs = danger.git.created_files.filter(isDocsFile).length > 0;
if (addsDocs || editsDocs) {
// Note, this does not yet cover edits to the autogenerated docs (e.g. comments within JS source files)
markdown(`:page_facing_up: Thanks for your contribution to the docs!`);
}

const isBlogFile = path => includes(path, 'blog/');

// Flags new blog posts. Note that mentions will not be parsed as the access token we're using does not belong to the Facebook org (on purpose)
const addsBlogPost = danger.git.created_files.filter(isBlogFile).length > 0;
if (addsBlogPost) {
const message = ':memo: Blog post';
const idea = 'This PR appears to add a new blog post, and may require further review from the React Native team.';
warn(`${message} - <i>${idea}</i>`);
markdown(`:memo: This PR requires attention from the @facebook/react-native team.`);
}

// Flags edits to blog posts
const editsBlogPost = danger.git.modified_files.filter(isBlogFile).length > 0;
if (editsBlogPost) {
const message = ':memo: Blog post';
const idea = 'This PR appears to edit an existing blog post, and may require further review from the React Native team.';
warn(`${message} - <i>${idea}</i>`);
markdown(`This PR requires attention from the @facebook/react-native team.`);
}

// Fails if the description is too short.
if (danger.github.pr.body.length < 10) {
fail(':grey_question: This pull request needs a description.')
}

// Warns if the PR title contains [WIP]
const isWIP = includes(danger.github.pr.title, '[WIP]')
if (isWIP) {
const message = ':construction_worker: Work In Progress';
const idea = 'This PR appears to be a work in progress, and may not be ready to be merged yet.';
warn(`${message} - <i>${idea}</i>`);
}

// Warns if there are changes to package.json, and tags the team.
const packageChanged = includes(danger.git.modified_files, 'package.json');
if (packageChanged) {
const message = ':lock: package.json';
const idea = 'Changes were made to package.json. This will require a manual import by a Facebook employee.';
warn(`${message} - <i>${idea}</i>`);
markdown(`This PR requires attention from the @facebook/react-native team.`);
}

// Warns if a test plan is missing.
const gettingStartedChanged = includes(danger.git.modified_files, 'docs/GettingStarted.md');
const includesTestPlan = danger.github.pr.body.toLowerCase().includes('test plan');

// Warns if a test plan is missing, when editing the Getting Started guide. This page needs to be tested in all its permutations.
if (!includesTestPlan && gettingStartedChanged) {
const message = ':clipboard: Test Plan';
const idea = 'This PR appears to be missing a Test Plan.';
warn(`${message} - <i>${idea}</i>`);
}
// Doc edits rarely require a test plan. We'll trust the reviewer to push back if one is needed.
if (!includesTestPlan && !editsDocs) {
const message = ':clipboard: Test Plan';
const idea = 'This PR appears to be missing a Test Plan.';
warn(`${message} - <i>${idea}</i>`);
}

// Tags PRs that have been submitted by a core contributor.
const taskforce = fs.readFileSync('../bots/IssueCommands.txt', 'utf8').split('\n')[0].split(':')[1];
const isSubmittedByTaskforce = includes(taskforce, danger.github.pr.user.login);
if (isSubmittedByTaskforce) {
markdown(`This PR has been submitted by a core contributor.`);
}

const isBotsCommandsFile = path => includes(path, 'bots/IssueCommands.txt');
if (isBotsCommandsFile) {
const message = ':exclamation: Bots';
const idea = 'This PR appears to modify the list of people that may issue commands to the GitHub bot.';
warn(`${message} - <i>${idea}</i>`);
}
10 changes: 10 additions & 0 deletions danger/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"private": true,
"scripts": {
"danger": "node ./node_modules/.bin/danger"
},
"devDependencies": {
"danger": "^0.21.2",
"lodash.includes": "^4.3.0"
}
}