Skip to content

Commit

Permalink
Output JUnit XML metadata for CircleCi
Browse files Browse the repository at this point in the history
Fixes #11949
  • Loading branch information
benbraou committed Jan 14, 2018
1 parent 65aeb70 commit eec8248
Show file tree
Hide file tree
Showing 21 changed files with 602 additions and 74 deletions.
11 changes: 11 additions & 0 deletions .circleci/config.yml
Expand Up @@ -8,6 +8,8 @@ jobs:
environment:
TZ: /usr/share/zoneinfo/America/Los_Angeles
TRAVIS_REPO_SLUG: facebook/react
REPORT_FORMATTER: junit
REPORT_DIR: reports/junit

parallelism: 4

Expand All @@ -34,6 +36,15 @@ jobs:
- run:
name: Test Packages
command: ./scripts/circleci/test_entry_point.sh
environment:
JEST_JUNIT_OUTPUT: "reports/junit/jest.xml"
JEST_PROCESSOR: "jest-junit"

- store_test_results:
path: reports/junit

- store_artifacts:
path: reports/junit

- save_cache:
name: Save node_modules cache
Expand Down
2 changes: 2 additions & 0 deletions package.json
Expand Up @@ -68,6 +68,8 @@
"gzip-size": "^3.0.0",
"jasmine-check": "^1.0.0-rc.0",
"jest": "^22.0.4",
"jest-junit": "^3.4.1",
"junit-merge": "^1.2.3",
"merge-stream": "^1.0.0",
"minimatch": "^3.0.4",
"minimist": "^1.2.0",
Expand Down
15 changes: 11 additions & 4 deletions scripts/circleci/build.sh
@@ -1,17 +1,24 @@
#!/bin/bash

set -e
#!/bin/bash

TEMPORARY_LOG_FILE="local_size_measurements-errors.log"

. ./scripts/circleci/common.sh

# Update the local size measurements to the master version
# so that the size diff printed at the end of the build is
# accurate.
curl -o scripts/rollup/results.json http://react.zpao.com/builds/master/latest/results.json
process_curl "build" "$REPORT_FORMATTER" "$TEMPORARY_LOG_FILE" curl \
-sS -o scripts/rollup/results.json http://react.zpao.com/builds/master/latest/results.json

set -e

yarn build --extract-errors

# Note: since we run the full build including extracting error codes,
# it is important that we *don't* reset the change to `scripts/error-codes/codes.json`.
# When production bundle tests run later, it needs to be available.
# See https://github.com/facebook/react/pull/11655.

# Do a sanity check on bundles

yarn lint-build
10 changes: 8 additions & 2 deletions scripts/circleci/check_license.sh
Expand Up @@ -6,8 +6,14 @@ set -e
EXPECTED='scripts/circleci/check_license.sh'
ACTUAL=$(git grep -l PATENTS)

ANNOUNCEMENT=$(echo "PATENTS crept into some new files?")
DIFF=$(diff -u <(echo "$EXPECTED") <(echo "$ACTUAL") || true)
DATA=$ANNOUNCEMENT$DIFF

if [ "$EXPECTED" != "$ACTUAL" ]; then
echo "PATENTS crept into some new files?"
diff -u <(echo "$EXPECTED") <(echo "$ACTUAL") || true
echo "$DATA"
if [ "$REPORT_FORMATTER" = "junit" ]; then
./scripts/circleci/write_junit_report.sh "check_license" "$DATA" false
fi
exit 1
fi
12 changes: 9 additions & 3 deletions scripts/circleci/check_modules.sh
Expand Up @@ -10,12 +10,18 @@ packages/shared/ReactTypes.js
scripts/rollup/wrappers.js'
ACTUAL=$(git grep -l @providesModule -- './*.js' ':!scripts/rollup/shims/*.js')

# Colors
# Colors^
red=$'\e[1;31m'
end=$'\e[0m'

