Skip to content

Commit 13523b3

Browse files
committed
Address review comments
1 parent f663bb1 commit 13523b3

3 files changed

Lines changed: 31 additions & 45 deletions

File tree

.github/workflows/dev-containers.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ jobs:
9999
run: |
100100
yarn install --frozen-lockfile
101101
docker run --privileged --rm tonistiigi/binfmt --install all
102+
- name: Install Dockerfile preprocessor tools
103+
run: |
104+
sudo apt-get update
105+
sudo apt-get install -y cpp cmake meson autoconf
102106
- name: Type-Check
103107
run: yarn type-check
104108
- name: Package

src/spec-node/dockerfilePreprocessor.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,8 @@ export async function preprocessDockerExtensionFile(
4242
const generatedOutputPath = path.resolve(workdirPath, generatedDockerfilePath);
4343
const generatedOutputDir = path.dirname(generatedOutputPath);
4444
await cliHost.mkdirp(generatedOutputDir);
45-
const staleOutputPaths = [generatedOutputPath];
46-
for (const stalePath of staleOutputPaths) {
47-
if (!await cliHost.isFile(stalePath)) {
48-
continue;
49-
}
50-
await cliHost.remove(stalePath);
45+
if (await cliHost.isFile(generatedOutputPath)) {
46+
await cliHost.remove(generatedOutputPath);
5147
}
5248

5349
// Minimal contract: tool args are user-controlled and run in the Dockerfile

src/test/dockerfilePreprocessor.test.ts

Lines changed: 25 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*---------------------------------------------------------------------------------------------
22
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
34
*--------------------------------------------------------------------------------------------*/
45

56
import * as assert from 'assert';
@@ -95,25 +96,6 @@ describe('dockerfilePreprocessor', function () {
9596
);
9697
});
9798

98-
it('requires configured generatedDockerfile path to be produced', async () => {
99-
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'devcontainer-preprocess-'));
100-
const inputPath = path.join(tmpDir, 'Dockerfile.in');
101-
await fs.writeFile(inputPath, 'FROM alpine:3.20\n');
102-
103-
const cliHost = await getCLIHost(process.cwd(), loadNativeModule, true);
104-
await assert.rejects(
105-
preprocessDockerExtensionFile(
106-
{ cliHost, output: nullLog },
107-
{ dockerfilePreprocessor: { tool: 'true', generatedDockerfilePath: 'build/Dockerfile' } },
108-
inputPath
109-
),
110-
(err: unknown) => {
111-
assert.ok(err instanceof ContainerError);
112-
assert.match((err as ContainerError).description, /generatedDockerfilePath/i);
113-
return true;
114-
}
115-
);
116-
});
11799

118100
it('passes paths via environment variables without positional args', async () => {
119101
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'devcontainer-preprocess-'));
@@ -148,7 +130,7 @@ describe('dockerfilePreprocessor', function () {
148130
));
149131
});
150132

151-
it('throws when tool succeeds but generated Dockerfile is not produced', async () => {
133+
it('throws when generatedDockerfilePath is configured but generated Dockerfile is not produced', async () => {
152134
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'devcontainer-preprocess-'));
153135
const inputPath = path.join(tmpDir, 'Dockerfile.in');
154136
await fs.writeFile(inputPath, 'FROM alpine:3.20\n');
@@ -163,6 +145,7 @@ describe('dockerfilePreprocessor', function () {
163145
(err: unknown) => {
164146
assert.ok(err instanceof ContainerError);
165147
assert.match((err as ContainerError).description, /did not produce/i);
148+
assert.match((err as ContainerError).description, /generatedDockerfile(?:Path| path)/i);
166149
return true;
167150
}
168151
);
@@ -191,29 +174,11 @@ describe('dockerfilePreprocessor', function () {
191174
);
192175
});
193176

194-
it('throws when generatedDockerfilePath is configured but not produced', async () => {
195-
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'devcontainer-preprocess-'));
196-
const inputPath = path.join(tmpDir, 'Dockerfile.in');
197-
await fs.writeFile(inputPath, 'FROM alpine:3.20\n');
198-
199-
const cliHost = await getCLIHost(process.cwd(), loadNativeModule, true);
200-
await assert.rejects(
201-
preprocessDockerExtensionFile(
202-
{ cliHost, output: nullLog },
203-
{ dockerfilePreprocessor: { tool: 'true', generatedDockerfilePath: 'build/Dockerfile' } },
204-
inputPath
205-
),
206-
(err: unknown) => {
207-
assert.ok(err instanceof ContainerError);
208-
assert.match((err as ContainerError).description, /generatedDockerfilePath/i);
209-
return true;
210-
}
211-
);
212-
});
213177
});
214178

215179
(process.platform === 'linux' ? describe : describe.skip)('dockerfilePreprocessor integration', function () {
216180
this.timeout('240s');
181+
const runningInCI = /^(true|1)$/i.test(process.env.CI || '');
217182

218183
const tmp = path.relative(process.cwd(), path.join(__dirname, 'tmp'));
219184
const cli = `npx --prefix ${tmp} devcontainer`;
@@ -251,6 +216,27 @@ describe('dockerfilePreprocessor', function () {
251216
mesonAvailable = Boolean(mesonCheck.stdout.trim());
252217
const autoconfCheck = await shellExec('command -v autoconf', undefined, true, true);
253218
autoconfAvailable = Boolean(autoconfCheck.stdout.trim());
219+
220+
if (runningInCI) {
221+
const missingTools: string[] = [];
222+
if (!cppAvailable) {
223+
missingTools.push('cpp');
224+
}
225+
if (!cmakeAvailable) {
226+
missingTools.push('cmake');
227+
}
228+
if (!mesonAvailable) {
229+
missingTools.push('meson');
230+
}
231+
if (!autoconfAvailable) {
232+
missingTools.push('autoconf');
233+
}
234+
assert.strictEqual(
235+
missingTools.length,
236+
0,
237+
`Missing required preprocessor tools on CI: ${missingTools.join(', ')}. Refusing to skip integration tests in CI.`
238+
);
239+
}
254240
});
255241

256242
it('should preprocess a Dockerfile.in during up cpp', async function () {

0 commit comments

Comments
 (0)