Просмотр исходного кода

desktop: publish betas to separate repo (#14376)

Brendan Allan 1 месяц назад
Родитель
Сommit
ce17f9dd94

+ 31 - 4
.github/workflows/publish.yml

@@ -41,6 +41,13 @@ jobs:
 
       - uses: ./.github/actions/setup-bun
 
+      - name: Setup git committer
+        id: committer
+        uses: ./.github/actions/setup-git-committer
+        with:
+          opencode-app-id: ${{ vars.OPENCODE_APP_ID }}
+          opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }}
+
       - name: Install OpenCode
         if: inputs.bump || inputs.version
         run: bun i -g opencode-ai
@@ -49,14 +56,16 @@ jobs:
         run: |
           ./script/version.ts
         env:
-          GH_TOKEN: ${{ github.token }}
+          GH_TOKEN: ${{ steps.committer.outputs.token }}
           OPENCODE_BUMP: ${{ inputs.bump }}
           OPENCODE_VERSION: ${{ inputs.version }}
           OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
+          GH_REPO: ${{ (github.ref_name == 'beta' && 'anomalyco/opencode-beta') || github.repository }}
     outputs:
       version: ${{ steps.version.outputs.version }}
       release: ${{ steps.version.outputs.release }}
       tag: ${{ steps.version.outputs.tag }}
+      repo: ${{ steps.version.outputs.repo }}
 
   build-cli:
     needs: version
@@ -69,6 +78,13 @@ jobs:
 
       - uses: ./.github/actions/setup-bun
 
+      - name: Setup git committer
+        id: committer
+        uses: ./.github/actions/setup-git-committer
+        with:
+          opencode-app-id: ${{ vars.OPENCODE_APP_ID }}
+          opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }}
+
       - name: Build
         id: build
         run: |
@@ -76,7 +92,8 @@ jobs:
         env:
           OPENCODE_VERSION: ${{ needs.version.outputs.version }}
           OPENCODE_RELEASE: ${{ needs.version.outputs.release }}
-          GH_TOKEN: ${{ github.token }}
+          GH_REPO: ${{ needs.version.outputs.repo }}
+          GH_TOKEN: ${{ steps.committer.outputs.token }}
 
       - uses: actions/upload-artifact@v4
         with:
@@ -189,6 +206,13 @@ jobs:
         if: contains(matrix.settings.host, 'ubuntu')
         run: cargo tauri --version
 
+      - name: Setup git committer
+        id: committer
+        uses: ./.github/actions/setup-git-committer
+        with:
+          opencode-app-id: ${{ vars.OPENCODE_APP_ID }}
+          opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }}
+
       - name: Build and upload artifacts
         uses: tauri-apps/tauri-action@390cbe447412ced1303d35abe75287949e43437a
         timeout-minutes: 60
@@ -196,14 +220,16 @@ jobs:
           projectPath: packages/desktop
           uploadWorkflowArtifacts: true
           tauriScript: ${{ (contains(matrix.settings.host, 'ubuntu') && 'cargo tauri') || '' }}
-          args: --target ${{ matrix.settings.target }} --config ./src-tauri/tauri.prod.conf.json --verbose
+          args: --target ${{ matrix.settings.target }} --config ${{ (github.ref_name == 'beta' && './src-tauri/tauri.beta.conf.json') || './src-tauri/tauri.prod.conf.json' }} --verbose
           updaterJsonPreferNsis: true
           releaseId: ${{ needs.version.outputs.release }}
           tagName: ${{ needs.version.outputs.tag }}
           releaseDraft: true
           releaseAssetNamePattern: opencode-desktop-[platform]-[arch][ext]
+          repo: ${{ (github.ref_name == 'beta' && 'opencode-beta') || '' }}
+          releaseCommitish: ${{ github.sha }}
         env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          GITHUB_TOKEN: ${{ steps.committer.outputs.token }}
           TAURI_BUNDLER_NEW_APPIMAGE_FORMAT: true
           TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
           TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
@@ -280,4 +306,5 @@ jobs:
           OPENCODE_RELEASE: ${{ needs.version.outputs.release }}
           AUR_KEY: ${{ secrets.AUR_KEY }}
           GITHUB_TOKEN: ${{ steps.committer.outputs.token }}
+          GH_REPO: ${{ needs.version.outputs.repo }}
           NPM_CONFIG_PROVENANCE: false

+ 13 - 10
packages/console/app/src/routes/download/[platform].ts → packages/console/app/src/routes/download/[channel]/[platform].ts

