Skip to content

Commit bb2ff1b

Browse files
pullfrog[bot]mrlubos
authored andcommitted
fix: silently ignore non-zero post-processor exit codes
Post-processors like ESLint and Oxfmt exit non-zero for non-fatal reasons (all files ignored, no matching files). Warnings from console.warn break CI pipelines that treat stderr as errors. Only actual spawn failures (ENOENT) are reported.
1 parent 94b26ef commit bb2ff1b

File tree

2 files changed

+9
-33
lines changed

2 files changed

+9
-33
lines changed

packages/shared/src/config/output/__tests__/postprocess.test.ts

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -122,48 +122,28 @@ describe('postprocessOutput', () => {
122122
).toThrow('Post-processor "My Formatter" failed to run: spawnSync my-formatter ENOENT');
123123
});
124124

125-
it('should warn when the process exits with a non-zero status code', () => {
126-
mockSync.mockReturnValue({ error: undefined, status: 1, stderr: Buffer.from('') } as any);
127-
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
128-
129-
postprocessOutput(
130-
{ ...baseConfig, postProcess: [{ args: ['{{path}}'], command: 'prettier' }] },
131-
noopPostProcessors,
132-
'',
133-
);
134-
135-
expect(warnSpy).toHaveBeenCalledWith(
136-
expect.stringContaining('Post-processor "prettier" exited with code 1'),
137-
);
138-
warnSpy.mockRestore();
139-
});
140-
141-
it('should include stderr in warning when process exits with non-zero status', () => {
125+
it('should silently ignore non-zero exit codes', () => {
142126
mockSync.mockReturnValue({
143127
error: undefined,
144-
status: 2,
145-
stderr: Buffer.from('error: file not found'),
128+
status: 1,
129+
stderr: Buffer.from('some error'),
146130
} as any);
147131
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
148132

149133
postprocessOutput(
150-
{ ...baseConfig, postProcess: [{ args: ['{{path}}'], command: 'biome' }] },
134+
{ ...baseConfig, postProcess: [{ args: ['{{path}}'], command: 'prettier' }] },
151135
noopPostProcessors,
152136
'',
153137
);
154138

155-
expect(warnSpy).toHaveBeenCalledTimes(1);
156-
const warnArg = warnSpy.mock.calls[0]![0] as string;
157-
expect(warnArg).toContain('Post-processor "biome" exited with code 2:');
158-
expect(warnArg).toContain('error: file not found');
139+
expect(warnSpy).not.toHaveBeenCalled();
159140
warnSpy.mockRestore();
160141
});
161142

162143
it('should continue processing after a non-zero exit code', () => {
163144
mockSync
164145
.mockReturnValueOnce({ error: undefined, status: 1, stderr: Buffer.from('') } as any)
165146
.mockReturnValueOnce({ error: undefined, status: 0 } as any);
166-
vi.spyOn(console, 'warn').mockImplementation(() => {});
167147

168148
postprocessOutput(
169149
{

packages/shared/src/config/output/postprocess.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,9 @@ export function postprocessOutput(
7979
throw new ConfigError(`Post-processor "${name}" failed to run: ${result.error.message}`);
8080
}
8181

82-
if (result.status !== null && result.status !== 0) {
83-
let message = `Post-processor "${name}" exited with code ${result.status}`;
84-
const stderr = result.stderr?.toString().trim();
85-
if (stderr) {
86-
message += `:\n${stderr}`;
87-
}
88-
console.warn(`${jobPrefix}${colors.yellow(`⚠️ ${message}`)}`);
89-
}
82+
// non-zero exit codes are silently ignored — post-processors like
83+
// ESLint and Oxfmt exit non-zero for non-fatal reasons (e.g. all
84+
// files ignored, no matching files) and warnings break CI pipelines
85+
// that treat any stderr output as an error
9086
}
9187
}

0 commit comments

Comments
 (0)