fix(e2e): fail fast on config dependency installs (#17280)

This commit is contained in:
Luke Parker
2026-03-13 14:08:51 +10:00
committed by GitHub
parent d961981e25
commit f0bba10b12
5 changed files with 40 additions and 16 deletions

View File

@@ -73,6 +73,7 @@ const serverEnv = {
OPENCODE_E2E_MESSAGE: "Seeded for UI e2e", OPENCODE_E2E_MESSAGE: "Seeded for UI e2e",
OPENCODE_E2E_MODEL: "opencode/gpt-5-nano", OPENCODE_E2E_MODEL: "opencode/gpt-5-nano",
OPENCODE_CLIENT: "app", OPENCODE_CLIENT: "app",
OPENCODE_STRICT_CONFIG_DEPS: "true",
} satisfies Record<string, string> } satisfies Record<string, string>
const runnerEnv = { const runnerEnv = {

View File

@@ -10,15 +10,20 @@ const now = Date.now()
const seed = async () => { const seed = async () => {
const { Instance } = await import("../src/project/instance") const { Instance } = await import("../src/project/instance")
const { InstanceBootstrap } = await import("../src/project/bootstrap") const { InstanceBootstrap } = await import("../src/project/bootstrap")
const { Config } = await import("../src/config/config")
const { Session } = await import("../src/session") const { Session } = await import("../src/session")
const { MessageID, PartID } = await import("../src/session/schema") const { MessageID, PartID } = await import("../src/session/schema")
const { Project } = await import("../src/project/project") const { Project } = await import("../src/project/project")
const { ModelID, ProviderID } = await import("../src/provider/schema") const { ModelID, ProviderID } = await import("../src/provider/schema")
const { ToolRegistry } = await import("../src/tool/registry")
await Instance.provide({ await Instance.provide({
directory: dir, directory: dir,
init: InstanceBootstrap, init: InstanceBootstrap,
fn: async () => { fn: async () => {
await Config.waitForDependencies()
await ToolRegistry.ids()
const session = await Session.create({ title }) const session = await Session.create({ title })
const messageID = MessageID.ascending() const messageID = MessageID.ascending()
const partID = PartID.ascending() const partID = PartID.ascending()

View File

@@ -4,7 +4,6 @@ import { Log } from "../util/log"
import path from "path" import path from "path"
import { Filesystem } from "../util/filesystem" import { Filesystem } from "../util/filesystem"
import { NamedError } from "@opencode-ai/util/error" import { NamedError } from "@opencode-ai/util/error"
import { text } from "node:stream/consumers"
import { Lock } from "../util/lock" import { Lock } from "../util/lock"
import { PackageRegistry } from "./registry" import { PackageRegistry } from "./registry"
import { proxied } from "@/util/proxied" import { proxied } from "@/util/proxied"
@@ -13,32 +12,29 @@ import { Process } from "../util/process"
export namespace BunProc { export namespace BunProc {
const log = Log.create({ service: "bun" }) const log = Log.create({ service: "bun" })
export async function run(cmd: string[], options?: Process.Options) { export async function run(cmd: string[], options?: Process.RunOptions) {
const full = [which(), ...cmd]
log.info("running", { log.info("running", {
cmd: [which(), ...cmd], cmd: full,
...options, ...options,
}) })
const result = Process.spawn([which(), ...cmd], { const result = await Process.run(full, {
...options, cwd: options?.cwd,
stdout: "pipe", abort: options?.abort,
stderr: "pipe", kill: options?.kill,
timeout: options?.timeout,
nothrow: options?.nothrow,
env: { env: {
...process.env, ...process.env,
...options?.env, ...options?.env,
BUN_BE_BUN: "1", BUN_BE_BUN: "1",
}, },
}) })
const code = await result.exited
const stdout = result.stdout ? await text(result.stdout) : undefined
const stderr = result.stderr ? await text(result.stderr) : undefined
log.info("done", { log.info("done", {
code, code: result.code,
stdout, stdout: result.stdout.toString(),
stderr, stderr: result.stderr.toString(),
}) })
if (code !== 0) {
throw new Error(`Command failed with exit code ${code}`)
}
return result return result
} }

View File

@@ -36,6 +36,7 @@ import { iife } from "@/util/iife"
import { Account } from "@/account" import { Account } from "@/account"
import { ConfigPaths } from "./paths" import { ConfigPaths } from "./paths"
import { Filesystem } from "@/util/filesystem" import { Filesystem } from "@/util/filesystem"
import { Process } from "@/util/process"
export namespace Config { export namespace Config {
const ModelId = z.string().meta({ $ref: "https://models.dev/model-schema.json#/$defs/Model" }) const ModelId = z.string().meta({ $ref: "https://models.dev/model-schema.json#/$defs/Model" })
@@ -296,6 +297,26 @@ export namespace Config {
], ],
{ cwd: dir }, { cwd: dir },
).catch((err) => { ).catch((err) => {
if (err instanceof Process.RunFailedError) {
const detail = {
dir,
cmd: err.cmd,
code: err.code,
stdout: err.stdout.toString(),
stderr: err.stderr.toString(),
}
if (Flag.OPENCODE_STRICT_CONFIG_DEPS) {
log.error("failed to install dependencies", detail)
throw err
}
log.warn("failed to install dependencies", detail)
return
}
if (Flag.OPENCODE_STRICT_CONFIG_DEPS) {
log.error("failed to install dependencies", { dir, error: err })
throw err
}
log.warn("failed to install dependencies", { dir, error: err }) log.warn("failed to install dependencies", { dir, error: err })
}) })
} }

View File

@@ -63,6 +63,7 @@ export namespace Flag {
export const OPENCODE_MODELS_PATH = process.env["OPENCODE_MODELS_PATH"] export const OPENCODE_MODELS_PATH = process.env["OPENCODE_MODELS_PATH"]
export const OPENCODE_DISABLE_CHANNEL_DB = truthy("OPENCODE_DISABLE_CHANNEL_DB") export const OPENCODE_DISABLE_CHANNEL_DB = truthy("OPENCODE_DISABLE_CHANNEL_DB")
export const OPENCODE_SKIP_MIGRATIONS = truthy("OPENCODE_SKIP_MIGRATIONS") export const OPENCODE_SKIP_MIGRATIONS = truthy("OPENCODE_SKIP_MIGRATIONS")
export const OPENCODE_STRICT_CONFIG_DEPS = truthy("OPENCODE_STRICT_CONFIG_DEPS")
function number(key: string) { function number(key: string) {
const value = process.env[key] const value = process.env[key]