Compare commits

..

39 Commits

Author SHA1 Message Date
opencode a8ce77b211 release: v0.0.0-ci-202601291718 2026-01-29 17:22:50 +00:00
Dax Raad 5e5327f652 sync 2026-01-29 12:16:25 -05:00
Dax Raad 9a4fcd3ac7 sync 2026-01-29 12:14:05 -05:00
Dax Raad 1b91bb8d35 sync 2026-01-29 12:13:16 -05:00
Dax Raad 1f84bfb90f sync 2026-01-29 12:08:56 -05:00
Dax Raad 6dea8e8337 sync 2026-01-29 12:02:28 -05:00
Dax Raad f67d329bd7 sync 2026-01-29 11:59:35 -05:00
Dax Raad 811c1cd41a sync 2026-01-29 11:55:44 -05:00
Dax Raad 1b24338027 sync 2026-01-29 11:54:57 -05:00
Dax Raad da13e89286 sync 2026-01-29 11:51:17 -05:00
Dax Raad e9d7f42e64 sync 2026-01-29 11:48:18 -05:00
Dax Raad 0369328eb2 sync 2026-01-29 11:42:11 -05:00
Dax Raad 01711d57e7 sync 2026-01-29 11:37:00 -05:00
Dax Raad 09a2f66016 sync 2026-01-29 11:31:55 -05:00
Dax Raad 7de4105285 sync 2026-01-29 11:31:50 -05:00
Dax Raad 8969581e2c sync 2026-01-29 11:23:21 -05:00
Dax Raad b8ff1f49de sync 2026-01-29 11:20:56 -05:00
Dax Raad 95f671aa14 sync 2026-01-29 11:18:39 -05:00
Dax Raad f13a5df854 sync 2026-01-29 11:17:38 -05:00
Dax Raad 1081d897b6 sync 2026-01-29 11:16:32 -05:00
Dax Raad 4300b4584a sync 2026-01-29 10:59:46 -05:00
Dax Raad 8076980332 sync 2026-01-29 10:55:14 -05:00
Dax Raad 12f4deba5b sync 2026-01-29 10:47:55 -05:00
Dax Raad cadbf2d214 sync 2026-01-29 10:46:28 -05:00
Dax Raad c38a45e3dc sync 2026-01-29 10:34:32 -05:00
Dax Raad 0e523b077e sync 2026-01-29 10:28:06 -05:00
Dax Raad 2258cf8f5f sync 2026-01-29 10:25:46 -05:00
Dax Raad 7b078fc164 sync 2026-01-29 10:25:37 -05:00
Dax Raad 6f83042fa1 sync 2026-01-29 10:25:33 -05:00
Dax Raad 3a60b07e51 sync 2026-01-29 10:25:14 -05:00
Dax Raad 4bea81d87c sync 2026-01-29 10:18:45 -05:00
Dax Raad 2bc9bac157 sync 2026-01-29 10:17:57 -05:00
Dax Raad d82ba619d0 sync 2026-01-29 09:59:11 -05:00
Dax Raad cac61862a6 sync 2026-01-29 09:58:49 -05:00
Dax Raad b1f8a5cf4e sync 2026-01-29 09:57:08 -05:00
Dax Raad a57b637a0c sync 2026-01-29 09:38:02 -05:00
Dax Raad 340332fca0 sync 2026-01-29 09:36:51 -05:00
Dax Raad 2fdca7fc08 sync 2026-01-29 09:36:13 -05:00
Dax Raad 6ae26dd0cf sync 2026-01-29 09:34:55 -05:00
32 changed files with 85 additions and 309 deletions
-34
View File
@@ -1,34 +0,0 @@
name: beta
on:
push:
branches: [dev]
pull_request:
types: [opened, synchronize, labeled, unlabeled]
jobs:
sync:
if: |
github.event_name == 'push' ||
(github.event_name == 'pull_request' &&
contains(github.event.pull_request.labels.*.name, 'contributor'))
runs-on: blacksmith-4vcpu-ubuntu-2404
permissions:
contents: write
pull-requests: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Bun
uses: ./.github/actions/setup-bun
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Sync beta branch
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bun script/beta.ts
+1 -1
View File
@@ -1,4 +1,4 @@
name: close-stale-prs
name: Close stale PRs
on:
workflow_dispatch:
+1 -1
View File
@@ -1,4 +1,4 @@
name: daily-issues-recap
name: Daily Issues Recap
on:
schedule:
+1 -1
View File
@@ -1,4 +1,4 @@
name: daily-pr-recap
name: Daily PR Recap
on:
schedule:
+1 -1
View File
@@ -1,4 +1,4 @@
name: docs-update
name: Docs Update
on:
schedule:
+1 -1
View File
@@ -1,4 +1,4 @@
name: duplicate-issues
name: Duplicate Issue Detection
on:
issues:
@@ -1,4 +1,4 @@
name: pr-management
name: Duplicate PR Check
on:
pull_request_target:
@@ -63,26 +63,3 @@ jobs:
gh pr comment "$PR_NUMBER" --body "_The following comment was made by an LLM, it may be inaccurate:_
$COMMENT"
add-contributor-label:
runs-on: ubuntu-latest
permissions:
pull-requests: write
issues: write
steps:
- name: Add Contributor Label
uses: actions/github-script@v8
with:
script: |
const isPR = !!context.payload.pull_request;
const issueNumber = isPR ? context.payload.pull_request.number : context.payload.issue.number;
const authorAssociation = isPR ? context.payload.pull_request.author_association : context.payload.issue.author_association;
if (authorAssociation === 'CONTRIBUTOR') {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
labels: ['contributor']
});
}
-1
View File
@@ -4,7 +4,6 @@ on:
push:
branches:
- dev
pull_request:
workflow_dispatch:
jobs:
@@ -1,4 +1,4 @@
name: nix-desktop
name: nix desktop
on:
push:
@@ -21,7 +21,7 @@ on:
workflow_dispatch:
jobs:
nix-desktop:
build-desktop:
strategy:
fail-fast: false
matrix:
+1 -1
View File
@@ -1,4 +1,4 @@
name: notify-discord
name: discord
on:
release:
+1 -1
View File
@@ -1,4 +1,4 @@
name: pr-standards
name: PR Standards
on:
pull_request_target:
+23 -18
View File
@@ -6,7 +6,6 @@ on:
branches:
- ci
- dev
- beta
- snapshot-*
workflow_dispatch:
inputs:
@@ -37,7 +36,7 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
fetch-depth: 0
- uses: ./.github/actions/setup-bun
- id: version
run: |
@@ -58,8 +57,9 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
fetch-tags: true
fetch-depth: 0
- run: git fetch --force --tags
- uses: ./.github/actions/setup-bun
@@ -81,6 +81,7 @@ jobs:
version: ${{ needs.version.outputs.version }}
build-tauri:
if: false
needs:
- build-cli
- version
@@ -103,8 +104,7 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
fetch-tags: true
fetch-depth: 0
- uses: apple-actions/import-codesign-certs@v2
if: ${{ runner.os == 'macOS' }}
@@ -126,6 +126,8 @@ jobs:
run: |
echo "${{ secrets.APPLE_API_KEY_PATH }}" > $RUNNER_TEMP/apple-api-key.p8
- run: git fetch --force --tags
- uses: ./.github/actions/setup-bun
- name: install dependencies (ubuntu only)
@@ -164,18 +166,22 @@ jobs:
cargo tauri --version
- name: Build and upload artifacts
uses: tauri-apps/tauri-action@390cbe447412ced1303d35abe75287949e43437a
uses: Wandalen/wretry.action@v3
timeout-minutes: 60
with:
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
updaterJsonPreferNsis: true
releaseId: ${{ needs.version.outputs.release }}
tagName: ${{ needs.version.outputs.tag }}
releaseDraft: true
releaseAssetNamePattern: opencode-desktop-[platform]-[arch][ext]
attempt_limit: 3
attempt_delay: 10000
action: tauri-apps/tauri-action@390cbe447412ced1303d35abe75287949e43437a
with: |
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
updaterJsonPreferNsis: true
releaseId: ${{ needs.version.outputs.release }}
tagName: ${{ needs.version.outputs.tag }}
releaseDraft: true
releaseAssetNamePattern: opencode-desktop-[platform]-[arch][ext]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_BUNDLER_NEW_APPIMAGE_FORMAT: true
@@ -192,12 +198,11 @@ jobs:
needs:
- version
- build-cli
- build-tauri
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
fetch-depth: 0
- name: Install OpenCode
if: inputs.bump || inputs.version
+1 -1
View File
@@ -1,4 +1,4 @@
name: review
name: Guidelines Check
on:
issue_comment:
+1 -1
View File
@@ -1,4 +1,4 @@
name: stale-issues
name: "Auto-close stale issues"
on:
schedule:
+4
View File
@@ -1,6 +1,9 @@
name: test
on:
push:
branches:
- dev
pull_request:
workflow_dispatch:
jobs:
@@ -17,6 +20,7 @@ jobs:
command: |
git config --global user.email "bot@opencode.ai"
git config --global user.name "opencode"
bun turbo typecheck
bun turbo test
- name: windows
host: windows-latest
+1 -1
View File
@@ -1,4 +1,4 @@
name: triage
name: Issue Triage
on:
issues:
@@ -1,4 +1,4 @@
name: nix-hashes
name: Update Nix Hashes
permissions:
contents: write
@@ -11,17 +11,17 @@ on:
- "package.json"
- "packages/*/package.json"
- "flake.lock"
- ".github/workflows/nix-hashes.yml"
- ".github/workflows/update-nix-hashes.yml"
pull_request:
paths:
- "bun.lock"
- "package.json"
- "packages/*/package.json"
- "flake.lock"
- ".github/workflows/nix-hashes.yml"
- ".github/workflows/update-nix-hashes.yml"
jobs:
nix-hashes:
update-node-modules-hashes:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
runs-on: blacksmith-4vcpu-ubuntu-2404
env:
+1 -1
View File
@@ -1,6 +1,6 @@
import { test, expect } from "./fixtures"
test.skip("file tree can expand folders and open a file", async ({ page, gotoSession }) => {
test("file tree can expand folders and open a file", async ({ page, gotoSession }) => {
await gotoSession()
const toggle = page.getByRole("button", { name: "Toggle file tree" })
+1 -1
View File
@@ -36,7 +36,7 @@ function writeAndWait(term: Terminal, data: string): Promise<void> {
})
}
describe.skip("SerializeAddon", () => {
describe("SerializeAddon", () => {
describe("ANSI color preservation", () => {
test("should preserve text attributes (bold, italic, underline)", async () => {
const { term, addon } = createTerminal()
@@ -5,7 +5,7 @@ import { makePersisted, type SyncStorage } from "@solid-primitives/storage"
import { createScrollPersistence } from "./layout-scroll"
describe("createScrollPersistence", () => {
test.skip("debounces persisted scroll writes", async () => {
test("debounces persisted scroll writes", async () => {
const key = "layout-scroll.test"
const data = new Map<string, string>()
const writes: string[] = []
-7
View File
@@ -540,7 +540,6 @@ export namespace Config {
codesearch: PermissionAction.optional(),
lsp: PermissionRule.optional(),
doom_loop: PermissionAction.optional(),
skill: PermissionRule.optional(),
})
.catchall(PermissionRule)
.or(PermissionAction),
@@ -560,11 +559,6 @@ export namespace Config {
})
export type Command = z.infer<typeof Command>
export const Skills = z.object({
paths: z.array(z.string()).optional().describe("Additional paths to skill folders"),
})
export type Skills = z.infer<typeof Skills>
export const Agent = z
.object({
model: z.string().optional(),
@@ -900,7 +894,6 @@ export namespace Config {
.record(z.string(), Command)
.optional()
.describe("Command configuration, see https://opencode.ai/docs/commands"),
skills: Skills.optional().describe("Additional skill folder paths"),
watcher: z
.object({
ignore: z.array(z.string()).optional(),
+3 -3
View File
@@ -284,8 +284,8 @@ export namespace ProviderTransform {
if (id.includes("glm-4.7")) return 1.0
if (id.includes("minimax-m2")) return 1.0
if (id.includes("kimi-k2")) {
// kimi-k2-thinking & kimi-k2.5 && kimi-k2p5
if (id.includes("thinking") || id.includes("k2.") || id.includes("k2p")) {
// kimi-k2-thinking & kimi-k2.5
if (id.includes("thinking") || id.includes("k2.")) {
return 1.0
}
return 0.6
@@ -296,7 +296,7 @@ export namespace ProviderTransform {
export function topP(model: Provider.Model) {
const id = model.id.toLowerCase()
if (id.includes("qwen")) return 1
if (id.includes("minimax-m2") || id.includes("kimi-k2.5") || id.includes("kimi-k2p5") || id.includes("gemini")) {
if (id.includes("minimax-m2") || id.includes("kimi-k2.5") || id.includes("gemini")) {
return 0.95
}
return undefined
+1 -7
View File
@@ -264,13 +264,7 @@ export namespace LLM {
extractReasoningMiddleware({ tagName: "think", startWithReasoning: false }),
],
}),
experimental_telemetry: {
isEnabled: cfg.experimental?.openTelemetry,
metadata: {
userId: cfg.username ?? "unknown",
sessionId: input.sessionID,
},
},
experimental_telemetry: { isEnabled: cfg.experimental?.openTelemetry },
})
}
-21
View File
@@ -1,6 +1,5 @@
import z from "zod"
import path from "path"
import os from "os"
import { Config } from "../config/config"
import { Instance } from "../project/instance"
import { NamedError } from "@opencode-ai/util/error"
@@ -41,7 +40,6 @@ export namespace Skill {
const OPENCODE_SKILL_GLOB = new Bun.Glob("{skill,skills}/**/SKILL.md")
const CLAUDE_SKILL_GLOB = new Bun.Glob("skills/**/SKILL.md")
const SKILL_GLOB = new Bun.Glob("**/SKILL.md")
export const state = Instance.state(async () => {
const skills: Record<string, Info> = {}
@@ -124,25 +122,6 @@ export namespace Skill {
}
}
// Scan additional skill paths from config
const config = await Config.get()
for (const skillPath of config.skills?.paths ?? []) {
const expanded = skillPath.startsWith("~/") ? path.join(os.homedir(), skillPath.slice(2)) : skillPath
const resolved = path.isAbsolute(expanded) ? expanded : path.join(Instance.directory, expanded)
if (!(await Filesystem.isDir(resolved))) {
log.warn("skill path not found", { path: resolved })
continue
}
for await (const match of SKILL_GLOB.scan({
cwd: resolved,
absolute: true,
onlyFiles: true,
followSymlinks: true,
})) {
await addSkill(match)
}
}
return skills
})
+3 -2
View File
@@ -62,11 +62,12 @@ export const SkillTool = Tool.define("skill", async (ctx) => {
always: [params.name],
metadata: {},
})
const content = (await ConfigMarkdown.parse(skill.location)).content
// Load and parse skill content
const parsed = await ConfigMarkdown.parse(skill.location)
const dir = path.dirname(skill.location)
// Format output similar to plugin pattern
const output = [`## Skill: ${skill.name}`, "", `**Base directory**: ${dir}`, "", content.trim()].join("\n")
const output = [`## Skill: ${skill.name}`, "", `**Base directory**: ${dir}`, "", parsed.content.trim()].join("\n")
return {
title: `Loaded skill: ${skill.name}`,
-10
View File
@@ -1364,7 +1364,6 @@ export type PermissionConfig =
codesearch?: PermissionActionConfig
lsp?: PermissionRuleConfig
doom_loop?: PermissionActionConfig
skill?: PermissionRuleConfig
[key: string]: PermissionRuleConfig | Array<string> | PermissionActionConfig | undefined
}
| PermissionActionConfig
@@ -1634,15 +1633,6 @@ export type Config = {
subtask?: boolean
}
}
/**
* Additional skill folder paths
*/
skills?: {
/**
* Additional paths to skill folders
*/
paths?: Array<string>
}
watcher?: {
ignore?: Array<string>
}
-16
View File
@@ -8994,9 +8994,6 @@
},
"doom_loop": {
"$ref": "#/components/schemas/PermissionActionConfig"
},
"skill": {
"$ref": "#/components/schemas/PermissionRuleConfig"
}
},
"additionalProperties": {
@@ -9509,19 +9506,6 @@
"required": ["template"]
}
},
"skills": {
"description": "Additional skill folder paths",
"type": "object",
"properties": {
"paths": {
"description": "Additional paths to skill folders",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"watcher": {
"type": "object",
"properties": {
-8
View File
@@ -82,9 +82,7 @@ You can also access our models through the following API endpoints.
| Gemini 3 Pro | gemini-3-pro | `https://opencode.ai/zen/v1/models/gemini-3-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
| MiniMax M2.1 | minimax-m2.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| MiniMax M2.1 Free | minimax-m2.1-free | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| GLM 4.7 | glm-4.7 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| GLM 4.7 Free | glm-4.7-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| GLM 4.6 | glm-4.6 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Kimi K2 Thinking | kimi-k2-thinking | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
@@ -115,9 +113,7 @@ We support a pay-as-you-go model. Below are the prices **per 1M tokens**.
| Model | Input | Output | Cached Read | Cached Write |
| --------------------------------- | ------ | ------ | ----------- | ------------ |
| Big Pickle | Free | Free | Free | - |
| MiniMax M2.1 Free | Free | Free | Free | - |
| MiniMax M2.1 | $0.30 | $1.20 | $0.10 | - |
| GLM 4.7 Free | Free | Free | Free | - |
| GLM 4.7 | $0.60 | $2.20 | $0.10 | - |
| GLM 4.6 | $0.60 | $2.20 | $0.10 | - |
| Kimi K2.5 | $0.60 | $3.00 | $0.10 | - |
@@ -153,8 +149,6 @@ Credit card fees are passed along at cost (4.4% + $0.30 per transaction); we don
The free models:
- GLM 4.7 is currently free on OpenCode for a limited time. The team is using this time to collect feedback and improve the model.
- MiniMax M2.1 is currently free on OpenCode for a limited time. The team is using this time to collect feedback and improve the model.
- Big Pickle is a stealth model that's free on OpenCode for a limited time. The team is using this time to collect feedback and improve the model.
<a href={email}>Contact us</a> if you have any questions.
@@ -184,8 +178,6 @@ charging you more than $20 if your balance goes below $5.
All our models are hosted in the US. Our providers follow a zero-retention policy and do not use your data for model training, with the following exceptions:
- GLM 4.7: During its free period, collected data may be used to improve the model.
- MiniMax M2.1: During its free period, collected data may be used to improve the model.
- Big Pickle: During its free period, collected data may be used to improve the model.
- OpenAI APIs: Requests are retained for 30 days in accordance with [OpenAI's Data Policies](https://platform.openai.com/docs/guides/your-data).
- Anthropic APIs: Requests are retained for 30 days in accordance with [Anthropic's Data Policies](https://docs.anthropic.com/en/docs/claude-code/data-usage).
-127
View File
@@ -1,127 +0,0 @@
#!/usr/bin/env bun
interface PR {
number: number
headRefName: string
headRefOid: string
createdAt: string
isDraft: boolean
title: string
}
async function main() {
console.log("Fetching open contributor PRs...")
const prsResult =
await $`gh pr list --label contributor --state open --json number,headRefName,headRefOid,createdAt,isDraft,title --limit 100`.nothrow()
if (prsResult.exitCode !== 0) {
throw new Error(`Failed to fetch PRs: ${prsResult.stderr}`)
}
const allPRs: PR[] = JSON.parse(prsResult.stdout)
const prs = allPRs.filter((pr) => !pr.isDraft)
console.log(`Found ${prs.length} open non-draft contributor PRs`)
console.log("Fetching latest dev branch...")
const fetchDev = await $`git fetch origin dev`.nothrow()
if (fetchDev.exitCode !== 0) {
throw new Error(`Failed to fetch dev branch: ${fetchDev.stderr}`)
}
console.log("Checking out beta branch...")
const checkoutBeta = await $`git checkout -B beta origin/dev`.nothrow()
if (checkoutBeta.exitCode !== 0) {
throw new Error(`Failed to checkout beta branch: ${checkoutBeta.stderr}`)
}
const applied: number[] = []
const skipped: Array<{ number: number; reason: string }> = []
for (const pr of prs) {
console.log(`\nProcessing PR #${pr.number}: ${pr.title}`)
const fetchPR = await $`git fetch origin pull/${pr.number}/head:pr-${pr.number}`.nothrow()
if (fetchPR.exitCode !== 0) {
console.log(` Failed to fetch PR #${pr.number}, skipping`)
skipped.push({ number: pr.number, reason: "Failed to fetch" })
continue
}
const merge = await $`git merge --squash pr-${pr.number}`.nothrow()
if (merge.exitCode !== 0) {
console.log(` Squash merge failed for PR #${pr.number}`)
console.log(` Error: ${merge.stderr}`)
await $`git reset --hard HEAD`.nothrow()
skipped.push({ number: pr.number, reason: `Squash merge failed: ${merge.stderr}` })
continue
}
const add = await $`git add -A`.nothrow()
if (add.exitCode !== 0) {
console.log(` Failed to stage changes for PR #${pr.number}`)
await $`git reset --hard HEAD`.nothrow()
skipped.push({ number: pr.number, reason: "Failed to stage" })
continue
}
const status = await $`git status --porcelain`.nothrow()
if (status.exitCode !== 0 || !status.stdout.trim()) {
console.log(` No changes to commit for PR #${pr.number}, skipping`)
await $`git reset --hard HEAD`.nothrow()
skipped.push({ number: pr.number, reason: "No changes to commit" })
continue
}
const commitMsg = `Apply PR #${pr.number}: ${pr.title}`
const commit = await Bun.spawn(["git", "commit", "-m", commitMsg], { stdout: "pipe", stderr: "pipe" })
const commitExit = await commit.exited
const commitStderr = await Bun.readableStreamToText(commit.stderr)
if (commitExit !== 0) {
console.log(` Failed to commit PR #${pr.number}`)
console.log(` Error: ${commitStderr}`)
await $`git reset --hard HEAD`.nothrow()
skipped.push({ number: pr.number, reason: `Commit failed: ${commitStderr}` })
continue
}
console.log(` Successfully applied PR #${pr.number}`)
applied.push(pr.number)
}
console.log("\n--- Summary ---")
console.log(`Applied: ${applied.length} PRs`)
applied.forEach((num) => console.log(` - PR #${num}`))
console.log(`Skipped: ${skipped.length} PRs`)
skipped.forEach((x) => console.log(` - PR #${x.number}: ${x.reason}`))
console.log("\nForce pushing beta branch...")
const push = await $`git push origin beta --force`.nothrow()
if (push.exitCode !== 0) {
throw new Error(`Failed to push beta branch: ${push.stderr}`)
}
console.log("Successfully synced beta branch")
}
main().catch((err) => {
console.error("Error:", err)
process.exit(1)
})
function $(strings: TemplateStringsArray, ...values: unknown[]) {
const cmd = strings.reduce((acc, str, i) => acc + str + (values[i] ?? ""), "")
return {
async nothrow() {
const proc = Bun.spawn(cmd.split(" "), {
stdout: "pipe",
stderr: "pipe",
})
const exitCode = await proc.exited
const stdout = await new Response(proc.stdout).text()
const stderr = await new Response(proc.stderr).text()
return { exitCode, stdout, stderr }
},
}
}
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/env bun
import { Script } from "@opencode-ai/script"
import { $ } from "bun"
if (!Script.preview) {
await $`gh release edit v${Script.version} --draft=false`
}
await $`bun install`
await $`gh release download --pattern "opencode-linux-*64.tar.gz" --pattern "opencode-darwin-*64.zip" -D dist`
await import(`../packages/opencode/script/publish-registries.ts`)
+9 -4
View File
@@ -32,8 +32,16 @@ Add highlights before publishing. Delete this section if no highlights.
`
let notes: string[] = []
console.log("=== publishing ===\n")
if (!Script.preview) {
const previous = await getLatestRelease()
notes = await buildNotes(previous, "HEAD")
// notes.unshift(highlightsTemplate)
}
const pkgjsons = await Array.fromAsync(
new Bun.Glob("**/package.json").scan({
absolute: true,
@@ -58,16 +66,13 @@ await $`bun install`
await import(`../packages/sdk/js/script/build.ts`)
if (Script.release) {
const previous = await getLatestRelease()
const notes = await buildNotes(previous, "HEAD")
// notes.unshift(highlightsTemplate)
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 --title "v${Script.version}" --notes ${notes.join("\n") || "No notable changes"}`
await $`gh release edit v${Script.version} --draft --title "v${Script.version}" --notes ${notes.join("\n") || "No notable changes"}`
}
console.log("\n=== cli ===\n")
+8 -8
View File
@@ -3,15 +3,15 @@
import { Script } from "@opencode-ai/script"
import { $ } from "bun"
let output = [`version=${Script.version}`]
let output = `version=${Script.version}\n`
if (!Script.preview) {
await $`gh release create v${Script.version} -d --title "v${Script.version}" ${Script.preview ? "--prerelease" : ""}`
const release = await $`gh release view v${Script.version} --json id,tagName`.json()
output.push(`release=${release.id}`)
output.push(`tag=${release.tagName}`)
}
await $`gh release create v${Script.version} -d --title "v${Script.version}" ${Script.preview ? "--prerelease" : ""}`
const release = await $`gh release view v${Script.version} --json id,tagName`.json()
output += `release=${release.id}\n`
output += `tag=${release.tagName}\n`
console.log(output)
if (process.env.GITHUB_OUTPUT) {
await Bun.write(process.env.GITHUB_OUTPUT, output.join("\n"))
await Bun.write(process.env.GITHUB_OUTPUT, output)
}