ANNOUNCEMENT=$(printf "%s\n" "${red}ERROR: @providesModule crept into some new files?${end}")
DIFF=$(diff -u <(echo "$EXPECTED") <(echo "$ACTUAL") || true)
DATA=$ANNOUNCEMENT$DIFF

if [ "$EXPECTED" != "$ACTUAL" ]; then
printf "%s\n" "${red}ERROR: @providesModule crept into some new files?${end}"
diff -u <(echo "$EXPECTED") <(echo "$ACTUAL") || true
echo "$DATA"
if [ "$REPORT_FORMATTER" = "junit" ]; then
./scripts/circleci/write_junit_report.sh "check_modules" "$DATA" false
fi
exit 1
fi
31 changes: 31 additions & 0 deletions scripts/circleci/common.sh
@@ -0,0 +1,31 @@

redirect_stderr() {
REPORT_FORMATTER=$1
TEMPORARY_LOG_FILE=$2

if [ "$REPORT_FORMATTER" = "junit" ]; then
"${@:3}" 2> "$TEMPORARY_LOG_FILE"
else
"${@:3}"
fi
}

process_curl() {
BUILD_STEP=$1
REPORT_FORMATTER=$2
TEMPORARY_LOG_FILE=$3

redirect_stderr "$REPORT_FORMATTER" "$TEMPORARY_LOG_FILE" "${@:4}"

if [ "$REPORT_FORMATTER" = "junit" ]; then
ERROR=$(cat "$TEMPORARY_LOG_FILE")
if [ "$ERROR" != "" ];then
echo $ERROR
./scripts/circleci/write_junit_report.sh "$BUILD_STEP" "$ERROR" false
fi
rm -f $TEMPORARY_LOG_FILE
if [ "$ERROR" != "" ];then
exit 1
fi
fi
}
2 changes: 1 addition & 1 deletion scripts/circleci/test_coverage.sh
Expand Up @@ -2,7 +2,7 @@

set -e

yarn test --coverage --runInBand
yarn test --coverage --runInBand --testResultsProcessor=${JEST_PROCESSOR}
if [ -z $CI_PULL_REQUEST ]; then
cat ./coverage/lcov.info | ./node_modules/.bin/coveralls
fi
Expand Down
10 changes: 5 additions & 5 deletions scripts/circleci/test_entry_point.sh
Expand Up @@ -7,24 +7,24 @@ set -e
COMMANDS_TO_RUN=()

if [ $((0 % CIRCLE_NODE_TOTAL)) -eq "$CIRCLE_NODE_INDEX" ]; then
COMMANDS_TO_RUN+=('node ./scripts/prettier/index')
COMMANDS_TO_RUN+=('node ./scripts/prettier/index check')
COMMANDS_TO_RUN+=('node ./scripts/tasks/flow')
COMMANDS_TO_RUN+=('node ./scripts/tasks/eslint')
COMMANDS_TO_RUN+=('yarn test --runInBand')
COMMANDS_TO_RUN+=("yarn test --runInBand --testResultsProcessor=${JEST_PROCESSOR}")
COMMANDS_TO_RUN+=('./scripts/circleci/check_license.sh')
COMMANDS_TO_RUN+=('./scripts/circleci/check_modules.sh')
COMMANDS_TO_RUN+=('./scripts/circleci/test_print_warnings.sh')
COMMANDS_TO_RUN+=('./scripts/circleci/track_stats.sh')
fi

if [ $((1 % CIRCLE_NODE_TOTAL)) -eq "$CIRCLE_NODE_INDEX" ]; then
COMMANDS_TO_RUN+=('yarn test-prod --runInBand')
COMMANDS_TO_RUN+=("yarn test-prod --runInBand --testResultsProcessor=${JEST_PROCESSOR}")
fi