@@ -1,5 +1,5 @@
-import { APIEvent } from "@solidjs/start"
-import { DownloadPlatform } from "./types"
+import type { APIEvent } from "@solidjs/start"
+import type { DownloadPlatform } from "../types"
 
 const assetNames: Record<string, string> = {
   "darwin-aarch64-dmg": "opencode-desktop-darwin-aarch64.dmg",
@@ -17,17 +17,20 @@ const downloadNames: Record<string, string> = {
   "windows-x64-nsis": "OpenCode Desktop Installer.exe",
 } satisfies { [K in DownloadPlatform]?: string }
 
-export async function GET({ params: { platform } }: APIEvent) {
+export async function GET({ params: { platform, channel } }: APIEvent) {
   const assetName = assetNames[platform]
   if (!assetName) return new Response("Not Found", { status: 404 })
 
-  const resp = await fetch(`https://github.com/anomalyco/opencode/releases/latest/download/${assetName}`, {
-    cf: {
-      // in case gh releases has rate limits
-      cacheTtl: 60 * 5,
-      cacheEverything: true,
-    },
-  } as any)
+  const resp = await fetch(
+    `https://github.com/anomalyco/${channel === "stable" ? "opencode" : "opencode-beta"}/releases/latest/download/${assetName}`,
+    {
+      cf: {
+        // in case gh releases has rate limits
+        cacheTtl: 60 * 5,
+        cacheEverything: true,
+      },
+    } as any,
+  )
 
   const downloadName = downloadNames[platform]
 

+ 11 - 11
packages/console/app/src/routes/download/index.tsx

@@ -1,18 +1,18 @@
 import "./index.css"
-import { Title, Meta } from "@solidjs/meta"
-import { A, createAsync, query } from "@solidjs/router"
-import { Header } from "~/component/header"
-import { Footer } from "~/component/footer"
-import { IconCopy, IconCheck } from "~/component/icon"
+import { Meta, Title } from "@solidjs/meta"
+import { A } from "@solidjs/router"
+import { createSignal, type JSX, onMount, Show } from "solid-js"
 import { Faq } from "~/component/faq"
-import desktopAppIcon from "../../asset/lander/opencode-desktop-icon.png"
+import { Footer } from "~/component/footer"
+import { Header } from "~/component/header"
+import { IconCheck, IconCopy } from "~/component/icon"
 import { Legal } from "~/component/legal"
+import { LocaleLinks } from "~/component/locale-links"
 import { config } from "~/config"
-import { createSignal, onMount, Show, JSX } from "solid-js"
-import { DownloadPlatform } from "./types"
 import { useI18n } from "~/context/i18n"
 import { useLanguage } from "~/context/language"
-import { LocaleLinks } from "~/component/locale-links"
+import desktopAppIcon from "../../asset/lander/opencode-desktop-icon.png"
+import type { DownloadPlatform } from "./types"
 
 type OS = "macOS" | "Windows" | "Linux" | null
 
@@ -40,8 +40,8 @@ function getDownloadPlatform(os: OS): DownloadPlatform {
   }
 }
 
-function getDownloadHref(platform: DownloadPlatform) {
-  return `/download/${platform}`
+function getDownloadHref(platform: DownloadPlatform, channel: "stable" | "beta" = "stable") {
+  return `/download/${channel}/${platform}`
 }
 
 function IconDownload(props: JSX.SvgSVGAttributes<SVGSVGElement>) {

+ 21 - 0
packages/desktop/src-tauri/tauri.beta.conf.json

@@ -0,0 +1,21 @@
+{
+  "$schema": "https://schema.tauri.app/config/2",
+  "productName": "OpenCode Beta",
+  "identifier": "ai.opencode.desktop.beta",
+  "bundle": {
+    "createUpdaterArtifacts": true,
+    "linux": {
+      "rpm": {
+        "compression": {
+          "type": "none"
+        }
+      }
+    }
+  },
+  "plugins": {
+    "updater": {
+      "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEYwMDM5Nzg5OUMzOUExMDQKUldRRW9UbWNpWmNEOENYT01CV0lhOXR1UFhpaXJsK1Z3aU9lZnNtNzE0TDROWVMwVW9XQnFOelkK",
+      "endpoints": ["https://github.com/anomalyco/opencode-beta/releases/latest/download/latest.json"]
+    }
+  }
+}

+ 11 - 7
packages/opencode/script/build.ts

@@ -1,10 +1,10 @@
 #!/usr/bin/env bun
 
-import solidPlugin from "../node_modules/@opentui/solid/scripts/solid-plugin"
-import path from "path"
-import fs from "fs"
 import { $ } from "bun"
+import fs from "fs"
+import path from "path"
 import { fileURLToPath } from "url"
+import solidPlugin from "../node_modules/@opentui/solid/scripts/solid-plugin"
 
 const __filename = fileURLToPath(import.meta.url)
 const __dirname = path.dirname(__filename)
@@ -12,8 +12,9 @@ const dir = path.resolve(__dirname, "..")
 
 process.chdir(dir)
 
-import pkg from "../package.json"
 import { Script } from "@opencode-ai/script"
+import pkg from "../package.json"
+
 const modelsUrl = process.env.OPENCODE_MODELS_URL || "https://models.dev"
 // Fetch and generate models.dev snapshot
 const modelsData = process.env.MODELS_DEV_API_JSON
@@ -26,7 +27,11 @@ await Bun.write(
 console.log("Generated models-snapshot.ts")
 
 // Load migrations from migration directories
-const migrationDirs = (await fs.promises.readdir(path.join(dir, "migration"), { withFileTypes: true }))
+const migrationDirs = (
+  await fs.promises.readdir(path.join(dir, "migration"), {
+    withFileTypes: true,
+  })
+)
   .filter((entry) => entry.isDirectory() && /^\d{4}\d{2}\d{2}\d{2}\d{2}\d{2}/.test(entry.name))
   .map((entry) => entry.name)
   .sort()
@@ -171,7 +176,6 @@ for (const item of targets) {
     compile: {
       autoloadBunfig: false,
       autoloadDotenv: false,
-      //@ts-ignore (bun types aren't up to date)
       autoloadTsconfig: true,
       autoloadPackageJson: true,
       target: name.replace(pkg.name, "bun") as any,
@@ -214,7 +218,7 @@ if (Script.release) {
       await $`zip -r ../../${key}.zip *`.cwd(`dist/${key}/bin`)
     }
   }
-  await $`gh release upload v${Script.version} ./dist/*.zip ./dist/*.tar.gz --clobber`
+  await $`gh release upload v${Script.version} ./dist/*.zip ./dist/*.tar.gz --clobber --repo ${process.env.GH_REPO}`
 }
 
 export { binaries }

+ 10 - 7
script/publish.ts

@@ -57,13 +57,16 @@ await $`bun install`
 await import(`../packages/sdk/js/script/build.ts`)
 
 if (Script.release) {
-  await $`git commit -am "release: v${Script.version}"`
-  await $`git tag v${Script.version}`
-  await $`git fetch origin`
-  await $`git cherry-pick HEAD..origin/dev`.nothrow()
-  await $`git push origin HEAD --tags --no-verify --force-with-lease`
-  await new Promise((resolve) => setTimeout(resolve, 5_000))
-  await $`gh release edit v${Script.version} --draft=false`
+  if (!Script.preview) {
+    await $`git commit -am "release: v${Script.version}"`
+    await $`git tag v${Script.version}`
+    await $`git fetch origin`
+    await $`git cherry-pick HEAD..origin/dev`.nothrow()
+    await $`git push origin HEAD --tags --no-verify --force-with-lease`
+    await new Promise((resolve) => setTimeout(resolve, 5_000))
+  }
+
+  await $`gh release edit v${Script.version} --draft=false --repo ${process.env.GH_REPO}`
 }
 
 console.log("\n=== cli ===\n")

+ 8 - 0
script/version.ts

@@ -17,8 +17,16 @@ if (!Script.preview) {
   const release = await $`gh release view v${Script.version} --json tagName,databaseId`.json()
   output.push(`release=${release.databaseId}`)
   output.push(`tag=${release.tagName}`)
+} else if (Script.channel === "beta") {
+  await $`gh release create v${Script.version} -d --title "v${Script.version}" --repo ${process.env.GH_REPO}`
+  const release =
+    await $`gh release view v${Script.version} --json tagName,databaseId --repo ${process.env.GH_REPO}`.json()
+  output.push(`release=${release.databaseId}`)
+  output.push(`tag=${release.tagName}`)
 }
 
+output.push(`repo=${process.env.GH_REPO}`)
+
 if (process.env.GITHUB_OUTPUT) {
   await Bun.write(process.env.GITHUB_OUTPUT, output.join("\n"))
 }