Don’t erase the `bin/` folder in CI (#317)

Summary:
Previously, our CI script would run `yarn backend`, which has the
side-effect of erasing the `bin/` directory. By itself, this is not
great, but not awful. However, this frequently triggers a race condition
in Prettier, causing the `check-pretty` step of the build to fail. (More
details: https://github.com/prettier/prettier/issues/4468.)

This patch changes the CI script to build the backend scripts into a
temporary directory.

Test Plan:
Before applying this patch: `yarn backend` and then `yarn travis`. If
this consistently causes a Travis failure due to `check-pretty`, then
your machine can reproduce the race condition that we‛re trying to
eliminate. (Otherwise, you can try creating a bunch more Git history…
I’m not really sure what to say. It is a race condition, after all.)
Then, apply this patch, and repeat the above steps; note that the error
no longer occurs, and that the build output is to a temporary directory.

wchargin-branch: ci-preserve-bin
This commit is contained in:
William Chargin 2018-05-29 15:40:42 -07:00 committed by GitHub
parent c0c79fd608
commit f8242c8cab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 14 additions and 9 deletions

View File

@ -59,7 +59,7 @@ function makeTasks(mode /*: "BASIC" | "FULL" */) {
},
{
id: "backend",
cmd: ["npm", "run", "--silent", "backend"],
cmd: ["npm", "run", "--silent", "backend", "--", "--dry-run"],
deps: [],
},
];

View File

@ -7,7 +7,7 @@ const nodeExternals = require("webpack-node-externals");
// This is the backend configuration. It builds applications that target
// Node and will not run in a browser.
module.exports = {
module.exports = (outputPath) => ({
// Don't attempt to continue if there are any errors.
bail: true,
// Target Node instead of the browser.
@ -15,7 +15,7 @@ module.exports = {
entry: paths.backendEntryPoints,
externals: [nodeExternals()],
output: {
path: paths.backendBuild,
path: outputPath,
// Generated JS file names (with nested folders).
// There will be one main bundle, and one file per asynchronous chunk.
// We don't currently advertise code splitting but Webpack supports it.
@ -77,4 +77,4 @@ module.exports = {
),
}),
],
};
});

View File

@ -19,6 +19,7 @@ require("../config/env");
const path = require("path");
const chalk = require("chalk");
const fs = require("fs-extra");
const tmp = require("tmp");
const webpack = require("webpack");
const config = require("../config/webpack.config.backend");
const paths = require("../config/paths");
@ -40,13 +41,17 @@ if (!checkRequiredFiles(Object.values(paths.backendEntryPoints))) {
process.exit(1);
}
const outputPath = process.argv.some((s) => s === "--dry-run" || s === "-n")
? tmp.dirSync({unsafeCleanup: true, prefix: "sourcecred-"}).name
: paths.backendBuild;
// First, read the current file sizes in build directory.
// This lets us display how much they changed later.
measureFileSizesBeforeBuild(paths.backendBuild)
measureFileSizesBeforeBuild(outputPath)
.then((previousFileSizes) => {
// Remove all content but keep the directory so that
// if you're in it, you don't end up in Trash
fs.emptyDirSync(paths.backendBuild);
fs.emptyDirSync(outputPath);
// Start the webpack build
return build(previousFileSizes);
})
@ -73,13 +78,13 @@ measureFileSizesBeforeBuild(paths.backendBuild)
printFileSizesAfterBuild(
stats,
previousFileSizes,
paths.backendBuild,
outputPath,
WARN_AFTER_BUNDLE_GZIP_SIZE,
WARN_AFTER_CHUNK_GZIP_SIZE
);
console.log();
const buildFolder = path.relative(process.cwd(), paths.backendBuild);
const buildFolder = path.relative(process.cwd(), outputPath);
console.log(`Build completed; results in '${buildFolder}'.`);
},
(err) => {
@ -93,7 +98,7 @@ measureFileSizesBeforeBuild(paths.backendBuild)
function build(previousFileSizes) {
console.log("Building backend applications...");
let compiler = webpack(config);
let compiler = webpack(config(outputPath));
return new Promise((resolve, reject) => {
compiler.run((err, stats) => {
if (err) {