if [ $((2 % CIRCLE_NODE_TOTAL)) -eq "$CIRCLE_NODE_INDEX" ]; then
COMMANDS_TO_RUN+=('./scripts/circleci/build.sh')
COMMANDS_TO_RUN+=('yarn test-build --runInBand')
COMMANDS_TO_RUN+=('yarn test-build-prod --runInBand')
COMMANDS_TO_RUN+=("yarn test-build --runInBand --testResultsProcessor=${JEST_PROCESSOR}")
COMMANDS_TO_RUN+=("yarn test-build-prod --runInBand --testResultsProcessor=${JEST_PROCESSOR}")
COMMANDS_TO_RUN+=('./scripts/circleci/upload_build.sh')
fi

Expand Down
11 changes: 9 additions & 2 deletions scripts/circleci/upload_build.sh
@@ -1,9 +1,11 @@
#!/bin/bash

set -e
. ./scripts/circleci/common.sh

TEMPORARY_LOG_FILE="upload_build-errors.log"

if [ -z $CI_PULL_REQUEST ] && [ -n "$BUILD_SERVER_ENDPOINT" ]; then
curl \
process_curl "upload_build" "$REPORT_FORMATTER" "$TEMPORARY_LOG_FILE" curl \
-F "react.development=@build/dist/react.development.js" \
-F "react.production.min=@build/dist/react.production.min.js" \
-F "react-dom.development=@build/dist/react-dom.development.js" \
Expand All @@ -18,3 +20,8 @@ if [ -z $CI_PULL_REQUEST ] && [ -n "$BUILD_SERVER_ENDPOINT" ]; then
-F "branch=$CIRCLE_BRANCH" \
$BUILD_SERVER_ENDPOINT
fi





7 changes: 7 additions & 0 deletions scripts/circleci/write_junit_report.sh
@@ -0,0 +1,7 @@
#!/bin/bash

set -e

node ./scripts/tasks/junit "$1" "$2" "$3"


30 changes: 26 additions & 4 deletions scripts/eslint/index.js
Expand Up @@ -11,14 +11,20 @@ const minimatch = require('minimatch');
const CLIEngine = require('eslint').CLIEngine;
const listChangedFiles = require('../shared/listChangedFiles');
const {es5Paths, esNextPaths} = require('../shared/pathsByLanguageVersion');

const allPaths = ['**/*.js'];
const {
isJunitEnabled,
writePartialJunitReport,
mergePartialJunitReports,
} = require('../shared/reporting');

let changedFiles = null;

const allPaths = ['**/*.js'];

function runESLintOnFilesWithOptions(filePatterns, onlyChanged, options) {
const cli = new CLIEngine(options);
const formatter = cli.getFormatter();
// stylish is the default ESLint formatter. We switch to JUnit formatter in the scope of circleci
const formatter = cli.getFormatter(isJunitEnabled() ? 'junit' : 'stylish');

if (onlyChanged && changedFiles === null) {
// Calculate lazily.
Expand Down Expand Up @@ -65,6 +71,8 @@ function runESLint({onlyChanged}) {
if (typeof onlyChanged !== 'boolean') {
throw new Error('Pass options.onlyChanged as a boolean.');
}
const mutableESLintTemporaryFiles = [];

let errorCount = 0;
let warningCount = 0;
let output = '';
Expand All @@ -79,12 +87,26 @@ function runESLint({onlyChanged}) {
runESLintOnFilesWithOptions(es5Paths, onlyChanged, {
configFile: `${__dirname}/eslintrc.es5.js`,
}),
].forEach(result => {
].forEach((result, index) => {
errorCount += result.errorCount;
warningCount += result.warningCount;
output += result.output;

if (isJunitEnabled()) {
// we create a JUnit file per run and then we merge them into one using junit-merge.
writePartialJunitReport(
'eslint',
result.output,
index,
mutableESLintTemporaryFiles
);
}
});
// Whether we store lint results in a file or not, we also log the results in the console
console.log(output);
if (isJunitEnabled()) {
mergePartialJunitReports('eslint', mutableESLintTemporaryFiles);
}
return errorCount === 0 && warningCount === 0;
}

Expand Down

0 comments on commit eec8248

Please sign in to comment.