mirror of
https://github.com/anomalyco/opencode.git
synced 2026-09-03 01:34:23 +00:00
fix(desktop): bundle the CLI in production releases (#46705)
This commit is contained in:
parent
0b771030ed
commit
ddda404d99
8 changed files with 56 additions and 26 deletions
3
.github/workflows/publish.yml
vendored
3
.github/workflows/publish.yml
vendored
|
|
@ -417,7 +417,6 @@ jobs:
|
|||
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
|
||||
|
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
if: github.ref_name == 'beta'
|
||||
with:
|
||||
name: opencode-preview-cli
|
||||
path: packages/cli/dist
|
||||
|
|
@ -480,7 +479,7 @@ jobs:
|
|||
OPENCODE_VERSION: ${{ needs.version.outputs.version }}
|
||||
OPENCODE_CHANNEL: ${{ (github.ref_name == 'beta' && 'beta') || 'prod' }}
|
||||
OPENCODE_CLI_TARGET: ${{ matrix.settings.target }}
|
||||
OPENCODE_CLI_DIST: ${{ (github.ref_name == 'beta' && format('{0}/packages/cli/dist', github.workspace)) || '' }}
|
||||
OPENCODE_CLI_DIST: ${{ github.workspace }}/packages/cli/dist
|
||||
|
||||
- name: Build
|
||||
run: bun run build
|
||||
|
|
|
|||
|
|
@ -87,6 +87,11 @@ stdenv.mkDerivation (finalAttrs: {
|
|||
|
||||
cd packages/desktop
|
||||
|
||||
export OPENCODE_CLI_DIST="$TMPDIR/desktop-cli"
|
||||
cli_package=$(bun -e 'import { getCurrentCli } from "./scripts/utils.ts"; console.log(getCurrentCli().package.replace("@opencode-ai/", ""))')
|
||||
mkdir -p "$OPENCODE_CLI_DIST/$cli_package/bin"
|
||||
cp ${lib.getExe opencode} "$OPENCODE_CLI_DIST/$cli_package/bin/opencode2"
|
||||
|
||||
bun run build
|
||||
npx electron-builder --dir \
|
||||
--config electron-builder.config.ts \
|
||||
|
|
|
|||
|
|
@ -17,3 +17,25 @@ bundle the assets as an application. The resulting app will be in `dist/`.
|
|||
```bash
|
||||
bun run build && bun run package
|
||||
```
|
||||
|
||||
Production builds require a prebuilt V2 CLI distribution. The release workflow supplies the artifact from the same run:
|
||||
|
||||
```bash
|
||||
OPENCODE_CHANNEL=prod OPENCODE_CLI_DIST=/absolute/path/to/packages/cli/dist bun run build
|
||||
OPENCODE_CHANNEL=prod bun run package
|
||||
```
|
||||
|
||||
Set `OPENCODE_CLI_TARGET` when packaging for a different architecture. The CLI is placed outside `app.asar` in the
|
||||
application's resources directory, and packaging fails if it is missing.
|
||||
|
||||
CLI preparation uses these channel rules:
|
||||
|
||||
| Channel | Without `OPENCODE_CLI_DIST` | With `OPENCODE_CLI_DIST` |
|
||||
| -------------------------------------- | ------------------------------ | --------------------------------------------- |
|
||||
| `dev`, `local`, unset, or unrecognized | Download the dev CLI | Download the dev CLI; ignore the distribution |
|
||||
| `beta` | Download the beta CLI | Copy the supplied CLI; fail if it is missing |
|
||||
| `prod`, `latest` | Fail before changing resources | Copy the supplied CLI; fail if it is missing |
|
||||
|
||||
`bun dev` is separate from packaging: it uses local renderer/server mode, the dev app identity, and the CLI source by
|
||||
default. `bun dev --download-server <version>` instead downloads that CLI version for local development. Neither path
|
||||
requires `OPENCODE_CLI_DIST` or runs the production prebuild.
|
||||
|
|
|
|||
|
|
@ -190,19 +190,8 @@ for (const channel of ["dev", "beta"] as const) {
|
|||
{
|
||||
from: "resources/",
|
||||
to: "",
|
||||
filter: ["opencode-cli*"],
|
||||
filter: ["opencode-cli", "opencode-cli.exe"],
|
||||
},
|
||||
])
|
||||
})
|
||||
}
|
||||
|
||||
test("does not bundle the CLI in prod builds", async () => {
|
||||
const previous = process.env.OPENCODE_CHANNEL
|
||||
process.env.OPENCODE_CHANNEL = "prod"
|
||||
const module = await import("./electron-builder.config.ts?no-cli-resource=prod")
|
||||
const config = module.default as Configuration
|
||||
if (previous === undefined) delete process.env.OPENCODE_CHANNEL
|
||||
else process.env.OPENCODE_CHANNEL = previous
|
||||
|
||||
expect(config.extraResources).toEqual([])
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { execFile } from "node:child_process"
|
||||
import { stat } from "node:fs/promises"
|
||||
import path from "node:path"
|
||||
import { fileURLToPath } from "node:url"
|
||||
import { promisify } from "node:util"
|
||||
|
|
@ -45,6 +46,7 @@ export function macSignOptions(options: CustomMacSignOptions): CustomMacSignOpti
|
|||
const channel = (() => {
|
||||
const raw = process.env.OPENCODE_CHANNEL
|
||||
if (raw === "dev" || raw === "beta" || raw === "prod") return raw
|
||||
if (raw === "latest") return "prod"
|
||||
return "dev"
|
||||
})()
|
||||
|
||||
|
|
@ -84,16 +86,21 @@ const getBase = (appId: string): Configuration => ({
|
|||
"!**/node_modules/js-yaml/dist/{js-yaml.js,js-yaml.min.js,*.map}",
|
||||
"!**/node_modules/js-yaml/bin{,/**/*}",
|
||||
],
|
||||
extraResources:
|
||||
channel !== "prod"
|
||||
? [
|
||||
{
|
||||
from: "resources/",
|
||||
to: "",
|
||||
filter: ["opencode-cli*"],
|
||||
},
|
||||
]
|
||||
: [],
|
||||
extraResources: [
|
||||
{
|
||||
from: "resources/",
|
||||
to: "",
|
||||
filter: ["opencode-cli", "opencode-cli.exe"],
|
||||
},
|
||||
],
|
||||
afterPack: async (context) => {
|
||||
const cli = path.join(
|
||||
context.packager.getResourcesDir(context.appOutDir),
|
||||
context.electronPlatformName === "win32" ? "opencode-cli.exe" : "opencode-cli",
|
||||
)
|
||||
const file = await stat(cli)
|
||||
if (!file.isFile() || file.size === 0) throw new Error(`Bundled CLI must be a non-empty file: ${cli}`)
|
||||
},
|
||||
mac: {
|
||||
category: "public.app-category.developer-tools",
|
||||
icon: `resources/icons/icon.icns`,
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ export default defineConfig(({ command }) => ({
|
|||
dedupe: ["effect"],
|
||||
},
|
||||
define: {
|
||||
"import.meta.env.OPENCODE_CHANNEL": JSON.stringify(channel),
|
||||
// Local renderer/server mode still uses the dev application identity and updater policy.
|
||||
"import.meta.env.OPENCODE_CHANNEL": JSON.stringify(channel === "local" ? "dev" : channel),
|
||||
},
|
||||
build: {
|
||||
minify: command === "build",
|
||||
|
|
|
|||
|
|
@ -4,9 +4,15 @@ import { $ } from "bun"
|
|||
import { copyBuiltCliToResources, downloadCliToResources, resolveChannel } from "./utils"
|
||||
|
||||
const channel = resolveChannel()
|
||||
if (channel === "prod" && !Bun.env.OPENCODE_CLI_DIST) {
|
||||
throw new Error("OPENCODE_CLI_DIST is required for production desktop builds")
|
||||
}
|
||||
|
||||
await $`bun ./scripts/copy-icons.ts ${channel}`
|
||||
await $`bun ./scripts/copy-metainfo.ts ${channel}`
|
||||
|
||||
if (channel === "dev") await downloadCliToResources()
|
||||
if (channel === "beta" && Bun.env.OPENCODE_CLI_DIST) await copyBuiltCliToResources(Bun.env.OPENCODE_CLI_DIST)
|
||||
if ((channel === "beta" || channel === "prod") && Bun.env.OPENCODE_CLI_DIST) {
|
||||
await copyBuiltCliToResources(Bun.env.OPENCODE_CLI_DIST)
|
||||
}
|
||||
if (channel === "beta" && !Bun.env.OPENCODE_CLI_DIST) await downloadCliToResources("beta")
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ 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
|
||||
if (raw === "latest") return "prod"
|
||||
return "dev"
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue