diff --git a/.circleci/config.yml b/.circleci/config.yml
index 6a19d4d7ab01..682a6732414f 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -591,38 +591,38 @@ jobs:
       - run:
           name: Analyze Shell Scripts
           command: |
-            if [ -n "$CIRCLE_PR_NUMBER" ]; then
-              echo -e "\\x1B[36mInstalling additional dependencies\\x1B[0m"
-              sudo apt-get install -y shellcheck
-              yarn add @octokit/rest@15.10.0
-              echo -e "\\x1B[36mAnalyzing shell scripts\\x1B[0m"
-              GITHUB_TOKEN="$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A""$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B" ./scripts/circleci/analyze_scripts.sh
-            else
-              echo "Skipping shell script analysis."
-            fi
+            echo -e "\\x1B[36mInstalling additional dependencies\\x1B[0m"
+            sudo apt-get install -y shellcheck
+            yarn add @octokit/rest@15.10.0
+            echo -e "\\x1B[36mAnalyzing shell scripts\\x1B[0m"; \
+            GITHUB_TOKEN="$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A""$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B" \
+            GITHUB_OWNER="$CIRCLE_PROJECT_USERNAME" \
+            GITHUB_REPO="$CIRCLE_PROJECT_REPONAME" \
+            GITHUB_PR_NUMBER="$CIRCLE_PR_NUMBER" \
+            ./scripts/circleci/analyze_scripts.sh
           when: always
 
       - run:
           name: Analyze Code
           command: |
-            if [ -n "$CIRCLE_PR_NUMBER" ]; then
-              echo -e "\\x1B[36mInstalling additional dependencies\\x1B[0m"; yarn add @octokit/rest@15.10.0
-              echo -e "\\x1B[36mAnalyzing code\\x1B[0m"; GITHUB_TOKEN="$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A""$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B" ./scripts/circleci/analyze_code.sh
-            else
-              echo "Skipping code analysis."
-            fi
+            echo -e "\\x1B[36mInstalling additional dependencies\\x1B[0m"; yarn add @octokit/rest@15.10.0
+            echo -e "\\x1B[36mAnalyzing code\\x1B[0m"; \
+            GITHUB_TOKEN="$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A""$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B" \
+            GITHUB_OWNER="$CIRCLE_PROJECT_USERNAME" \
+            GITHUB_REPO="$CIRCLE_PROJECT_REPONAME" \
+            GITHUB_PR_NUMBER="$CIRCLE_PR_NUMBER" \
+            ./scripts/circleci/analyze_code.sh
           when: always
 
       - run:
           name: Analyze Pull Request
           command: |
-            if [ -n "$CIRCLE_PR_NUMBER" ]; then
-              cd bots
-              yarn install --non-interactive --cache-folder ~/.cache/yarn
-              DANGER_GITHUB_API_TOKEN="$PUBLIC_PULLBOT_GITHUB_TOKEN_A""$PUBLIC_PULLBOT_GITHUB_TOKEN_B" yarn danger
-            else
-              echo "Skipping pull request analysis."
-            fi
+            echo -e "\\x1B[36mInstalling additional dependencies\\x1B[0m"
+            cd bots
+            yarn install --non-interactive --cache-folder ~/.cache/yarn
+            echo -e "\\x1B[36mAnalyzing pull request\\x1B[0m"; \
+            DANGER_GITHUB_API_TOKEN="$PUBLIC_PULLBOT_GITHUB_TOKEN_A""$PUBLIC_PULLBOT_GITHUB_TOKEN_B" \
+            yarn danger
           when: always
       - save-cache: *save-cache-analysis
 
@@ -730,6 +730,8 @@ workflows:
             tags:
               only: /v[0-9]+(\.[0-9]+)*(\-rc(\.[0-9]+)?)?/
 
-      # Run code checks
+      # Run code checks on PRs from forks
       - analyze_pr:
-          filters: *filter-ignore-master-stable
+          filters:
+            branches:
+              only: /^pull\/.*$/
diff --git a/scripts/circleci/analyze_code.sh b/scripts/circleci/analyze_code.sh
index a2953e45c574..ef55d484e91a 100755
--- a/scripts/circleci/analyze_code.sh
+++ b/scripts/circleci/analyze_code.sh
@@ -9,7 +9,7 @@ cat <(echo eslint; npm run lint --silent -- --format=json; echo flow; npm run fl
 # check status
 STATUS=$?
 if [ $STATUS == 0 ]; then
-  echo "Code analyzed successfully"
+  echo "Code analyzed successfully."
 else
-  echo "Code analysis failed, error status $STATUS"
+  echo "Code analysis failed, error status $STATUS."
 fi
diff --git a/scripts/circleci/analyze_scripts.sh b/scripts/circleci/analyze_scripts.sh
index 730f00f5a30c..052688cab9ba 100755
--- a/scripts/circleci/analyze_scripts.sh
+++ b/scripts/circleci/analyze_scripts.sh
@@ -13,7 +13,7 @@ cat <(echo shellcheck; printf '%s\n' "${results[@]}" | jq .,[] | jq -s . | jq --
 # check status
 STATUS=$?
 if [ $STATUS == 0 ]; then
-  echo "Shell scripts analyzed successfully"
+  echo "Shell scripts analyzed successfully."
 else
-  echo "Shell script analysis failed, error status $STATUS"
+  echo "Shell script analysis failed, error status $STATUS."
 fi
diff --git a/scripts/circleci/code-analysis-bot.js b/scripts/circleci/code-analysis-bot.js
index 0e5a3d5be70a..86f21ab69f52 100644
--- a/scripts/circleci/code-analysis-bot.js
+++ b/scripts/circleci/code-analysis-bot.js
@@ -9,12 +9,12 @@
 
 'use strict';
 
-if (!process.env.CIRCLE_PROJECT_USERNAME) {
-  console.error('Missing CIRCLE_PROJECT_USERNAME. Example: facebook');
+if (!process.env.GITHUB_OWNER) {
+  console.error('Missing GITHUB_OWNER. Example: facebook');
   process.exit(1);
 }
-if (!process.env.CIRCLE_PROJECT_REPONAME) {
-  console.error('Missing CIRCLE_PROJECT_REPONAME. Example: react-native');
+if (!process.env.GITHUB_REPO) {
+  console.error('Missing GITHUB_REPO. Example: react-native');
   process.exit(1);
 }
 
@@ -162,35 +162,51 @@ function getLineMapFromPatch(patchString) {
   return lineMap;
 }
 
-function sendReview(owner, repo, number, commit_id, comments, convertersUsed) {
-  if (comments.length === 0) {
-    // Do not leave an empty review.
-    return;
-  }
-
-  let body = '**Code analysis results:**\n\n';
-  convertersUsed.forEach(converter => {
-    body += '* `' + converter + '` found some issues.\n';
-  });
-
-  const event = 'REQUEST_CHANGES';
-
-  const opts = {
-    owner,
-    repo,
-    number,
-    commit_id,
-    body,
-    event,
-    comments,
-  };
+function sendReview(owner, repo, number, commit_id, body, comments) {
+  if (process.env.GITHUB_TOKEN) {
+    if (comments.length === 0) {
+      // Do not leave an empty review.
+      return;
+    }
 
-  octokit.pullRequests.createReview(opts, function(error, res) {
-    if (error) {
-      console.error(error);
+    const event = 'REQUEST_CHANGES';
+
+    const opts = {
+      owner,
+      repo,
+      number,
+      commit_id,
+      body,
+      event,
+      comments,
+    };
+
+    octokit.pullRequests.createReview(opts, function(error, res) {
+      if (error) {
+        console.error(error);
+        return;
+      }
+    });
+  } else {
+    if (comments.length === 0) {
+      console.log('No issues found.');
       return;
     }
-  });
+
+    if (process.env.CIRCLE_CI) {
+      console.error(
+        'Code analysis found issues, but the review cannot be posted to GitHub without an access token.',
+      );
+      process.exit(1);
+    }
+
+    let results = body + '\n';
+    comments.forEach(comment => {
+      results +=
+        comment.path + ':' + comment.position + ': ' + comment.body + '\n';
+    });
+    console.log(results);
+  }
 }
 
 function main(messages, owner, repo, number) {
@@ -199,18 +215,17 @@ function main(messages, owner, repo, number) {
     return;
   }
 
-  if (!process.env.GITHUB_TOKEN) {
-    console.error(
-      'Missing GITHUB_TOKEN. Example: 5fd88b964fa214c4be2b144dc5af5d486a2f8c1e',
+  if (process.env.GITHUB_TOKEN) {
+    octokit.authenticate({
+      type: 'oauth',
+      token: process.env.GITHUB_TOKEN,
+    });
+  } else {
+    console.log(
+      'Missing GITHUB_TOKEN. Example: 5fd88b964fa214c4be2b144dc5af5d486a2f8c1e. Review feedback with code analysis results will not be provided on GitHub.',
     );
-    process.exit(1);
   }
 
-  octokit.authenticate({
-    type: 'oauth',
-    token: process.env.GITHUB_TOKEN,
-  });
-
   getShaFromPullRequest(owner, repo, number, sha => {
     getFilesFromCommit(owner, repo, sha, files => {
       let comments = [];
@@ -234,7 +249,13 @@ function main(messages, owner, repo, number) {
         }); // forEach
       }); // filter
 
-      sendReview(owner, repo, number, sha, comments, convertersUsed);
+      let body = '**Code analysis results:**\n\n';
+      const uniqueconvertersUsed = [...new Set(convertersUsed)];
+      uniqueconvertersUsed.forEach(converter => {
+        body += '* `' + converter + '` found some issues.\n';
+      });
+
+      sendReview(owner, repo, number, sha, body, comments);
     }); // getFilesFromCommit
   }); // getShaFromPullRequest
 }
@@ -287,16 +308,16 @@ process.stdin.on('end', function() {
     delete messages[absolutePath];
   }
 
-  const owner = process.env.CIRCLE_PROJECT_USERNAME;
-  const repo = process.env.CIRCLE_PROJECT_REPONAME;
+  const owner = process.env.GITHUB_OWNER;
+  const repo = process.env.GITHUB_REPO;
 
-  if (!process.env.CIRCLE_PR_NUMBER) {
-    console.error('Missing CIRCLE_PR_NUMBER. Example: 4687');
+  if (!process.env.GITHUB_PR_NUMBER) {
+    console.error('Missing GITHUB_PR_NUMBER. Example: 4687');
     // for master branch, don't throw an error
     process.exit(0);
   }
 
-  const number = process.env.CIRCLE_PR_NUMBER;
+  const number = process.env.GITHUB_PR_NUMBER;
 
   // intentional lint warning to make sure that the bot is working :)
   main(messages, owner, repo, number);
