fix: 修正 logo 中 N 和 G 字母造型
N 添加对角线笔画(█▄ █),G 添加内横杠(█ ▀█), 避免与 O 字母造型雷同。同步更新 ui.ts 中的硬编码 wordmark。
This commit is contained in:
12
packages/desktop/scripts/copy-bundles.ts
Normal file
12
packages/desktop/scripts/copy-bundles.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { $ } from "bun"
|
||||
import * as path from "node:path"
|
||||
|
||||
import { RUST_TARGET } from "./utils"
|
||||
|
||||
if (!RUST_TARGET) throw new Error("RUST_TARGET not defined")
|
||||
|
||||
const BUNDLE_DIR = "dist"
|
||||
const BUNDLES_OUT_DIR = path.join(process.cwd(), "dist/bundles")
|
||||
|
||||
await $`mkdir -p ${BUNDLES_OUT_DIR}`
|
||||
await $`cp -r ${BUNDLE_DIR}/* ${BUNDLES_OUT_DIR}`
|
||||
12
packages/desktop/scripts/copy-icons.ts
Normal file
12
packages/desktop/scripts/copy-icons.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { $ } from "bun"
|
||||
import { resolveChannel } from "./utils"
|
||||
|
||||
const arg = process.argv[2]
|
||||
const channel = arg === "dev" || arg === "beta" || arg === "prod" ? arg : resolveChannel()
|
||||
|
||||
const src = `./icons/${channel}`
|
||||
const dest = "resources/icons"
|
||||
|
||||
await $`rm -rf ${dest}`
|
||||
await $`cp -R ${src} ${dest}`
|
||||
console.log(`Copied ${channel} icons from ${src} to ${dest}`)
|
||||
47
packages/desktop/scripts/copy-metainfo.ts
Normal file
47
packages/desktop/scripts/copy-metainfo.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { resolveChannel } from "./utils"
|
||||
|
||||
const arg = process.argv[2]
|
||||
const channel = arg === "dev" || arg === "beta" || arg === "prod" ? arg : resolveChannel()
|
||||
|
||||
const appId = channel === "prod" ? "ai.opencode.desktop" : `ai.opencode.desktop.${channel}`
|
||||
const productName = channel === "prod" ? "OpenCode" : `OpenCode ${channel.charAt(0).toUpperCase() + channel.slice(1)}`
|
||||
const summary = `Open source AI coding agent${channel !== "prod" ? ` (${channel})` : ""}`
|
||||
|
||||
const xml = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop-application">
|
||||
<id>${appId}</id>
|
||||
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>MIT</project_license>
|
||||
|
||||
<name>${productName}</name>
|
||||
<summary>${summary}</summary>
|
||||
|
||||
<developer id="ly.anoma">
|
||||
<name>Anomaly Innovations Inc.</name>
|
||||
</developer>
|
||||
|
||||
<description>
|
||||
<p>
|
||||
OpenCode is an open source agent that helps you write and run code with any AI model.
|
||||
</p>
|
||||
</description>
|
||||
|
||||
<launchable type="desktop-id">${appId}.desktop</launchable>
|
||||
|
||||
<content_rating type="oars-1.1" />
|
||||
|
||||
<url type="bugtracker">https://github.com/anomalyco/opencode/issues</url>
|
||||
<url type="homepage">https://opencode.ai</url>
|
||||
<url type="vcs-browser">https://github.com/anomalyco/opencode</url>
|
||||
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<image>https://raw.githubusercontent.com/anomalyco/opencode/b75d4d1c5ec449585d515c756fc81f080a157a9a/packages/web/src/assets/lander/screenshot.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
</component>
|
||||
`
|
||||
|
||||
await Bun.write(`resources/${appId}.metainfo.xml`, xml)
|
||||
console.log(`Generated metainfo for ${channel} at resources/${appId}.metainfo.xml`)
|
||||
219
packages/desktop/scripts/finalize-latest-json.ts
Normal file
219
packages/desktop/scripts/finalize-latest-json.ts
Normal file
@@ -0,0 +1,219 @@
|
||||
#!/usr/bin/env bun
|
||||
|
||||
import { $ } from "bun"
|
||||
import path from "node:path"
|
||||
import { parseArgs } from "node:util"
|
||||
|
||||
const { values } = parseArgs({
|
||||
args: Bun.argv.slice(2),
|
||||
options: {
|
||||
"dry-run": { type: "boolean", default: false },
|
||||
},
|
||||
})
|
||||
|
||||
const dryRun = values["dry-run"]
|
||||
|
||||
const repo = process.env.GH_REPO
|
||||
if (!repo) throw new Error("GH_REPO is required")
|
||||
|
||||
const releaseId = process.env.OPENCODE_RELEASE
|
||||
if (!releaseId) throw new Error("OPENCODE_RELEASE is required")
|
||||
|
||||
const version = process.env.OPENCODE_VERSION
|
||||
if (!version) throw new Error("OPENCODE_VERSION is required")
|
||||
|
||||
const dir = process.env.LATEST_YML_DIR
|
||||
if (!dir) throw new Error("LATEST_YML_DIR is required")
|
||||
const root = dir
|
||||
|
||||
const token = process.env.GH_TOKEN ?? process.env.GITHUB_TOKEN
|
||||
if (!token) throw new Error("GH_TOKEN or GITHUB_TOKEN is required")
|
||||
|
||||
const rel = await fetch(`https://api.github.com/repos/${repo}/releases/${releaseId}`, {
|
||||
headers: {
|
||||
Authorization: `token ${token}`,
|
||||
Accept: "application/vnd.github+json",
|
||||
},
|
||||
})
|
||||
|
||||
if (!rel.ok) {
|
||||
throw new Error(`Failed to fetch release: ${rel.status} ${rel.statusText}`)
|
||||
}
|
||||
|
||||
type Asset = {
|
||||
name: string
|
||||
url: string
|
||||
}
|
||||
|
||||
type Release = {
|
||||
assets?: Asset[]
|
||||
}
|
||||
|
||||
const assets = ((await rel.json()) as Release).assets ?? []
|
||||
const amap = new Map(assets.map((item) => [item.name, item]))
|
||||
|
||||
type Item = {
|
||||
url: string
|
||||
}
|
||||
|
||||
type Yml = {
|
||||
version: string
|
||||
files: Item[]
|
||||
}
|
||||
|
||||
function parse(text: string): Yml {
|
||||
const lines = text.split("\n")
|
||||
let version = ""
|
||||
const files: Item[] = []
|
||||
let url = ""
|
||||
|
||||
const flush = () => {
|
||||
if (!url) return
|
||||
files.push({ url })
|
||||
url = ""
|
||||
}
|
||||
|
||||
for (const line of lines) {
|
||||
const trim = line.trim()
|
||||
if (line.startsWith("version:")) {
|
||||
version = line.slice("version:".length).trim()
|
||||
continue
|
||||
}
|
||||
if (trim.startsWith("- url:")) {
|
||||
flush()
|
||||
url = trim.slice("- url:".length).trim()
|
||||
continue
|
||||
}
|
||||
const indented = line.startsWith(" ") || line.startsWith("\t")
|
||||
if (!indented) flush()
|
||||
}
|
||||
flush()
|
||||
|
||||
return { version, files }
|
||||
}
|
||||
|
||||
async function read(sub: string, file: string) {
|
||||
const item = Bun.file(path.join(root, sub, file))
|
||||
if (!(await item.exists())) return undefined
|
||||
return parse(await item.text())
|
||||
}
|
||||
|
||||
function pick(list: Item[], exts: string[]) {
|
||||
for (const ext of exts) {
|
||||
const found = list.find((item) => item.url.split("?")[0]?.toLowerCase().endsWith(ext))
|
||||
if (found) return found.url
|
||||
}
|
||||
}
|
||||
|
||||
function link(raw: string) {
|
||||
if (raw.startsWith("https://") || raw.startsWith("http://")) return raw
|
||||
return `https://github.com/${repo}/releases/download/v${version}/${raw}`
|
||||
}
|
||||
|
||||
async function sign(url: string, key: string) {
|
||||
const name = decodeURIComponent(new URL(url).pathname.split("/").pop() ?? key)
|
||||
const asset = amap.get(name)
|
||||
const res = await fetch(asset?.url ?? url, {
|
||||
headers: {
|
||||
Authorization: `token ${token}`,
|
||||
...(asset ? { Accept: "application/octet-stream" } : {}),
|
||||
},
|
||||
})
|
||||
if (!res.ok) {
|
||||
throw new Error(`Failed to fetch file ${name}: ${res.status} ${res.statusText} (${asset?.url ?? url})`)
|
||||
}
|
||||
|
||||
const tmp = process.env.RUNNER_TEMP ?? "/tmp"
|
||||
const file = path.join(tmp, name)
|
||||
await Bun.write(file, await res.arrayBuffer())
|
||||
await $`bunx @tauri-apps/cli signer sign ${file}`
|
||||
const sigFile = Bun.file(`${file}.sig`)
|
||||
if (!(await sigFile.exists())) throw new Error(`Signature file not found for ${name}`)
|
||||
return (await sigFile.text()).trim()
|
||||
}
|
||||
|
||||
const add = async (data: Record<string, { url: string; signature: string }>, key: string, raw: string | undefined) => {
|
||||
if (!raw) return
|
||||
if (data[key]) return
|
||||
const url = link(raw)
|
||||
data[key] = { url, signature: await sign(url, key) }
|
||||
}
|
||||
|
||||
const alias = (data: Record<string, { url: string; signature: string }>, key: string, src: string) => {
|
||||
if (data[key]) return
|
||||
if (!data[src]) return
|
||||
data[key] = data[src]
|
||||
}
|
||||
|
||||
const winx = await read("latest-yml-x86_64-pc-windows-msvc", "latest.yml")
|
||||
const wina = await read("latest-yml-aarch64-pc-windows-msvc", "latest.yml")
|
||||
const macx = await read("latest-yml-x86_64-apple-darwin", "latest-mac.yml")
|
||||
const maca = await read("latest-yml-aarch64-apple-darwin", "latest-mac.yml")
|
||||
const linx = await read("latest-yml-x86_64-unknown-linux-gnu", "latest-linux.yml")
|
||||
const lina = await read("latest-yml-aarch64-unknown-linux-gnu", "latest-linux-arm64.yml")
|
||||
|
||||
const yver = winx?.version ?? wina?.version ?? macx?.version ?? maca?.version ?? linx?.version ?? lina?.version
|
||||
if (yver && yver !== version) throw new Error(`latest.yml version mismatch: expected ${version}, got ${yver}`)
|
||||
|
||||
const out: Record<string, { url: string; signature: string }> = {}
|
||||
|
||||
const winxexe = pick(winx?.files ?? [], [".exe"])
|
||||
const winaexe = pick(wina?.files ?? [], [".exe"])
|
||||
|
||||
const macxTarGz = "opencode-desktop-mac-x64.app.tar.gz"
|
||||
const macaTarGz = "opencode-desktop-mac-arm64.app.tar.gz"
|
||||
|
||||
const linxDeb = pick(linx?.files ?? [], [".deb"])
|
||||
const linxRpm = pick(linx?.files ?? [], [".rpm"])
|
||||
const linxAppImage = pick(linx?.files ?? [], [".appimage"])
|
||||
const linaDeb = pick(lina?.files ?? [], [".deb"])
|
||||
const linaRpm = pick(lina?.files ?? [], [".rpm"])
|
||||
const linaAppImage = pick(lina?.files ?? [], [".appimage"])
|
||||
|
||||
await add(out, "windows-x86_64-nsis", winxexe)
|
||||
await add(out, "windows-aarch64-nsis", winaexe)
|
||||
await add(out, "darwin-x86_64-app", macxTarGz)
|
||||
await add(out, "darwin-aarch64-app", macaTarGz)
|
||||
|
||||
await add(out, "linux-x86_64-deb", linxDeb)
|
||||
await add(out, "linux-x86_64-rpm", linxRpm)
|
||||
await add(out, "linux-x86_64-appimage", linxAppImage)
|
||||
await add(out, "linux-aarch64-deb", linaDeb)
|
||||
await add(out, "linux-aarch64-rpm", linaRpm)
|
||||
await add(out, "linux-aarch64-appimage", linaAppImage)
|
||||
|
||||
alias(out, "windows-x86_64", "windows-x86_64-nsis")
|
||||
alias(out, "windows-aarch64", "windows-aarch64-nsis")
|
||||
alias(out, "darwin-x86_64", "darwin-x86_64-app")
|
||||
alias(out, "darwin-aarch64", "darwin-aarch64-app")
|
||||
alias(out, "linux-x86_64", "linux-x86_64-deb")
|
||||
alias(out, "linux-aarch64", "linux-aarch64-deb")
|
||||
|
||||
const platforms = Object.fromEntries(
|
||||
Object.keys(out)
|
||||
.sort()
|
||||
.map((key) => [key, out[key]]),
|
||||
)
|
||||
|
||||
if (!Object.keys(platforms).length) throw new Error("No updater files found in latest.yml artifacts")
|
||||
|
||||
const data = {
|
||||
version,
|
||||
notes: "",
|
||||
pub_date: new Date().toISOString(),
|
||||
platforms,
|
||||
}
|
||||
|
||||
const tmp = process.env.RUNNER_TEMP ?? "/tmp"
|
||||
const file = path.join(tmp, "latest.json")
|
||||
await Bun.write(file, JSON.stringify(data, null, 2))
|
||||
|
||||
const tag = `v${version}`
|
||||
|
||||
if (dryRun) {
|
||||
console.log(`dry-run: wrote latest.json for ${tag} to ${file}`)
|
||||
process.exit(0)
|
||||
}
|
||||
await $`gh release upload ${tag} ${file} --clobber --repo ${repo}`
|
||||
|
||||
console.log(`finalized latest.json for ${tag}`)
|
||||
124
packages/desktop/scripts/finalize-latest-yml.ts
Normal file
124
packages/desktop/scripts/finalize-latest-yml.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env bun
|
||||
|
||||
import { $ } from "bun"
|
||||
import path from "path"
|
||||
|
||||
const dir = process.env.LATEST_YML_DIR!
|
||||
if (!dir) throw new Error("LATEST_YML_DIR is required")
|
||||
|
||||
const repo = process.env.GH_REPO
|
||||
if (!repo) throw new Error("GH_REPO is required")
|
||||
|
||||
const version = process.env.OPENCODE_VERSION
|
||||
if (!version) throw new Error("OPENCODE_VERSION is required")
|
||||
|
||||
type FileEntry = {
|
||||
url: string
|
||||
sha512: string
|
||||
size: number
|
||||
blockMapSize?: number
|
||||
}
|
||||
|
||||
type LatestYml = {
|
||||
version: string
|
||||
files: FileEntry[]
|
||||
releaseDate: string
|
||||
}
|
||||
|
||||
function parse(content: string): LatestYml {
|
||||
const lines = content.split("\n")
|
||||
let version = ""
|
||||
let releaseDate = ""
|
||||
const files: FileEntry[] = []
|
||||
let current: Partial<FileEntry> | undefined
|
||||
|
||||
const flush = () => {
|
||||
if (current?.url && current.sha512 && current.size) files.push(current as FileEntry)
|
||||
current = undefined
|
||||
}
|
||||
|
||||
for (const line of lines) {
|
||||
const indented = line.startsWith(" ") || line.startsWith(" -")
|
||||
if (line.startsWith("version:")) version = line.slice("version:".length).trim()
|
||||
else if (line.startsWith("releaseDate:"))
|
||||
releaseDate = line.slice("releaseDate:".length).trim().replace(/^'|'$/g, "")
|
||||
else if (line.trim().startsWith("- url:")) {
|
||||
flush()
|
||||
current = { url: line.trim().slice("- url:".length).trim() }
|
||||
} else if (indented && current && line.trim().startsWith("sha512:"))
|
||||
current.sha512 = line.trim().slice("sha512:".length).trim()
|
||||
else if (indented && current && line.trim().startsWith("size:"))
|
||||
current.size = Number(line.trim().slice("size:".length).trim())
|
||||
else if (indented && current && line.trim().startsWith("blockMapSize:"))
|
||||
current.blockMapSize = Number(line.trim().slice("blockMapSize:".length).trim())
|
||||
else if (!indented && current) flush()
|
||||
}
|
||||
flush()
|
||||
|
||||
return { version, files, releaseDate }
|
||||
}
|
||||
|
||||
function serialize(data: LatestYml) {
|
||||
const lines = [`version: ${data.version}`, "files:"]
|
||||
for (const file of data.files) {
|
||||
lines.push(` - url: ${file.url}`)
|
||||
lines.push(` sha512: ${file.sha512}`)
|
||||
lines.push(` size: ${file.size}`)
|
||||
if (file.blockMapSize) lines.push(` blockMapSize: ${file.blockMapSize}`)
|
||||
}
|
||||
lines.push(`releaseDate: '${data.releaseDate}'`)
|
||||
return lines.join("\n") + "\n"
|
||||
}
|
||||
|
||||
async function read(subdir: string, filename: string): Promise<LatestYml | undefined> {
|
||||
const file = Bun.file(path.join(dir, subdir, filename))
|
||||
if (!(await file.exists())) return undefined
|
||||
return parse(await file.text())
|
||||
}
|
||||
|
||||
const output: Record<string, string> = {}
|
||||
|
||||
// Windows: merge arm64 + x64 into single file
|
||||
const winX64 = await read("latest-yml-x86_64-pc-windows-msvc", "latest.yml")
|
||||
const winArm64 = await read("latest-yml-aarch64-pc-windows-msvc", "latest.yml")
|
||||
if (winX64 || winArm64) {
|
||||
const base = winArm64 ?? winX64!
|
||||
output["latest.yml"] = serialize({
|
||||
version: base.version,
|
||||
files: [...(winArm64?.files ?? []), ...(winX64?.files ?? [])],
|
||||
releaseDate: base.releaseDate,
|
||||
})
|
||||
}
|
||||
|
||||
// Linux x64: pass through
|
||||
const linuxX64 = await read("latest-yml-x86_64-unknown-linux-gnu", "latest-linux.yml")
|
||||
if (linuxX64) output["latest-linux.yml"] = serialize(linuxX64)
|
||||
|
||||
// Linux arm64: pass through
|
||||
const linuxArm64 = await read("latest-yml-aarch64-unknown-linux-gnu", "latest-linux-arm64.yml")
|
||||
if (linuxArm64) output["latest-linux-arm64.yml"] = serialize(linuxArm64)
|
||||
|
||||
// macOS: merge arm64 + x64 into single file
|
||||
const macX64 = await read("latest-yml-x86_64-apple-darwin", "latest-mac.yml")
|
||||
const macArm64 = await read("latest-yml-aarch64-apple-darwin", "latest-mac.yml")
|
||||
if (macX64 || macArm64) {
|
||||
const base = macArm64 ?? macX64!
|
||||
output["latest-mac.yml"] = serialize({
|
||||
version: base.version,
|
||||
files: [...(macArm64?.files ?? []), ...(macX64?.files ?? [])],
|
||||
releaseDate: base.releaseDate,
|
||||
})
|
||||
}
|
||||
|
||||
// Upload to release
|
||||
const tag = `v${version}`
|
||||
const tmp = process.env.RUNNER_TEMP ?? "/tmp"
|
||||
|
||||
for (const [filename, content] of Object.entries(output)) {
|
||||
const filepath = path.join(tmp, filename)
|
||||
await Bun.write(filepath, content)
|
||||
await $`gh release upload ${tag} ${filepath} --clobber --repo ${repo}`
|
||||
console.log(`uploaded ${filename}`)
|
||||
}
|
||||
|
||||
console.log("finalized latest yml files")
|
||||
10
packages/desktop/scripts/prebuild.ts
Normal file
10
packages/desktop/scripts/prebuild.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bun
|
||||
import { $ } from "bun"
|
||||
|
||||
import { resolveChannel } from "./utils"
|
||||
|
||||
const channel = resolveChannel()
|
||||
await $`bun ./scripts/copy-icons.ts ${channel}`
|
||||
await $`bun ./scripts/copy-metainfo.ts ${channel}`
|
||||
|
||||
await $`cd ../opencode && bun script/build-node.ts`
|
||||
5
packages/desktop/scripts/predev.ts
Normal file
5
packages/desktop/scripts/predev.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { $ } from "bun"
|
||||
|
||||
await $`bun ./scripts/copy-icons.ts ${process.env.OPENCODE_CHANNEL ?? "dev"}`
|
||||
|
||||
await $`cd ../opencode && bun script/build-node.ts`
|
||||
9
packages/desktop/scripts/prepare.ts
Executable file
9
packages/desktop/scripts/prepare.ts
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bun
|
||||
import { Script } from "@opencode-ai/script"
|
||||
|
||||
await import("./prebuild")
|
||||
|
||||
const pkg = await Bun.file("./package.json").json()
|
||||
pkg.version = Script.version
|
||||
await Bun.write("./package.json", JSON.stringify(pkg, null, 2) + "\n")
|
||||
console.log(`Updated package.json version to ${Script.version}`)
|
||||
77
packages/desktop/scripts/utils.ts
Normal file
77
packages/desktop/scripts/utils.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { $ } from "bun"
|
||||
|
||||
export type Channel = "dev" | "beta" | "prod"
|
||||
|
||||
export function resolveChannel(): Channel {
|
||||
const raw = Bun.env.OPENCODE_CHANNEL
|
||||
if (raw === "dev" || raw === "beta" || raw === "prod") return raw
|
||||
return "dev"
|
||||
}
|
||||
|
||||
export const SIDECAR_BINARIES: Array<{ rustTarget: string; ocBinary: string; assetExt: string }> = [
|
||||
{
|
||||
rustTarget: "aarch64-apple-darwin",
|
||||
ocBinary: "opencode-darwin-arm64",
|
||||
assetExt: "zip",
|
||||
},
|
||||
{
|
||||
rustTarget: "x86_64-apple-darwin",
|
||||
ocBinary: "opencode-darwin-x64-baseline",
|
||||
assetExt: "zip",
|
||||
},
|
||||
{
|
||||
rustTarget: "aarch64-pc-windows-msvc",
|
||||
ocBinary: "opencode-windows-arm64",
|
||||
assetExt: "zip",
|
||||
},
|
||||
{
|
||||
rustTarget: "x86_64-pc-windows-msvc",
|
||||
ocBinary: "opencode-windows-x64-baseline",
|
||||
assetExt: "zip",
|
||||
},
|
||||
{
|
||||
rustTarget: "x86_64-unknown-linux-gnu",
|
||||
ocBinary: "opencode-linux-x64-baseline",
|
||||
assetExt: "tar.gz",
|
||||
},
|
||||
{
|
||||
rustTarget: "aarch64-unknown-linux-gnu",
|
||||
ocBinary: "opencode-linux-arm64",
|
||||
assetExt: "tar.gz",
|
||||
},
|
||||
]
|
||||
|
||||
export const RUST_TARGET = Bun.env.RUST_TARGET
|
||||
|
||||
function nativeTarget() {
|
||||
const { platform, arch } = process
|
||||
if (platform === "darwin") return arch === "arm64" ? "aarch64-apple-darwin" : "x86_64-apple-darwin"
|
||||
if (platform === "win32") return arch === "arm64" ? "aarch64-pc-windows-msvc" : "x86_64-pc-windows-msvc"
|
||||
if (platform === "linux") return arch === "arm64" ? "aarch64-unknown-linux-gnu" : "x86_64-unknown-linux-gnu"
|
||||
throw new Error(`Unsupported platform: ${platform}/${arch}`)
|
||||
}
|
||||
|
||||
export function getCurrentSidecar(target = RUST_TARGET ?? nativeTarget()) {
|
||||
const binaryConfig = SIDECAR_BINARIES.find((b) => b.rustTarget === target)
|
||||
if (!binaryConfig) throw new Error(`Sidecar configuration not available for Rust target '${target}'`)
|
||||
|
||||
return binaryConfig
|
||||
}
|
||||
|
||||
export async function copyBinaryToSidecarFolder(source: string) {
|
||||
const dir = `resources`
|
||||
await $`mkdir -p ${dir}`
|
||||
const dest = windowsify(`${dir}/opencode-cli`)
|
||||
await $`cp ${source} ${dest}`
|
||||
if (process.platform === "win32" && process.env.GITHUB_ACTIONS === "true") {
|
||||
await $`pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File ../../script/sign-windows.ps1 ${dest}`
|
||||
}
|
||||
if (process.platform === "darwin") await $`codesign --force --sign - ${dest}`
|
||||
|
||||
console.log(`Copied ${source} to ${dest}`)
|
||||
}
|
||||
|
||||
export function windowsify(path: string) {
|
||||
if (path.endsWith(".exe")) return path
|
||||
return `${path}${process.platform === "win32" ? ".exe" : ""}`
|
||||
}
|
||||
Reference in New Issue
Block a user