Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions src/cli/operations/deploy/__tests__/change-detection.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { canSkipDeploy, computeProjectDeployHash } from '../change-detection';
import { describe, expect, it, vi } from 'vitest';

let harnessJsonContent = '{"name":"h1","model":{"provider":"bedrock","modelId":"anthropic.claude-3"}}';
let dockerfileContent = 'FROM python:3.12';

vi.mock('node:fs/promises', () => ({
readFile: vi.fn().mockImplementation((path: string) => {
if (path.includes('harness.json'))
return Promise.resolve('{"name":"h1","model":{"provider":"bedrock","modelId":"anthropic.claude-3"}}');
if (path.includes('harness.json')) return Promise.resolve(harnessJsonContent);
if (path.includes('system-prompt.md')) return Promise.resolve('You are a helpful assistant.');
if (path.includes('Dockerfile')) return Promise.resolve(dockerfileContent);
return Promise.reject(Object.assign(new Error('ENOENT'), { code: 'ENOENT' }));
}),
}));
Expand Down Expand Up @@ -52,6 +55,21 @@ describe('computeProjectDeployHash', () => {
const hash2 = await computeProjectDeployHash(io2);
expect(hash1).not.toBe(hash2);
});

it('returns different hash when only the referenced Dockerfile content changes', async () => {
harnessJsonContent = '{"name":"h1","dockerfile":"Dockerfile"}';
try {
const io = mockConfigIO({});
dockerfileContent = 'FROM python:3.12';
const hash1 = await computeProjectDeployHash(io);
dockerfileContent = 'FROM python:3.13';
const hash2 = await computeProjectDeployHash(io);
expect(hash1).not.toBe(hash2);
} finally {
harnessJsonContent = '{"name":"h1","model":{"provider":"bedrock","modelId":"anthropic.claude-3"}}';
dockerfileContent = 'FROM python:3.12';
}
});
});

describe('canSkipDeploy', () => {
Expand Down
10 changes: 10 additions & 0 deletions src/cli/operations/deploy/change-detection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@

for (const harness of projectSpec.harnesses ?? []) {
const harnessDir = join(projectRoot, harness.path);
let dockerfile: string | undefined;
try {
const harnessJson = await readFile(join(harnessDir, 'harness.json'), 'utf-8');
hash.update(harnessJson);
dockerfile = JSON.parse(harnessJson)?.dockerfile;

Check failure on line 30 in src/cli/operations/deploy/change-detection.ts

View workflow job for this annotation

GitHub Actions / lint

Unsafe member access .dockerfile on an `any` value

Check failure on line 30 in src/cli/operations/deploy/change-detection.ts

View workflow job for this annotation

GitHub Actions / lint

Unsafe assignment of an `any` value
} catch {
// harness.json missing — hash will differ from last deploy
}
Expand All @@ -35,6 +37,14 @@
} catch {
// no system prompt
}
if (dockerfile) {
try {
const dockerfileContent = await readFile(join(harnessDir, dockerfile), 'utf-8');
hash.update(dockerfileContent);
} catch {
// referenced Dockerfile missing — hash will differ from last deploy
}
}
}

const awsTargets = await configIO.readAWSDeploymentTargets();
Expand Down
Loading