diff --git a/.sentryclirc b/.sentryclirc new file mode 100644 index 0000000..d480dc3 --- /dev/null +++ b/.sentryclirc @@ -0,0 +1,3 @@ +[defaults] +org = enix +project = gitako diff --git a/package.json b/package.json index 59594d5..a0d8b8f 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,10 @@ "postinstall": "node scripts/generate-octicon.js", "start": "webpack --watch", "postversion": "node scripts/version.js && npm run build", - "build": "NODE_ENV=production webpack && npm run postbuild", - "postbuild": "cd dist && rm -f ./gitako.zip && zip gitako.zip -r *" + "build": "./scripts/roll.sh" }, "dependencies": { + "@sentry/browser": "^4.6.4", "ini": "^1.3.5", "js-base64": "^2.5.1", "nprogress": "^0.2.0", @@ -30,6 +30,7 @@ "@babel/preset-env": "^7.3.4", "@babel/preset-react": "^7.0.0", "@babel/preset-typescript": "^7.3.3", + "@sentry/cli": "^1.40.0", "@svgr/webpack": "^4.1.0", "@types/chrome": "^0.0.81", "@types/ini": "^1.3.30", diff --git a/scripts/get-version.js b/scripts/get-version.js new file mode 100644 index 0000000..9186eda --- /dev/null +++ b/scripts/get-version.js @@ -0,0 +1,3 @@ +const { version } = require('../package.json') +console.log(version) +module.exports = version diff --git a/scripts/roll.sh b/scripts/roll.sh new file mode 100755 index 0000000..fba38d3 --- /dev/null +++ b/scripts/roll.sh @@ -0,0 +1,14 @@ +#!/bin/sh +rm -rf dist +NODE_ENV=production yarn webpack +GITAKO_VERSION=$(node scripts/get-version.js) +echo "Got version $GITAKO_VERSION" + +# sentry +yarn sentry-cli releases new "$GITAKO_VERSION" +yarn sentry-cli releases files "$GITAKO_VERSION" upload-sourcemaps dist --no-rewrite +yarn sentry-cli releases finalize "$GITAKO_VERSION" + +cd dist +rm -f ./gitako.zip +zip -r gitako.zip * -x *.map diff --git a/scripts/version.js b/scripts/version.js index 470e218..11dad2f 100644 --- a/scripts/version.js +++ b/scripts/version.js @@ -8,23 +8,22 @@ const path = require('path') const cp = require('child_process') const rootPath = path.resolve(__dirname, '../') -const packagePath = path.resolve(rootPath, 'package.json') const manifestPath = path.resolve(rootPath, 'src/manifest.json') -const packageJSON = require(packagePath) const manifest = require(manifestPath) +const version = require('./get-version') -const version = packageJSON.version manifest.version = version fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, ' '), 'utf-8') -const exec = command => new Promise((resolve, reject) => cp.exec(command, (error, stdout, stderr) => - error ? reject(error) : resolve(stdout || stderr) -)) +const exec = command => + new Promise((resolve, reject) => + cp.exec(command, (error, stdout, stderr) => + error ? reject(error) : resolve(stdout || stderr), + ), + ) exec(`git tag -d v${version}`) - .then(() => - exec(`git add src/manifest.json && git commit --amend --no-edit`) - ).then(() => - exec(`git tag v${version}`) - ).catch(console.error) + .then(() => exec(`git add src/manifest.json && git commit --amend --no-edit`)) + .then(() => exec(`git tag v${version}`)) + .catch(console.error) diff --git a/src/analytics.ts b/src/analytics.ts index e1ac487..6d507f9 100644 --- a/src/analytics.ts +++ b/src/analytics.ts @@ -1,11 +1,19 @@ import { Middleware } from 'driver/connect.js' import { IN_PRODUCTION_MODE } from 'env' +import * as Sentry from '@sentry/browser' import { version } from '../package.json' -// TODO: set this through ENV or something else -const LOG_ENDPOINT = 'https://enix.one/gitako/log' -export function raiseError(error: Error) { - return reportError(error) +const PUBLIC_KEY = 'd22ec5c9cc874539a51c78388c12e3b0' +const PROJECT_ID = '1406497' + +Sentry.init({ + dsn: `https://${PUBLIC_KEY}@sentry.io/${PROJECT_ID}`, + release: version, + environment: IN_PRODUCTION_MODE ? 'production' : 'development', +}) + +export function raiseError(error: Error, extra?: any) { + return reportError(error, extra) } export const withErrorLog: Middleware = function withErrorLog(method, args) { @@ -21,26 +29,19 @@ export const withErrorLog: Middleware = function withErrorLog(method, args) { ] } -function encodeParams< - T extends { - [key: string]: any - } ->(params: T) { - return Object.keys(params) - .map((key: keyof T) => `${key}=${encodeURIComponent(JSON.stringify(params[key]))}`) - .join('&') -} - -function reportError(error: Error) { - const reportBody = { - stack: error.stack, - error: (error && error.message) || error, - path: window.location.href, - version, - } +function reportError(error: Error, extra?: any) { if (!IN_PRODUCTION_MODE) { - console.error(reportBody) - return + console.error(error) + console.error('Extra:\n', extra) + // return + } + + Sentry.captureException(error) + if (extra) { + Sentry.withScope(scope => { + Object.keys(extra).forEach(key => { + scope.setExtra(key, extra[key]) + }) + }) } - return fetch(`${LOG_ENDPOINT}?${encodeParams(reportBody)}`) } diff --git a/src/components/Gitako.tsx b/src/components/Gitako.tsx index ad37b77..bb74311 100644 --- a/src/components/Gitako.tsx +++ b/src/components/Gitako.tsx @@ -3,8 +3,8 @@ import SideBar from 'components/SideBar' import { raiseError } from 'analytics' export default class Gitako extends React.PureComponent { - componentDidCatch(error: Error) { - raiseError(error) + componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { + raiseError(error, errorInfo) } render() { diff --git a/yarn.lock b/yarn.lock index 0d7a586..ea96097 100644 --- a/yarn.lock +++ b/yarn.lock @@ -718,6 +718,70 @@ lodash "^4.17.11" to-fast-properties "^2.0.0" +"@sentry/browser@^4.6.4": + version "4.6.4" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-4.6.4.tgz#94e376be7bb313b6faf9e40950405897dd1c1605" + integrity sha512-w2ITpQbs2vTKS5vtPXDgeDyr+5C4lCnTXugJrqn8u8w/XaDb3vRogfMWpQcaUENllO5xdZSItSAAHsQucY/LvA== + dependencies: + "@sentry/core" "4.6.4" + "@sentry/types" "4.5.3" + "@sentry/utils" "4.6.4" + tslib "^1.9.3" + +"@sentry/cli@^1.40.0": + version "1.40.0" + resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.40.0.tgz#ab6565034d63bb6dfa840954f16efb058578fbcb" + integrity sha512-xn9MnHPnH9d8/BnOCg9GubGhdXTv+aZ+4ax0YEsjQklq8u9GfFZVpBQJ0cykMUBup7+DHmyGGga8qcoO9ew0gw== + dependencies: + fs-copy-file-sync "^1.1.1" + https-proxy-agent "^2.2.1" + mkdirp "^0.5.1" + node-fetch "^2.1.2" + progress "2.0.0" + proxy-from-env "^1.0.0" + +"@sentry/core@4.6.4": + version "4.6.4" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-4.6.4.tgz#7236e08115423b81b96a13c2c37f29bcc1477745" + integrity sha512-NGl2nkAaQ8dGqJAMS1Hb+7RyVjW4tmCbK6d7H/zKnOpBuU+qSW4XCm2NoGLLa8qb4SZUPIBRv6U0ByvEQlGtqw== + dependencies: + "@sentry/hub" "4.6.4" + "@sentry/minimal" "4.6.4" + "@sentry/types" "4.5.3" + "@sentry/utils" "4.6.4" + tslib "^1.9.3" + +"@sentry/hub@4.6.4": + version "4.6.4" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-4.6.4.tgz#2bd5d67ccd43d4f5afc45005a330a11b14d46cea" + integrity sha512-R3ACxUZbrAMP6vyIvt1k4bE3OIyg1CzbEhzknKljPrk1abVmJVP7W/X1vBysdRtI3m/9RjOSO7Lxx3XXqoHoQg== + dependencies: + "@sentry/types" "4.5.3" + "@sentry/utils" "4.6.4" + tslib "^1.9.3" + +"@sentry/minimal@4.6.4": + version "4.6.4" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-4.6.4.tgz#dc4bb47df90dad6025d832852ac11fe29ed50147" + integrity sha512-jZa9mfzDzJI98tg6uxFG3gdVLyz0nOHpLP9H8Kn/BelZ7WEG/ogB8PDi1hI9JvCTXAr8kV81mEecldADa9L9Yg== + dependencies: + "@sentry/hub" "4.6.4" + "@sentry/types" "4.5.3" + tslib "^1.9.3" + +"@sentry/types@4.5.3": + version "4.5.3" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-4.5.3.tgz#3350dce2b7f9b936a8c327891c12e3aef7bd8852" + integrity sha512-7ll1PAFNjrBNX9rzy3P2qAQrpQwHaDO3uKj735qsnGw34OtAS8Xr8WYrjI14f9fMPa/XIeWvMPb4GMic28V/ag== + +"@sentry/utils@4.6.4": + version "4.6.4" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-4.6.4.tgz#ca254c142b519b4f20d63c2f9edf1a89966be36f" + integrity sha512-Tc5R46z7ve9Z+uU34ceDoEUR7skfQgXVIZqjbrTQphgm6EcMSNdRfkK3SJYZL5MNKiKhb7Tt/O3aPBy5bTZy6w== + dependencies: + "@sentry/types" "4.5.3" + tslib "^1.9.3" + "@svgr/babel-plugin-add-jsx-attribute@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.0.0.tgz#5acf239cd2747b1a36ec7e708de05d914cb9b948" @@ -1085,6 +1149,13 @@ acorn@^6.0.5, acorn@^6.0.7: resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== +agent-base@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" + integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== + dependencies: + es6-promisify "^5.0.0" + ajv-errors@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" @@ -1999,6 +2070,13 @@ debug@^2.1.2, debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" +debug@^3.1.0: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + debug@^4.0.1, debug@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" @@ -2234,6 +2312,18 @@ es-to-primitive@^1.2.0: is-date-object "^1.0.1" is-symbol "^1.0.2" +es6-promise@^4.0.3: + version "4.2.6" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.6.tgz#b685edd8258886365ea62b57d30de28fadcd974f" + integrity sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -2619,6 +2709,11 @@ from2@^2.1.0: inherits "^2.0.1" readable-stream "^2.0.0" +fs-copy-file-sync@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/fs-copy-file-sync/-/fs-copy-file-sync-1.1.1.tgz#11bf32c096c10d126e5f6b36d06eece776062918" + integrity sha512-2QY5eeqVv4m2PfyMiEuy9adxNP+ajf+8AR05cEi+OAzPcOj90hvFImeZhTmKLBgSd9EvG33jsD7ZRxsx9dThkQ== + fs-minipass@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" @@ -2909,6 +3004,14 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= +https-proxy-agent@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" + integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ== + dependencies: + agent-base "^4.1.0" + debug "^3.1.0" + iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -3762,6 +3865,11 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +node-fetch@^2.1.2: + version "2.3.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" + integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== + node-libs-browser@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.0.tgz#c72f60d9d46de08a940dedbb25f3ffa2f9bbaa77" @@ -4242,6 +4350,11 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= +progress@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" + integrity sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8= + progress@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" @@ -4275,6 +4388,11 @@ property-information@^5.0.0, property-information@^5.0.1: dependencies: xtend "^4.0.1" +proxy-from-env@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" + integrity sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4= + prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" @@ -5108,7 +5226,7 @@ tar@^4: safe-buffer "^5.1.2" yallist "^3.0.2" -terser-webpack-plugin@^1.1.0, terser-webpack-plugin@^1.2.3: +terser-webpack-plugin@^1.1.0: version "1.2.3" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.2.3.tgz#3f98bc902fac3e5d0de730869f50668561262ec8" integrity sha512-GOK7q85oAb/5kE12fMuLdn2btOS9OBZn4VsecpHDywoUC/jLhSAKOiYo0ezx7ss2EXPMzyEWFoE0s1WLE+4+oA== @@ -5221,7 +5339,7 @@ trough@^1.0.0: resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.3.tgz#e29bd1614c6458d44869fc28b255ab7857ef7c24" integrity sha512-fwkLWH+DimvA4YCy+/nvJd61nWQQ2liO/nF/RjkTpiOGi+zxZzVkhb1mvbHIIW4b/8nDsYI8uTmAlc0nNkRMOw== -tslib@^1.9.0: +tslib@^1.9.0, tslib@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==