-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-image.ts
More file actions
81 lines (70 loc) · 2.41 KB
/
Copy pathdocker-image.ts
File metadata and controls
81 lines (70 loc) · 2.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/usr/bin/env bun
/**
* Build / push the aidd container image with both the floating `:latest` tag
* and the explicit `:{package.version}` tag (spernakit's docker-image.ts
* methodology). docker-compose.production.yml requires APP_VERSION (no
* :latest fallback), so both tags always exist for compose-up and rollback.
*
* The agent-backend CLI versions baked into the image are pinned here (single
* source of truth) and passed to the Dockerfile as build args — bump a version
* on this map and rebuild to ship newer CLIs.
*
* Usage:
* bun scripts/docker-image.ts build # docker build with both tags
* bun scripts/docker-image.ts push # docker push both tags
*/
import { spawnSync } from 'node:child_process';
import { readFileSync } from 'node:fs';
import { join, resolve } from 'node:path';
export const AGENT_CLI_VERSIONS = {
CLAUDE_CODE_VERSION: '2.1.175',
CODEX_VERSION: '0.139.0',
KILOCODE_VERSION: '7.3.45',
OPENCODE_VERSION: '1.17.4',
} as const;
const projectRoot = resolve(import.meta.dirname, '..');
interface PackageJson {
name?: string;
version?: string;
}
export function imageTags(pkg: PackageJson): { image: string; tags: string[] } {
if (!pkg.name || !pkg.version) {
throw new Error('package.json must have name and version');
}
return { image: `ghcr.io/nomadicdaddy/${pkg.name}`, tags: ['latest', pkg.version] };
}
export function buildArgs(image: string, tags: string[]): string[] {
const args = ['build'];
for (const tag of tags) {
args.push('-t', `${image}:${tag}`);
}
for (const [key, value] of Object.entries(AGENT_CLI_VERSIONS)) {
args.push('--build-arg', `${key}=${value}`);
}
args.push('.');
return args;
}
function run(args: string[]): number {
const result = spawnSync('docker', args, { cwd: projectRoot, stdio: 'inherit' });
return result.status ?? 1;
}
export function main(argv: string[] = process.argv.slice(2)): number {
const subcommand = argv[0];
if (subcommand !== 'build' && subcommand !== 'push') {
console.error('Usage: bun scripts/docker-image.ts <build|push>');
return 2;
}
const pkg = JSON.parse(readFileSync(join(projectRoot, 'package.json'), 'utf8')) as PackageJson;
const { image, tags } = imageTags(pkg);
if (subcommand === 'build') {
return run(buildArgs(image, tags));
}
for (const tag of tags) {
const status = run(['push', `${image}:${tag}`]);
if (status !== 0) return status;
}
return 0;
}
if (import.meta.main) {
process.exit(main());
}