Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): exit with code 1 when remix build fails #1822

Merged
merged 5 commits into from
Apr 11, 2022

Conversation

gmaliar
Copy link
Contributor

@gmaliar gmaliar commented Feb 6, 2022

When builds fail remix does not exit with an error code which makes it hard to catch build failures in CI environments

return await Promise.all([
manifestPromise.then(() => browserBuildPromise),
serverBuildPromise
]);
} catch (err) {
options.onBuildFailure(err as Error);
return [undefined, undefined];
}

Example:

❯ yarn create remix
❯ cd ./my-remix-app
❯ echo -e "import doesntExists from \"doesnt-exists\";\ndoesntExists();\n$(cat app/routes/index.tsx)" > app/routes/index.tsx
❯ npx remix build

npx remix build
Building Remix app in production mode...
The path "doesnt-exists" is imported in app/routes/index.tsx but doesnt-exists is not listed in your package.json dependencies. Did you forget to install it?
 > node_modules/@web-std/file/tsconfig.json:6:24: warning: Non-relative path "packages/file/src/lib.js" is not allowed when "baseUrl" is not set (did you forget a leading "./"?)
    6 │       "@web-std/file": ["packages/file/src/lib.js"]
      ╵                         ~~~~~~~~~~~~~~~~~~~~~~~~~~

 > app/routes/index.tsx:1:25: error: Could not resolve "doesnt-exists" (mark it as external to exclude it from the bundle)
    1 │ import doesntExists from "doesnt-exists";~~~~~~~~~~~~~~~

Build failed with 1 error:
app/routes/index.tsx:1:25: error: Could not resolve "doesnt-exists" (mark it as external to exclude it from the bundle)
Built in 571ms

❯ echo $?
0

@gmaliar
Copy link
Contributor Author

gmaliar commented Feb 6, 2022

accidentally closed this by force pushing to my remix dev branch #1527

@@ -61,7 +61,11 @@ export async function build(

let start = Date.now();
let config = await readConfig(remixRoot);
await compiler.build(config, { mode: mode, sourcemap });
try {
await compiler.build(config, { mode: mode, sourcemap });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like we intended to have this code pass onBuildFailure, and then we can process.exit(1) there instead of a try catch

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, also we use a defaultOnBuildFailure handler, I think the process.exit(1) needs to go there.

@mjackson can you help us understand the intent here? Right now it just does console.error in the default build failure handler, seems like that's also the spot we'd want to process.exit(1) as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the default on build error is a great place to exit with an error code.
Would you like me to change?

When builds fail remix does not exit with an error code which makes it hard to catch build failures in CI environments

Example:
```sh
❯ yarn create remix
❯ cd ./my-remix-app
❯ echo -e "import doesntExists from \"doesnt-exists\";\ndoesntExists();\n$(cat app/routes/index.tsx)" > app/routes/index.tsx
❯ npx remix build

npx remix build
Building Remix app in production mode...
The path "doesnt-exists" is imported in app/routes/index.tsx but doesnt-exists is not listed in your package.json dependencies. Did you forget to install it?
 > node_modules/@web-std/file/tsconfig.json:6:24: warning: Non-relative path "packages/file/src/lib.js" is not allowed when "baseUrl" is not set (did you forget a leading "./"?)
    6 │       "@web-std/file": ["packages/file/src/lib.js"]
      ╵                         ~~~~~~~~~~~~~~~~~~~~~~~~~~

 > app/routes/index.tsx:1:25: error: Could not resolve "doesnt-exists" (mark it as external to exclude it from the bundle)
    1 │ import doesntExists from "doesnt-exists";
      ╵                          ~~~~~~~~~~~~~~~

Build failed with 1 error:
app/routes/index.tsx:1:25: error: Could not resolve "doesnt-exists" (mark it as external to exclude it from the bundle)
Built in 571ms

❯ echo $?
0
```
@remix-cla-bot
Copy link
Contributor

remix-cla-bot bot commented Feb 10, 2022

Thank you for signing the Contributor License Agreement. Let's get this merged! 🥳

@gmaliar
Copy link
Contributor Author

gmaliar commented Feb 10, 2022

@ryanflorence we actually got it wrong.
@jacob-ebey already added error handling for the cli here:

.catch(handleError);

The only problem with it, is that the defaultBuildFailureHandler doesn't throw anything so the error just get swallowed and it doesn't exit for some use-cases.

Now there's another thing we got wrong, the default build failure handler is also used in watch, if it would process.exit(1) on watch, it's counterproductive to the watch intent, so it's not the correct spot to implement the exit procedure.

Instead, I've created a different onBuidlFailure that throw an error but still formats the failure as the default handler.
I propose an internal change in the compiler.ts file that extracts the formatting into a function formatBuildFailure that the defaultOnBuildFailure will use to format errors and also the different onBuildFailure can use when is invoked from the cli.

@gmaliar
Copy link
Contributor Author

gmaliar commented Feb 22, 2022

@ryanflorence @mjackson can we get this merged?

@machour machour linked an issue Apr 1, 2022 that may be closed by this pull request
@machour machour added the feat:dx Issues related to the developer experience label Apr 7, 2022
@gmaliar
Copy link
Contributor Author

gmaliar commented Apr 11, 2022

@mjackson @kentcdodds @ryanflorence this has been ready for a while, can we get this merged?

Copy link
Member

@kentcdodds kentcdodds left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. I'll ping Michael and Ryan about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed feat:dx Issues related to the developer experience
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: Failed build does not return the right exit code
5 participants