Created
October 15, 2020 16:28
-
-
Save malliapi/49633556f19677bcd67c99355880db43 to your computer and use it in GitHub Desktop.
RollBar Sourcemaps Upload
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @module build/scripts/rollbar-sourcemap-upload | |
* | |
* Extracts currently built sourcemaps and uploads them to rollbar. | |
*/ | |
const request = require('request'); | |
const fs = require('fs'); | |
const path = require('path'); | |
const chalk = require('chalk'); | |
const logger = require('../lib/logger'); | |
const config = require('../../config/config.server'); | |
const { getBundles } = require('../../config/config.assets'); | |
// eslint-disable-next-line import/no-unresolved | |
const webpackAssets = require('../../dist/assets.json'); | |
// SOURCE_VERSION is the SHA of the current git commit | |
// exposed under a Heroku build environment variable | |
// see https://devcenter.heroku.com/articles/buildpack-api#bin-compile-summary | |
// CIRCLE_SHA1 is the same for CircleCI environments | |
const version = process.env.SOURCE_VERSION || process.env.CIRCLE_SHA1; | |
if (require.main === module && !version) { | |
logger.error('SOURCE_VERSION or CIRCLE_SHA1 must be provided for Rollbar sourcemaps to be matched to error traces'); | |
process.exit(1); | |
} | |
/** | |
* Helps resolve the local file path. | |
* | |
* @param {string} publicPath - public path of a file to search eg. `/assets/js/app.js` | |
* @returns {string} Absolute path to file on local filesystem | |
*/ | |
function getLocalFilePath(publicPath) { | |
return path.resolve(path.join(__dirname, `../../dist/public${publicPath}`)); | |
} | |
/** | |
* Uploads a single source map to Rollbar. | |
* | |
* @param {string} filePath - public path of a file to search eg. `/assets/js/app.js` | |
* @returns {Promise} Promised request | |
*/ | |
function uploadSingleSourceMap(filePath) { | |
const rollbarUrl = 'https://api.rollbar.com/api/1/sourcemap'; | |
const accessToken = config.rollbarServerAccessToken; | |
const minifiedUrl = config.app + filePath; | |
const fileName = filePath.split('/').pop(); | |
return new Promise((resolve, reject) => { | |
request.post( | |
{ | |
url: rollbarUrl, | |
headers: { | |
'content-type': 'multipart/form-data', | |
}, | |
multipart: [ | |
{ | |
'Content-Disposition': 'form-data; name="access_token"', | |
body: accessToken, | |
}, | |
{ | |
'Content-Disposition': 'form-data; name="version"', | |
body: version, | |
}, | |
{ | |
'Content-Disposition': 'form-data; name="minified_url"', | |
body: minifiedUrl, | |
}, | |
{ | |
'Content-Disposition': `form-data; name="source_map" filename="${fileName}"`, | |
body: fs.readFileSync(getLocalFilePath(`${filePath}.map`)), | |
}, | |
], | |
}, | |
(err, response, body) => { | |
if (err) { | |
reject(err); | |
} | |
if (response.statusCode !== 200) { | |
reject(new Error(`Expected 200 got ${response.statusCode}`)); | |
} else { | |
resolve(body); | |
} | |
} | |
); | |
}); | |
} | |
/** | |
* Executes requests to Rollbar. | |
* | |
* @param {object} [assets=webpackAssets] - Assets to upload. webpack.assets by default. | |
* @returns {Promise} Promise chain of all simultaneous uploads | |
*/ | |
function uploadSourceMapsToRollbar(assets = webpackAssets) { | |
const { assetsByChunkName } = assets; | |
const fileUploads = Object.keys(assetsByChunkName).map((bundleName) => { | |
const filePath = getBundles(bundleName, assets).js[0]; | |
return uploadSingleSourceMap(filePath); | |
}); | |
return Promise.resolve() | |
.then(() => logger.info(`Uploading sourcemaps to Rollbar for ${chalk.bold(config.env)} target environment`)) | |
.then(() => Promise.all(fileUploads)) | |
.then((response) => { | |
logger.success('Sourcemap upload successful'); | |
return response; | |
}) | |
.catch((err) => { | |
logger.error(`Upload failed ${err.stack}`); | |
throw err; | |
}); | |
} | |
// Called directly (npm run upload-sourcemaps), start uploading | |
if (require.main === module) { | |
uploadSourceMapsToRollbar().catch(() => process.exit(1)); | |
} | |
module.exports = { | |
uploadSourceMapsToRollbar, | |
uploadSingleSourceMap, | |
getLocalFilePath, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment