syncLiteLLMVersion.js
1 #!/usr/bin/env node 2 const fs = require("fs") 3 const path = require("path") 4 5 const repoRoot = path.resolve(__dirname, "..") 6 const versionConfigPath = path.join(repoRoot, "hosting", "litellm-version.json") 7 8 function readJson(filePath) { 9 return JSON.parse(fs.readFileSync(filePath, "utf8")) 10 } 11 12 function updateFile(filePath, updater) { 13 const original = fs.readFileSync(filePath, "utf8") 14 const updated = updater(original) 15 16 return { 17 changed: original !== updated, 18 updated, 19 } 20 } 21 22 function required(value, label) { 23 if (!value || typeof value !== "string") { 24 throw new Error(`Invalid ${label}`) 25 } 26 return value 27 } 28 29 function replaceRequired(content, pattern, replacement, filePath) { 30 if (!pattern.test(content)) { 31 throw new Error(`Could not find target pattern in ${filePath}`) 32 } 33 return content.replace(pattern, replacement) 34 } 35 36 function main() { 37 const checkOnly = process.argv.includes("--check") 38 const versionConfig = readJson(versionConfigPath) 39 const version = required(versionConfig.version, "version") 40 const channel = required(versionConfig.channel, "channel") 41 42 const imageTag = `main-v${version}-${channel}` 43 44 const updates = [ 45 { 46 path: path.join(repoRoot, "hosting", "single", "Dockerfile"), 47 update: content => 48 replaceRequired( 49 content, 50 /ARG LITELLM_PYPI_VERSION=.*/, 51 `ARG LITELLM_PYPI_VERSION=${version}`, 52 "hosting/single/Dockerfile" 53 ), 54 }, 55 { 56 path: path.join(repoRoot, "hosting", "docker-compose.yaml"), 57 update: content => 58 replaceRequired( 59 content, 60 /image:\s*(?:docker\.litellm\.ai|ghcr\.io)\/berriai\/litellm:[^\s\n]+/, 61 `image: ghcr.io/berriai/litellm:${imageTag}`, 62 "hosting/docker-compose.yaml" 63 ), 64 }, 65 { 66 path: path.join(repoRoot, "hosting", "docker-compose.build.yaml"), 67 update: content => 68 replaceRequired( 69 content, 70 /image:\s*(?:docker\.litellm\.ai|ghcr\.io)\/berriai\/litellm:[^\s\n]+/, 71 `image: ghcr.io/berriai/litellm:${imageTag}`, 72 "hosting/docker-compose.build.yaml" 73 ), 74 }, 75 { 76 path: path.join(repoRoot, "hosting", "docker-compose.dev.yaml"), 77 update: content => 78 replaceRequired( 79 content, 80 /image:\s*(?:docker\.litellm\.ai|ghcr\.io)\/berriai\/litellm:[^\s\n]+/, 81 `image: ghcr.io/berriai/litellm:${imageTag}`, 82 "hosting/docker-compose.dev.yaml" 83 ), 84 }, 85 { 86 path: path.join(repoRoot, "charts", "budibase", "values.yaml"), 87 update: content => 88 replaceRequired( 89 content, 90 /image:\s*ghcr\.io\/berriai\/litellm:[^\s\n]+/, 91 `image: ghcr.io/berriai/litellm:${imageTag}`, 92 "charts/budibase/values.yaml" 93 ), 94 }, 95 ] 96 97 const changed = [] 98 for (const item of updates) { 99 const result = updateFile(item.path, item.update) 100 if (result.changed) { 101 if (!checkOnly) { 102 fs.writeFileSync(item.path, result.updated) 103 } 104 changed.push(path.relative(repoRoot, item.path)) 105 } 106 } 107 108 console.log( 109 `LiteLLM version ${ 110 checkOnly ? "check" : "sync" 111 }: version=${version}, channel=${channel}` 112 ) 113 if (changed.length > 0) { 114 const header = checkOnly ? "Out-of-sync files" : "Updated files" 115 console.log(`${header}:\n${changed.join("\n")}`) 116 if (checkOnly) { 117 process.exit(1) 118 } 119 } else { 120 console.log(checkOnly ? "All files are in sync" : "No files changed") 121 } 122 } 123 124 main()