diff --git a/.buildkite/eslint-formatter-buildkite.js b/.buildkite/eslint-formatter-buildkite.js new file mode 100644 index 000000000..7acc52da9 --- /dev/null +++ b/.buildkite/eslint-formatter-buildkite.js @@ -0,0 +1,108 @@ +const spawnSync = require('child_process').spawnSync; +const relative = require('path').relative; + +module.exports = function(results) { + const { warning, error } = results.reduce( + function(acc, file) { + if (file.errorCount > 0) { + acc.error.push(file); + } + + if (file.warningCount > 0) { + acc.warning.push(file); + } + + return acc; + }, + { + warning: [], + error: [] + } + ); + + if (error.length > 0) { + let errorOutput = ` +#### ESLint Errors + +${ + error.map(function(file) { + return ` +
${relative('.', file.filePath)} + +${ + file.messages.map(function(message) { + if (message.severity !== 2) { + return ''; + } + + return `${message.line}:${message.column}: ${message.message} (${message.ruleId})`; + }).join('\n\n') +} + +
`; + + // return JSON.stringify(file, null, 2); + }).join('\n\n') +}`; + + if (process.env["BUILDKITE"]) { + const result = spawnSync( + 'buildkite-agent', [ 'annotate', '--context', 'eslint-errors', '--style', 'error', ], + { encoding: 'utf8', input: errorOutput } + ); + + console.log(result.output.join('\n')); + console.log('Exit code: ' + result.status); + + if (result.error) { + throw result.error; + } + } else { + console.log(errorOutput); + } + } + + if (warning.length > 0) { + let warningOutput = ` +#### ESLint Warnings + +${ + warning.map(function(file) { + return ` +
${relative('.', file.filePath)} + +${ + file.messages.map(function(message) { + if (message.severity > 1) { + return ''; + } + + return `${message.line}:${message.column}: ${message.message} (${message.ruleId})`; + }).join('\n\n') +} + +
`; + + // return JSON.stringify(file, null, 2); + }).join('\n\n') +}`; + + if (process.env["BUILDKITE"]) { + const result = spawnSync( + 'buildkite-agent', [ 'annotate', '--context', 'eslint-warnings', '--style', 'warning' ], + { encoding: 'utf8', input: warningOutput } + ); + + console.log(result.output.join('\n')); + console.log('Exit code: ' + result.status); + + if (result.error) { + throw result.error; + } + } else { + console.log(warningOutput); + } + } + + return ''; +}; diff --git a/.buildkite/eslint-formatter-multi.js b/.buildkite/eslint-formatter-multi.js new file mode 100644 index 000000000..10e0d8d36 --- /dev/null +++ b/.buildkite/eslint-formatter-multi.js @@ -0,0 +1,32 @@ +// Pull in ESLint's own "getFormatter" method (https://git.io/fpAqw), which +// normalises both ESLint's friendly names, npm package names, and files +// on-disk, and then returns the result of requiring them. +let getFormatter = require('eslint/lib/cli-engine').prototype.getFormatter.bind({}); + +module.exports = function(results) { + // Since ESLint doesn't give us access to any context or config, + // we have to resort to pulling Environment Variables + let formatters = ( + process.env['ESLINT_MULTI_FORMATTERS'].split(';') + || [ false ] + ); + + // Map over each formatter, calling it with the result array we got given, + // then return the combination of all the outputs. + return formatters + .map(function (formatterName) { + let formatter = getFormatter(formatterName); + + // TODO: When would this happen, and not just be a thrown error? + if (!formatter) { + console.debug('Weird! "' + formatterName + '" isn\'t a real formatter...'); + return; + } + + return formatter(results); + }) + .filter(function(output) { + return output && output.trim().length > 0; + }) + .join('\n\n'); +}; diff --git a/Dockerfile b/Dockerfile index 2ee7a401f..b2e478b53 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,16 @@ EXPOSE 4890 ENV EMOJI_HOST=http://buildkite.localhost/_frontend/vendor/emojis +ADD --chown=root:root https://apt.buildkite.com/keys/6452D198.asc /etc/apt/trusted.gpg.d/buildkite.asc + +RUN echo "--- :package: Installing system deps" \ + # Buildkite apt sources + && chmod 644 /etc/apt/trusted.gpg.d/buildkite.asc \ + && echo "deb http://apt.buildkite.com/buildkite-agent unstable main" > /etc/apt/sources.list.d/buildkite.list \ + # Install buildkite-agent + && apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install --assume-yes --no-install-recommends buildkite-agent + WORKDIR /frontend # Install yarn dependencies diff --git a/app/components/layout/Navigation/index.js b/app/components/layout/Navigation/index.js index 07cb9b3ff..1576aa72c 100644 --- a/app/components/layout/Navigation/index.js +++ b/app/components/layout/Navigation/index.js @@ -82,7 +82,7 @@ class Navigation extends React.PureComponent { ) { this.setState({ lastDefaultTeam: UserSessionStore.get(`organization-default-team:${nextProps.organization.id}`) - }); + }) } } diff --git a/docker-compose.yml b/docker-compose.yml index 7b8321c03..59750c2ac 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,8 +9,11 @@ services: - BUILDKITE_COMMIT - BUILDKITE_ORGANIZATION_SLUG - BUILDKITE_PIPELINE_SLUG + - BUILDKITE_BUILD_URL + - BUILDKITE_JOB_ID + - BUILDKITE_AGENT_ACCESS_TOKEN - CI volumes: - "./bundle-analysis:/frontend/bundle-analysis" - "./coverage:/frontend/coverage" - - "./dist:/host/dist" \ No newline at end of file + - "./dist:/host/dist" diff --git a/package.json b/package.json index b6ad2d38a..c2a37d85b 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,8 @@ "test": "NODE_ENV=test jest --colors", "test-with-coverage": "yarn test --coverage", "flow": "flow", - "lint": "eslint . --color", - "lint-and-fix": "eslint --fix --color .", + "lint": "ESLINT_MULTI_FORMATTERS=\"stylish;./.buildkite/eslint-formatter-buildkite.js\" eslint . -f='./.buildkite/eslint-formatter-multi.js' --color", + "lint-and-fix": "ESLINT_MULTI_FORMATTERS=\"stylish;./.buildkite/eslint-formatter-buildkite.js\" eslint --fix -f='./.buildkite/eslint-formatter-multi.js' --color .", "relay-compile": "relay-compiler --schema app/graph/schema.json --src app", "prebuild": "yarn run relay-compile", "build": "NODE_ENV=development webpack --config webpack/config.js --progress --bail --cache",