Skip to content

Commit 06cec36

Browse files
committed
fix(core): don't mark package as built if any of its scripts fails (#5176)
1 parent fd57e2a commit 06cec36

File tree

3 files changed

+67
-7
lines changed

3 files changed

+67
-7
lines changed

.yarn/versions/7d105aea.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
releases:
2+
"@yarnpkg/cli": patch
3+
"@yarnpkg/core": patch
4+
5+
declined:
6+
- "@yarnpkg/plugin-compat"
7+
- "@yarnpkg/plugin-constraints"
8+
- "@yarnpkg/plugin-dlx"
9+
- "@yarnpkg/plugin-essentials"
10+
- "@yarnpkg/plugin-exec"
11+
- "@yarnpkg/plugin-file"
12+
- "@yarnpkg/plugin-git"
13+
- "@yarnpkg/plugin-github"
14+
- "@yarnpkg/plugin-http"
15+
- "@yarnpkg/plugin-init"
16+
- "@yarnpkg/plugin-interactive-tools"
17+
- "@yarnpkg/plugin-link"
18+
- "@yarnpkg/plugin-nm"
19+
- "@yarnpkg/plugin-npm"
20+
- "@yarnpkg/plugin-npm-cli"
21+
- "@yarnpkg/plugin-pack"
22+
- "@yarnpkg/plugin-patch"
23+
- "@yarnpkg/plugin-pnp"
24+
- "@yarnpkg/plugin-pnpm"
25+
- "@yarnpkg/plugin-stage"
26+
- "@yarnpkg/plugin-typescript"
27+
- "@yarnpkg/plugin-version"
28+
- "@yarnpkg/plugin-workspace-tools"
29+
- "@yarnpkg/builder"
30+
- "@yarnpkg/doctor"
31+
- "@yarnpkg/extensions"
32+
- "@yarnpkg/nm"
33+
- "@yarnpkg/pnpify"
34+
- "@yarnpkg/sdks"

packages/acceptance-tests/pkg-tests-specs/sources/commands/install.test.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,29 @@ describe(`Commands`, () => {
318318
),
319319
);
320320

321+
test(
322+
`should not mark package as built if any of its scripts fails`,
323+
makeTemporaryEnv(
324+
{
325+
scripts: {
326+
preinstall: `echo 'foo'`,
327+
postinstall: `exit 1`,
328+
},
329+
},
330+
async ({path, run, source}) => {
331+
await expect(run(`install`, `--inline-builds`)).rejects.toMatchObject({
332+
code: 1,
333+
stdout: expect.stringContaining(`foo`),
334+
});
335+
336+
await expect(run(`install`, `--inline-builds`)).rejects.toMatchObject({
337+
code: 1,
338+
stdout: expect.stringContaining(`foo`),
339+
});
340+
},
341+
),
342+
);
343+
321344
test(
322345
`should wait for direct dependencies to finish building`,
323346
makeTemporaryMonorepoEnv(

packages/yarnpkg-core/sources/Project.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,7 +1353,7 @@ export class Project {
13531353

13541354
while (buildablePackages.size > 0) {
13551355
const savedSize = buildablePackages.size;
1356-
const buildPromises = [];
1356+
const buildPromises: Array<Promise<unknown>> = [];
13571357

13581358
for (const locatorHash of buildablePackages) {
13591359
const pkg = this.storedPackages.get(locatorHash);
@@ -1436,18 +1436,15 @@ export class Project {
14361436
stdout.end();
14371437
stderr.end();
14381438

1439-
if (exitCode === 0) {
1440-
nextBState.set(pkg.locatorHash, buildHash);
1439+
if (exitCode === 0)
14411440
return true;
1442-
}
14431441

14441442
xfs.detachTemp(logDir);
14451443

14461444
const buildMessage = `${structUtils.prettyLocator(this.configuration, pkg)} couldn't be built successfully (exit code ${formatUtils.pretty(this.configuration, exitCode, formatUtils.Type.NUMBER)}, logs can be found here: ${formatUtils.pretty(this.configuration, logFile, formatUtils.Type.PATH)})`;
14471445

14481446
if (this.optionalBuilds.has(pkg.locatorHash)) {
14491447
report.reportInfo(MessageName.BUILD_FAILED, buildMessage);
1450-
nextBState.set(pkg.locatorHash, buildHash);
14511448
return true;
14521449
} else {
14531450
report.reportError(MessageName.BUILD_FAILED, buildMessage);
@@ -1456,15 +1453,21 @@ export class Project {
14561453
});
14571454

14581455
if (!wasBuildSuccessful) {
1459-
return;
1456+
return false;
14601457
}
14611458
}
1459+
1460+
return true;
14621461
});
14631462

14641463
buildPromises.push(
14651464
...pkgBuilds,
1466-
Promise.allSettled(pkgBuilds).then(() => {
1465+
Promise.allSettled(pkgBuilds).then(results => {
14671466
buildablePackages.delete(locatorHash);
1467+
1468+
if (results.every(result => result.status === `fulfilled` && result.value === true)) {
1469+
nextBState.set(pkg.locatorHash, buildHash);
1470+
}
14681471
}),
14691472
);
14701473
}

0 commit comments

Comments
 (0)