You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by ky...@apache.org on 2019/08/08 07:13:50 UTC

[incubator-weex] branch master updated: [Travis] Add Lint in TravisCI and Update iOS TravisCI (#2731)

This is an automated email from the ASF dual-hosted git repository.

kyork pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-weex.git


The following commit(s) were added to refs/heads/master by this push:
     new 3bfb619  [Travis] Add Lint in TravisCI and Update iOS TravisCI (#2731)
3bfb619 is described below

commit 3bfb619122bbb87431b90790dd0d47a8db8ef193
Author: Renmin <33...@users.noreply.github.com>
AuthorDate: Thu Aug 8 15:13:42 2019 +0800

    [Travis] Add Lint in TravisCI and Update iOS TravisCI (#2731)
    
    Add the following tasks:
    
    * Android Lint
    * OCLint
---
 .travis.yml                                 | 117 +++++++++++++++++++++++-----
 Dangerfile                                  |   0
 dangerfile-ios.js                           |  21 +----
 dangerfile-output.js                        |  71 +++++++++++++++++
 dangerfile-static-check.js                  |  89 +++++++++++++++++++++
 ios/sdk/.gitignore                          |   1 +
 ios/sdk/WeexSDK/Sources/Utility/WXVersion.m |   4 +-
 package-lock.json                           |  41 +++-------
 package.json                                |   2 +-
 9 files changed, 276 insertions(+), 70 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 47dace8..868c588 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,6 @@
 os: linux
 language: node_js
-node_js: 7.6
+node_js: 12.6.0
 matrix:
     fast_finish: true
     include:
@@ -31,7 +31,20 @@ matrix:
         android:
           components:
             - android-26
+            - extra-android-m2repository 
+      # static check
+      - env: TEST_SUITE=static_code_analysis OCLINT=true
+        osx_image: xcode7.2
+        language: objective-c
+      - env: TEST_SUITE=static_code_analysis ANDROID_LINT=true
+        language: android
+        dist: trusty
+        jdk: oraclejdk8
+        android:
+          components:
+            - android-26
             - extra-android-m2repository
+        
 cache:
   directories:
     - npm
@@ -39,15 +52,36 @@ cache:
     - $HOME/.gradle/wrapper/
     - $HOME/.android/build-cache
     - $HOME/android-ndk-r18b
+    - bundle
+
 before_cache:
   - rm -f  $HOME/.gradle/caches/modules-2/modules-2.lock
   - rm -fr $HOME/.gradle/caches/*/plugin-resolution/
+  - rm -fr $HOME/node_modules/*
+
+before_install:
+  - |
+    # install android lint 
+    if [[ ("$TEST_SUITE" = "static_code_analysis") && ("${ANDROID_LINT}" = "true") ]]; then
+      apt-get install rubygems
+      gem install bundler
+      bundle install
+    fi
+
+    # install oclint
+    if [[ ("$TEST_SUITE" = "static_code_analysis") && ("${OCLINT}" = "true") ]]; then
+      brew cask uninstall oclint
+      brew tap oclint/formulae
+      brew install oclint
+    fi
+
+    
+
 install:
   - |
-    case $TEST_SUITE in
-      "android") 
+    if [[ ("$TEST_SUITE" = "android") || ("${ANDROID_LINT}" = "true") ]]; then
         curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
-        nvm install 7.6
+        nvm install 12.6.0
         npm install
         echo y | sdkmanager "cmake;3.6.4111459"
         if find "${HOME}/android-ndk-r18b" -mindepth 1 | read; then
@@ -64,11 +98,22 @@ install:
         export ANDROID_NDK_HOME=$HOME/android-ndk-r18b
         export PATH=$PATH:$ANDROID_NDK_HOME
         echo "ndk.dir=$ANDROID_NDK_HOME" > android/local.properties
-        ;;
-      "jsfm" | "danger" | "ios" )
+    elif [[ ("$TEST_SUITE" = "jsfm") || ("$TEST_SUITE" = "danger") ||  ("${OCLINT}" = "true") ]]; then
+        curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
+        nvm install 12.6.0  
         npm install
-        ;;
-    esac
+    elif [[ ("$TEST_SUITE" = "ios") ]]; then
+        curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
+        nvm install 12.6.0  
+
+        git submodule update --init --remote
+        cd weex-playground/ios && bash update_podfile_for_travisci.sh
+        cd ../../ && npm install
+        cd weex-playground/ios && pod install --repo-update
+        cd ../../
+    fi
+    
+
 script:
   - |
     case $TEST_SUITE in
@@ -87,29 +132,65 @@ script:
             GRADLE_ABI=""
             ;;
         esac
-
-        hasAndroidFile=$(npm run danger -- run --dangerfile ./dangerfile-android.js)
-        echo "The value of hasAndroidFile is ${hasAndroidFile}"
-        if [[ "$hasAndroidFile" =~ "hasAndroidFile" ]]; then
+        if npm run danger -- ci --dangerfile ./dangerfile-android.js | grep -q "hasAndroidFile" ; then
           cd android
           ./gradlew clean install -PbuildRuntimeApi=true ${GRADLE_ABI} --info
           ./gradlew install -PbuildRuntimeApi=false ${GRADLE_ABI} --info
         fi
         ;;
       "jsfm" )
-        npm run danger -- run --dangerfile ./dangerfile-jsfm.js
+        npm run danger -- ci -i jsfm --dangerfile ./dangerfile-jsfm.js
         ;;
       "danger" )
-        npm run danger -- run --dangerfile ./dangerfile.js
+        npm run danger -- ci -i danger --dangerfile ./dangerfile.js
         ;;
       "ios" )
-        hasIosFile=$(npm run danger -- run --dangerfile ./dangerfile-ios.js)
-        echo "The value of hasIosFile is ${hasIosFile}"
-        if [[ "$hasIosFile" =~ "hasIosFile" ]]; then
-          xcodebuild -project ios/sdk/WeexSDK.xcodeproj test -scheme WeexSDKTests CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -destination "platform=iOS Simulator,name=iPhone 6"
+        if npm run danger -- ci --dangerfile ./dangerfile-ios.js | grep -q "hasIosFile" ; then
+          # build WeexSDK and run WeexSDKTests
+          xcodebuild -quiet -project ios/sdk/WeexSDK.xcodeproj test -scheme WeexSDKTests CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -destination "platform=iOS Simulator,name=iPhone 6" || exit 1
+          # build WeexDemo and run WeexDemo test
+          cd weex-playground/ios && mkdir tmp && mv * tmp;cd tmp
+          xcodebuild -quiet -workspace WeexDemo.xcworkspace test -scheme WeexDemo CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -destination "platform=iOS Simulator,name=iPhone 6" || exit 1
         fi
         ;;
     esac
+    
+    if [[ ("$TEST_SUITE" = "static_code_analysis") && ("${OCLINT}" = "true") ]]; then
+      if npm run danger -- ci --dangerfile ./dangerfile-static-check.js | grep -q "hasCFile" ; then
+        echo "hasCFile"
+        cd ios/sdk && xcodebuild | xcpretty -r json-compilation-database -o compile_commands.json
+        oclint-json-compilation-database oclint_args -- \
+          -disable-rule=ShortVariableName \
+          -disable-rule=LongLine \
+          -disable-rule=LongMethod \
+          -disable-rule=HighNcssMethod \
+          -disable-rule=LongVariableName \
+          -disable-rule=HighCyclomaticComplexity \
+          -disable-rule=HighNPathComplexity \
+          -disable-rule=UnusedLocalVariable \
+          -disable-rule=DoubleNegative \
+          -disable-rule=MultipleUnaryOperator \
+          -disable-rule=DeepNestedBlock \
+          -disable-rule=AssignIvarOutsideAccessors \
+          -disable-rule=BitwiseOperatorInConditional \
+          -max-priority-1=15000 \
+          -max-priority-2=15000 \
+          -max-priority-3=15000 > oclint.log
+        export TITLE="OCLint Result"
+        cd ../../ && npm run danger -- ci -i oclint --dangerfile ./dangerfile-output.js
+      fi
+    fi 
+
+    if [[ ("$TEST_SUITE" = "static_code_analysis") && ("${ANDROID_LINT}" = "true") ]]; then
+      if npm run danger -- ci --dangerfile ./dangerfile-static-check.js | grep -q "hasAndroidFile" ; then
+        echo "hasAndroidFile"
+        cd android
+        ./gradlew :weex_sdk:lint --quiet
+        export TITLE="AndroidLint Result"
+        cd ../ && npm run danger -- ci -i androidlint --dangerfile ./dangerfile-output.js
+      fi
+    fi
+
 notifications:
   webhooks:
     on_pull_requests: false
diff --git a/Dangerfile b/Dangerfile
new file mode 100644
index 0000000..e69de29
diff --git a/dangerfile-ios.js b/dangerfile-ios.js
index c507cce..e14aec5 100644
--- a/dangerfile-ios.js
+++ b/dangerfile-ios.js
@@ -90,22 +90,5 @@ if (!hasIosFile && danger.git.deleted_files) {
 }
 
 if(hasIosFile){
-  console.log('hasIosFile');
-}
-// console.log('-----------------------------hasIosFile-----------------------------:'+hasIosFile);
-// if(hasIosFile){
-//   var runTestCmd='source ~/.bash_profile; '
-//     +'xcodebuild -project ios/sdk/WeexSDK.xcodeproj test '
-//     +'-scheme WeexSDKTests CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO '
-//     +'-destination "platform=iOS Simulator,name=iPhone 6"'
-//   runSuccess = shell.exec(runTestCmd,{ async: false, timeout: 8 * 60 * 1000, maxBuffer: 200 * 1024 * 1024 }).code == 0;
-//   if(!runSuccess){
-//     fail("ios platform run unit test failed!");
-//   }
-// }else{
-//   console.log('has no ios file changed.');
-//   message('has no ios file changed.');
-// }
-// message('ios test finished.')
-
-
+  console.log('hasIosFile!!!');
+}
\ No newline at end of file
diff --git a/dangerfile-output.js b/dangerfile-output.js
new file mode 100644
index 0000000..d4d8a89
--- /dev/null
+++ b/dangerfile-output.js
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { fail, warn } from 'danger'
+const shell = require('shelljs')
+const title = process.env.TITLE
+const fs = require('fs')
+
+// code come from: https://stackoverflow.com/a/12745196
+// get the index of nth char in string
+function nth_occurrence (string, char, nth) {
+  var first_index = string.indexOf(char)
+  var length_up_to_first_index = first_index + 1
+  if (nth === 1) {
+      return first_index;
+  } else {
+      var string_after_first_occurrence = string.slice(length_up_to_first_index);
+      var next_occurrence = nth_occurrence(string_after_first_occurrence, char, nth - 1);
+      if (next_occurrence === -1) {
+          return -1;
+      } else {
+          return length_up_to_first_index + next_occurrence;  
+      }
+  }
+}
+
+if (title === 'OCLint Result') {
+  const command = 'cat ios/sdk/oclint.log | grep -i "P[1|2]"'
+  const child = shell.exec(command)
+  if (child.stdout !== '') {
+    fail(child.stdout)
+    fail(title)
+  }
+  if (child.stderr !== '') {
+    fail(child.stderr)
+    fail(title)
+  }
+}
+else if (title === 'AndroidLint Result') {
+  var content = fs.readFileSync('android/sdk/build/reports/lint-results.html', 'utf8')
+  // in xml report,Overview Section,Disabled Checks Section and Suppressing Warnings and Errors Section is not reported.
+  // in html report, those Section are included,
+  // but Overview Section can't work in markdown,
+  // on the other hand,Disabled Checks Section and Suppressing Warnings and Errors Section are not needed.
+  // the first section is Overview section,
+  // the last two section are  Disabled Checks Section and Suppressing Warnings and Errors Section.
+  // so we should grep the str from the second <section to the third </section> from last"
+  const occurance = content.split('</section>').length - 1
+  if (occurance > 3) {
+    content = content.substr(nth_occurrence(content, '<section ', 2))
+    content = content.substr(0, nth_occurrence(content, '</section>', occurance - 3))
+    fail(content)
+    fail(title)
+  }
+}
\ No newline at end of file
diff --git a/dangerfile-static-check.js b/dangerfile-static-check.js
new file mode 100644
index 0000000..2497588
--- /dev/null
+++ b/dangerfile-static-check.js
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { danger } from "danger";
+import fs from "fs";
+import path from 'path';
+import GitHubApi from 'github';
+import parseDiff from 'parse-diff';
+import shell from "shelljs";
+
+const type_unknown = 0;
+const type_c = 1;
+const type_android = 2;
+
+const getFileType = file => {
+    if (file.match(/.+\.(m|h|mm|cpp|cc)/)) {
+        return type_c;
+    } else if (file.match(/android/)) {
+        return type_android;
+    } else {
+        return type_unknown;
+    }
+}
+
+var hasCFile = false;
+var hasAndroidFile = false;
+
+function check(file_type) {
+    var has_file_type = false;
+    if (!has_file_type && danger.git.created_files) {
+        danger.git.created_files.some(file => {
+            var f = (getFileType(file) == file_type)
+            if (f) {
+                has_file_type = f;
+            }
+            return f;
+        });
+    }
+
+    if (!has_file_type && danger.git.modified_files) {
+        danger.git.modified_files.some(file => {
+            var f = (getFileType(file) == file_type)
+            if (f) {
+                has_file_type = f;
+            }
+            return f;
+        });
+    }
+
+    if (!has_file_type && danger.git.deleted_files) {
+        danger.git.deleted_files.some(file => {
+            var f = (getFileType(file) == file_type)
+            if (f) {
+                has_file_type = f;
+            }
+            return f;
+        });
+    }
+
+    return has_file_type
+}
+
+hasCFile = check(type_c)
+hasAndroidFile = check(type_android)
+
+var output_str = ""
+if (hasCFile) {
+    output_str += 'hasCFile\n'
+}
+if (hasAndroidFile) {
+    output_str += 'hasAndroidFile\n'
+}
+console.log(output_str)
diff --git a/ios/sdk/.gitignore b/ios/sdk/.gitignore
new file mode 100644
index 0000000..0dbf501
--- /dev/null
+++ b/ios/sdk/.gitignore
@@ -0,0 +1 @@
+*compile_commands.json
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXVersion.m b/ios/sdk/WeexSDK/Sources/Utility/WXVersion.m
index 0138907..2775310 100644
--- a/ios/sdk/WeexSDK/Sources/Utility/WXVersion.m
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXVersion.m
@@ -20,8 +20,8 @@
 #import "WXVersion.h"
 #import "WXDefine.h"
 
-static const char* WeexSDKBuildTime = "2019-07-16 07:08:34 UTC";
-static const unsigned long WeexSDKBuildTimestamp = 1563260914;
+static const char* WeexSDKBuildTime = "2019-07-21 09:08:41 UTC";
+static const unsigned long WeexSDKBuildTimestamp = 1563700121;
 
 NSString* GetWeexSDKVersion(void)
 {
diff --git a/package-lock.json b/package-lock.json
index 211b6b4..a16a0f3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3778,8 +3778,7 @@
           "version": "2.1.1",
           "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
           "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "aproba": {
           "version": "1.2.0",
@@ -3803,15 +3802,13 @@
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
           "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "brace-expansion": {
           "version": "1.1.11",
           "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
           "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
           "dev": true,
-          "optional": true,
           "requires": {
             "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
@@ -3828,22 +3825,19 @@
           "version": "1.1.0",
           "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
           "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "concat-map": {
           "version": "0.0.1",
           "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
           "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "console-control-strings": {
           "version": "1.1.0",
           "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
           "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "core-util-is": {
           "version": "1.0.2",
@@ -3974,8 +3968,7 @@
           "version": "2.0.3",
           "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
           "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "ini": {
           "version": "1.3.5",
@@ -3989,7 +3982,6 @@
           "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
           "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
           "dev": true,
-          "optional": true,
           "requires": {
             "number-is-nan": "^1.0.0"
           }
@@ -4006,7 +3998,6 @@
           "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
           "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
           "dev": true,
-          "optional": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
@@ -4015,15 +4006,13 @@
           "version": "0.0.8",
           "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
           "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "minipass": {
           "version": "2.2.4",
           "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz",
           "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==",
           "dev": true,
-          "optional": true,
           "requires": {
             "safe-buffer": "^5.1.1",
             "yallist": "^3.0.0"
@@ -4044,7 +4033,6 @@
           "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
           "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
           "dev": true,
-          "optional": true,
           "requires": {
             "minimist": "0.0.8"
           }
@@ -4133,8 +4121,7 @@
           "version": "1.0.1",
           "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
           "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "object-assign": {
           "version": "4.1.1",
@@ -4148,7 +4135,6 @@
           "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
           "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
           "dev": true,
-          "optional": true,
           "requires": {
             "wrappy": "1"
           }
@@ -4244,8 +4230,7 @@
           "version": "5.1.1",
           "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
           "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "safer-buffer": {
           "version": "2.1.2",
@@ -4287,7 +4272,6 @@
           "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
           "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
           "dev": true,
-          "optional": true,
           "requires": {
             "code-point-at": "^1.0.0",
             "is-fullwidth-code-point": "^1.0.0",
@@ -4309,7 +4293,6 @@
           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
           "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
           "dev": true,
-          "optional": true,
           "requires": {
             "ansi-regex": "^2.0.0"
           }
@@ -4358,15 +4341,13 @@
           "version": "1.0.2",
           "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
           "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "yallist": {
           "version": "3.0.2",
           "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz",
           "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=",
-          "dev": true,
-          "optional": true
+          "dev": true
         }
       }
     },
diff --git a/package.json b/package.json
index 80cccf9..28cb05c 100644
--- a/package.json
+++ b/package.json
@@ -97,7 +97,7 @@
     "chromedriver": "^2.21.2",
     "cross-spawn": "^4.0.0",
     "css-loader": "^0.26.1",
-    "danger": "^0.18.0",
+    "danger": "^9.0.0",
     "dateformat": "^2.0.0",
     "eslint": "^2.11.1",
     "eslint-plugin-flowtype": "^2.40.1",