fix(cli): retry service file renames on Windows (#59105)

Co-authored-by: Kit Langton <kit.langton@gmail.com>
This commit is contained in:
Luke Parker
2026-10-26 09:51:22 +10:00
committed by GitHub
Unverified
parent e943bb62da
commit f8af56d28f
3 changed files with 12 additions and 4 deletions
+3 -3
View File
@@ -2,7 +2,7 @@ import { Global } from "@opencode/util/global"
import { OPENCODE_CHANNEL, OPENCODE_VERSION } from "../version"
import { Hash } from "@opencode/util/hash"
import { Service } from "@opencode/client/effect/service"
import { Effect, FileSystem, Option, Schema } from "effect"
import { Effect, FileSystem, Option, Schedule, Schema } from "effect"
import { randomBytes } from "crypto"
import path from "path"
import { selfCommand } from "../util/process"
@@ -178,10 +178,10 @@ function route() {
const write = Effect.fn("cli.service-config.write")(function* (value: Info) {
const { fs, configFile } = yield* paths
const temp = configFile + ".tmp"
const temp = configFile + "." + process.pid + ".tmp"
yield* fs.makeDirectory(path.dirname(configFile), { recursive: true })
yield* fs.writeFileString(temp, JSON.stringify(value, null, 2) + "\n", { mode: 0o600 })
yield* fs.rename(temp, configFile)
yield* fs.rename(temp, configFile).pipe(Effect.retry({ times: 20, schedule: Schedule.spaced("10 millis") }))
})
export const password = Effect.fn("cli.service-config.password")(function* (value?: string) {
@@ -36,7 +36,14 @@ export const register = Effect.fnUntraced(function* (options: {
found.url === info.url &&
found.pid === info.pid &&
found.password === info.password
yield* fs.writeFileString(temp, encoded, { mode: 0o600 }).pipe(Effect.andThen(fs.rename(temp, options.file)))
yield* fs
.writeFileString(temp, encoded, { mode: 0o600 })
.pipe(
// Windows rename can fail with EPERM while a contender or test polls the registration file.
Effect.andThen(
fs.rename(temp, options.file).pipe(Effect.retry({ times: 20, schedule: Schedule.spaced("10 millis") })),
),
)
yield* current.pipe(
Effect.catchCause((cause) =>
Effect.logWarning("managed service registration check failed; shutting down", {
+1
View File
@@ -851,6 +851,7 @@ function serviceEnv(root: string) {
...process.env,
BUN_RUNTIME_TRANSPILER_CACHE_PATH: transpilerCache,
HOME: root,
OPENCODE_CONFIG_DIR: undefined,
OPENCODE_DB: path.join(root, "opencode.db"),
OPENCODE_TEST_HOME: root,
XDG_CACHE_HOME: path.join(root, "cache"),