mirror of
https://github.com/different-ai/openwork
synced 2026-04-25 17:15:34 +02:00
fix(orchestrator): fall back to release binaries during npm install (#1080)
Co-authored-by: Omar McAdam <omar@OpenWork-Studio.localdomain>
This commit is contained in:
10
.github/workflows/release-macos-aarch64.yml
vendored
10
.github/workflows/release-macos-aarch64.yml
vendored
@@ -678,10 +678,12 @@ jobs:
|
||||
echo "exists=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Build sidecar artifacts
|
||||
- name: Build orchestrator release artifacts
|
||||
env:
|
||||
SOURCE_DATE_EPOCH: ${{ steps.source-date.outputs.epoch }}
|
||||
run: pnpm --filter openwork-orchestrator build:sidecars
|
||||
run: |
|
||||
pnpm --filter openwork-orchestrator build:bin:all
|
||||
pnpm --filter openwork-orchestrator build:sidecars
|
||||
|
||||
- name: Release review (strict)
|
||||
env:
|
||||
@@ -702,12 +704,12 @@ jobs:
|
||||
--notes "$notes" \
|
||||
--latest=false
|
||||
|
||||
- name: Upload sidecar assets
|
||||
- name: Upload orchestrator release assets
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
tag="openwork-orchestrator-v${{ steps.sidecar-versions.outputs.orchestrator }}"
|
||||
gh release upload "$tag" apps/orchestrator/dist/sidecars/* --repo "$GITHUB_REPOSITORY" --clobber
|
||||
gh release upload "$tag" apps/orchestrator/dist/bin/* apps/orchestrator/dist/sidecars/* --repo "$GITHUB_REPOSITORY" --clobber
|
||||
|
||||
publish-npm:
|
||||
name: Publish npm packages
|
||||
|
||||
@@ -20,6 +20,10 @@ openwork serve --workspace /path/to/workspace
|
||||
|
||||
`openwork` ships as a compiled binary, so Bun is not required at runtime.
|
||||
|
||||
If npm skips the optional platform package, `postinstall` falls back to downloading the matching
|
||||
binary from the `openwork-orchestrator-v<version>` GitHub release. Override the download host with
|
||||
`OPENWORK_ORCHESTRATOR_DOWNLOAD_BASE_URL` when you need to use a mirror.
|
||||
|
||||
`openwork` downloads and caches the `openwork-server`, `opencode-router`, and `opencode` sidecars on
|
||||
first run using a SHA-256 manifest. Use `--sidecar-dir` or `OPENWORK_SIDECAR_DIR` to control the
|
||||
cache location, and `--sidecar-base-url` / `--sidecar-manifest` to point at a custom host.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const childProcess = require("child_process")
|
||||
const fs = require("fs")
|
||||
const os = require("os")
|
||||
const path = require("path")
|
||||
|
||||
@@ -45,14 +46,18 @@ if (!arch) {
|
||||
|
||||
const pkg = `openwork-orchestrator-${platform}-${arch}`
|
||||
const binary = platform === "windows" ? "openwork.exe" : "openwork"
|
||||
const fallback = path.join(__dirname, "..", "dist", "bin", binary)
|
||||
|
||||
let pkgJsonPath
|
||||
try {
|
||||
pkgJsonPath = require.resolve(`${pkg}/package.json`)
|
||||
} catch {
|
||||
if (fs.existsSync(fallback)) {
|
||||
run(fallback)
|
||||
}
|
||||
console.error(
|
||||
`openwork: no prebuilt binary package found for ${platform}/${arch}.\n` +
|
||||
`Try installing the platform package manually: ${pkg}`,
|
||||
`Try reinstalling openwork-orchestrator or installing the platform package manually: ${pkg}`,
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"
|
||||
import { dirname, join } from "node:path"
|
||||
import os from "os"
|
||||
import { createRequire } from "module"
|
||||
import { fileURLToPath } from "node:url"
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const rootDir = dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
function detect() {
|
||||
const platformMap = {
|
||||
@@ -22,21 +26,90 @@ function detect() {
|
||||
return { platform, arch }
|
||||
}
|
||||
|
||||
function name() {
|
||||
function packageName() {
|
||||
const { platform, arch } = detect()
|
||||
return `openwork-orchestrator-${platform}-${arch}`
|
||||
}
|
||||
|
||||
try {
|
||||
const pkg = name()
|
||||
require.resolve(`${pkg}/package.json`)
|
||||
console.log(`openwork-orchestrator: verified platform package: ${pkg}`)
|
||||
} catch (error) {
|
||||
const pkg = name()
|
||||
console.error(
|
||||
`openwork-orchestrator: failed to locate platform binary package (${pkg}).\n` +
|
||||
`Your package manager may have skipped optionalDependencies.\n` +
|
||||
`Try installing it manually: npm i -g ${pkg}`,
|
||||
)
|
||||
process.exit(1)
|
||||
function binaryName() {
|
||||
const { platform } = detect()
|
||||
return platform === "windows" ? "openwork.exe" : "openwork"
|
||||
}
|
||||
|
||||
function fallbackAssetName() {
|
||||
const { platform, arch } = detect()
|
||||
return `openwork-bun-${platform}-${arch}${platform === "windows" ? ".exe" : ""}`
|
||||
}
|
||||
|
||||
function fallbackBinaryPath() {
|
||||
return join(rootDir, "dist", "bin", binaryName())
|
||||
}
|
||||
|
||||
function readOwnVersion() {
|
||||
const pkg = JSON.parse(readFileSync(join(rootDir, "package.json"), "utf8"))
|
||||
const version = String(pkg.version || "").trim()
|
||||
if (!version) {
|
||||
throw new Error("openwork-orchestrator: package version is missing")
|
||||
}
|
||||
return version
|
||||
}
|
||||
|
||||
function resolveFallbackBaseUrl(version) {
|
||||
const override = String(process.env.OPENWORK_ORCHESTRATOR_DOWNLOAD_BASE_URL || "").trim()
|
||||
if (override) {
|
||||
return override.replace(/\/$/, "")
|
||||
}
|
||||
return `https://github.com/different-ai/openwork/releases/download/openwork-orchestrator-v${version}`
|
||||
}
|
||||
|
||||
async function downloadFallbackBinary() {
|
||||
const version = readOwnVersion()
|
||||
const asset = fallbackAssetName()
|
||||
const url = `${resolveFallbackBaseUrl(version)}/${asset}`
|
||||
const destination = fallbackBinaryPath()
|
||||
|
||||
console.log(`openwork-orchestrator: downloading fallback binary ${asset}`)
|
||||
const response = await fetch(url)
|
||||
if (!response.ok) {
|
||||
throw new Error(`download failed (${response.status} ${response.statusText}) from ${url}`)
|
||||
}
|
||||
|
||||
const buffer = Buffer.from(await response.arrayBuffer())
|
||||
mkdirSync(dirname(destination), { recursive: true })
|
||||
writeFileSync(destination, buffer)
|
||||
if (binaryName() !== "openwork.exe") {
|
||||
chmodSync(destination, 0o755)
|
||||
}
|
||||
|
||||
console.log(`openwork-orchestrator: installed fallback binary at ${destination}`)
|
||||
}
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
const pkg = packageName()
|
||||
require.resolve(`${pkg}/package.json`)
|
||||
console.log(`openwork-orchestrator: verified platform package: ${pkg}`)
|
||||
return
|
||||
} catch {
|
||||
if (existsSync(fallbackBinaryPath())) {
|
||||
console.log(`openwork-orchestrator: using existing fallback binary at ${fallbackBinaryPath()}`)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await downloadFallbackBinary()
|
||||
} catch (error) {
|
||||
const pkg = packageName()
|
||||
const message = error instanceof Error ? error.message : String(error)
|
||||
console.error(
|
||||
`openwork-orchestrator: failed to locate platform binary package (${pkg}).\n` +
|
||||
`Your package manager may have skipped optionalDependencies, or the package asset is unavailable.\n` +
|
||||
`Fallback download failed: ${message}\n` +
|
||||
`Try installing it manually: npm i -g ${pkg}`,
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
await main()
|
||||
|
||||
@@ -117,7 +117,7 @@ writeJson(join(meta, "package.json"), {
|
||||
"openwork-orchestrator": "./bin/openwork",
|
||||
},
|
||||
scripts: {
|
||||
postinstall: "bun ./postinstall.mjs || node ./postinstall.mjs",
|
||||
postinstall: "node ./postinstall.mjs",
|
||||
},
|
||||
optionalDependencies,
|
||||
files: ["bin", "postinstall.mjs", "constants.json"],
|
||||
|
||||
Reference in New Issue
Block a user