Merged PR #757
This commit is contained in:
@@ -173,9 +173,81 @@ jobs:
|
||||
- name: Install method smoke tests
|
||||
run: bun run ci:test:install-methods
|
||||
|
||||
release:
|
||||
release_binary:
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
needs: [check, native, test, install_methods]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-22.04
|
||||
target_id: linux-x64
|
||||
native_artifact: pi-natives-linux-x64
|
||||
binary_path: packages/coding-agent/binaries/omp-linux-x64
|
||||
- os: ubuntu-24.04-arm
|
||||
target_id: linux-arm64
|
||||
native_artifact: pi-natives-linux-arm64
|
||||
binary_path: packages/coding-agent/binaries/omp-linux-arm64
|
||||
- os: macos-15-intel
|
||||
target_id: darwin-x64
|
||||
native_artifact: pi-natives-darwin-x64
|
||||
binary_path: packages/coding-agent/binaries/omp-darwin-x64
|
||||
- os: macos-14
|
||||
target_id: darwin-arm64
|
||||
native_artifact: pi-natives-darwin-arm64
|
||||
binary_path: packages/coding-agent/binaries/omp-darwin-arm64
|
||||
- os: windows-latest
|
||||
target_id: win32-x64
|
||||
native_artifact: pi-natives-win32-x64
|
||||
binary_path: packages/coding-agent/binaries/omp-windows-x64.exe
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
lfs: true
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: "1.3"
|
||||
- name: Cache bun dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.bun/install/cache
|
||||
key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }}
|
||||
- run: bun install --frozen-lockfile
|
||||
- name: Download native addon(s)
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.native_artifact }}
|
||||
path: packages/natives/native
|
||||
- name: Build release binary
|
||||
env:
|
||||
RELEASE_TARGETS: ${{ matrix.target_id }}
|
||||
run: bun run ci:release:build-binaries
|
||||
- name: Smoke release binary
|
||||
if: runner.os != 'Windows'
|
||||
run: |
|
||||
runtime_dir="$(mktemp -d)"
|
||||
HOME="$runtime_dir/home" XDG_DATA_HOME="$runtime_dir/xdg" "${{ matrix.binary_path }}" --version
|
||||
- name: Smoke release binary (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
$runtimeDir = Join-Path $env:TEMP ("omp-runtime-" + [System.Guid]::NewGuid().ToString("N"))
|
||||
New-Item -ItemType Directory -Force -Path $runtimeDir | Out-Null
|
||||
$env:HOME = Join-Path $runtimeDir "home"
|
||||
$env:XDG_DATA_HOME = Join-Path $runtimeDir "xdg"
|
||||
& "${{ matrix.binary_path }}" --version
|
||||
- name: Upload release binary artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: omp-binary-${{ matrix.target_id }}
|
||||
path: ${{ matrix.binary_path }}
|
||||
|
||||
release:
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
needs: [release_binary]
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -197,6 +269,12 @@ jobs:
|
||||
path: ~/.bun/install/cache
|
||||
key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }}
|
||||
- run: bun install --frozen-lockfile
|
||||
- name: Download release binaries
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: omp-binary-*
|
||||
path: packages/coding-agent/binaries
|
||||
merge-multiple: true
|
||||
- name: Download native addons
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
@@ -205,9 +283,6 @@ jobs:
|
||||
merge-multiple: true
|
||||
- name: Verify native addons
|
||||
run: bun run ci:release:verify-natives
|
||||
|
||||
- name: Build binaries
|
||||
run: bun run ci:release:build-binaries
|
||||
- name: Stage native addons for release
|
||||
run: cp packages/natives/native/*.node packages/coding-agent/binaries/
|
||||
- name: Create GitHub Release
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
- Fixed edit tool diff and replace operations to report missing-file failures as `File not found: <path>` errors instead of raw filesystem ENOENT errors
|
||||
- Fixed `local://` URL path leak on Linux where `//` collapsing to `/` produced `local:/path` forms that bypassed the internal protocol handler and leaked as filesystem paths, breaking plan mode file resolution
|
||||
- Fixed Darwin compiled binaries failing to start under Bun 1.3.12 by ad-hoc signing local and release binary builds after applying Bun's no-codesign workaround ([#754](https://github.com/can1357/oh-my-pi/issues/754))
|
||||
- Fixed Tavily web search silently returning off-topic news articles when `--recency` was set. The provider was unconditionally coupling `topic: "news"` to recency, which scoped Tavily's index to news publications and excluded documentation, release notes, GitHub, and all non-news technical content. Technical queries with `--recency` now return the correct corpus.
|
||||
- Fixed status-line sanitization to strip OSC, DCS, PM, APC, and 8-bit CSI escape sequences instead of leaving payload fragments in the UI
|
||||
- Fixed inline read tool previews to avoid rendering duplicate summary rows above the same code cell
|
||||
@@ -7115,4 +7116,4 @@ Initial public release.
|
||||
- Git branch display in footer
|
||||
- Message queueing during streaming responses
|
||||
- OAuth integration for Gmail and Google Calendar access
|
||||
- HTML export with syntax highlighting and collapsible sections
|
||||
- HTML export with syntax highlighting and collapsible sections
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"omp": "src/cli.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "bun --cwd=../stats scripts/generate-client-bundle.ts --generate && bun --cwd=../natives run embed:native && bun build --compile --define PI_COMPILED=true --external mupdf --root ../.. ./src/cli.ts --outfile dist/omp && bun --cwd=../natives run embed:native --reset && bun --cwd=../stats scripts/generate-client-bundle.ts --reset",
|
||||
"build": "bun scripts/build-binary.ts",
|
||||
"check": "biome check . && bun run check:types",
|
||||
"check:types": "tsgo -p tsconfig.json --noEmit",
|
||||
"lint": "biome lint .",
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env bun
|
||||
|
||||
import * as path from "node:path";
|
||||
|
||||
const packageDir = path.join(import.meta.dir, "..");
|
||||
const outputPath = path.join(packageDir, "dist", "omp");
|
||||
|
||||
function shouldAdhocSignDarwinBinary(): boolean {
|
||||
return process.platform === "darwin";
|
||||
}
|
||||
|
||||
async function runCommand(command: string[], env: NodeJS.ProcessEnv = Bun.env): Promise<void> {
|
||||
const proc = Bun.spawn(command, {
|
||||
cwd: packageDir,
|
||||
env,
|
||||
stdout: "inherit",
|
||||
stderr: "inherit",
|
||||
});
|
||||
const exitCode = await proc.exited;
|
||||
if (exitCode !== 0) {
|
||||
throw new Error(`Command failed with exit code ${exitCode}: ${command.join(" ")}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
await runCommand(["bun", "--cwd=../stats", "scripts/generate-client-bundle.ts", "--generate"]);
|
||||
try {
|
||||
await runCommand(["bun", "--cwd=../natives", "run", "embed:native"]);
|
||||
try {
|
||||
const buildEnv = shouldAdhocSignDarwinBinary() ? { ...Bun.env, BUN_NO_CODESIGN_MACHO_BINARY: "1" } : Bun.env;
|
||||
await runCommand(
|
||||
[
|
||||
"bun",
|
||||
"build",
|
||||
"--compile",
|
||||
"--define",
|
||||
"PI_COMPILED=true",
|
||||
"--external",
|
||||
"mupdf",
|
||||
"--root",
|
||||
"../..",
|
||||
"./src/cli.ts",
|
||||
"--outfile",
|
||||
"dist/omp",
|
||||
],
|
||||
buildEnv,
|
||||
);
|
||||
|
||||
// Bun 1.3.12 emits a truncated Mach-O signature on darwin builds.
|
||||
if (shouldAdhocSignDarwinBinary()) {
|
||||
await runCommand(["codesign", "--force", "--sign", "-", outputPath]);
|
||||
}
|
||||
} finally {
|
||||
await runCommand(["bun", "--cwd=../natives", "run", "embed:native", "--reset"]);
|
||||
}
|
||||
} finally {
|
||||
await runCommand(["bun", "--cwd=../stats", "scripts/generate-client-bundle.ts", "--reset"]);
|
||||
}
|
||||
}
|
||||
|
||||
await main();
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
import * as fs from "node:fs/promises";
|
||||
import * as path from "node:path";
|
||||
import { $ } from "bun";
|
||||
|
||||
interface BinaryTarget {
|
||||
id: string;
|
||||
platform: string;
|
||||
arch: string;
|
||||
target: string;
|
||||
@@ -17,30 +17,35 @@ const entrypoint = "./packages/coding-agent/src/cli.ts";
|
||||
const isDryRun = process.argv.includes("--dry-run");
|
||||
const targets: BinaryTarget[] = [
|
||||
{
|
||||
id: "darwin-arm64",
|
||||
platform: "darwin",
|
||||
arch: "arm64",
|
||||
target: "bun-darwin-arm64",
|
||||
outfile: "packages/coding-agent/binaries/omp-darwin-arm64",
|
||||
},
|
||||
{
|
||||
id: "darwin-x64",
|
||||
platform: "darwin",
|
||||
arch: "x64",
|
||||
target: "bun-darwin-x64",
|
||||
outfile: "packages/coding-agent/binaries/omp-darwin-x64",
|
||||
},
|
||||
{
|
||||
id: "linux-x64",
|
||||
platform: "linux",
|
||||
arch: "x64",
|
||||
target: "bun-linux-x64-modern",
|
||||
outfile: "packages/coding-agent/binaries/omp-linux-x64",
|
||||
},
|
||||
{
|
||||
id: "linux-arm64",
|
||||
platform: "linux",
|
||||
arch: "arm64",
|
||||
target: "bun-linux-arm64",
|
||||
outfile: "packages/coding-agent/binaries/omp-linux-arm64",
|
||||
},
|
||||
{
|
||||
id: "win32-x64",
|
||||
platform: "win32",
|
||||
arch: "x64",
|
||||
target: "bun-windows-x64-modern",
|
||||
@@ -48,19 +53,53 @@ const targets: BinaryTarget[] = [
|
||||
},
|
||||
];
|
||||
|
||||
function parseRequestedTargets(): Set<string> | null {
|
||||
const flagIndex = process.argv.findIndex(arg => arg === "--targets");
|
||||
const flagValue =
|
||||
flagIndex >= 0
|
||||
? process.argv[flagIndex + 1]
|
||||
: process.argv.find(arg => arg.startsWith("--targets="))?.split("=", 2)[1] ?? Bun.env.RELEASE_TARGETS;
|
||||
|
||||
if (!flagValue) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Set(
|
||||
flagValue
|
||||
.split(",")
|
||||
.map(value => value.trim())
|
||||
.filter(Boolean),
|
||||
);
|
||||
}
|
||||
|
||||
function shouldAdhocSignDarwinBinary(target: BinaryTarget): boolean {
|
||||
return target.platform === "darwin" && process.platform === "darwin";
|
||||
}
|
||||
|
||||
async function runCommand(command: string[], cwd: string, env: NodeJS.ProcessEnv = Bun.env): Promise<void> {
|
||||
const proc = Bun.spawn(command, {
|
||||
cwd,
|
||||
env,
|
||||
stdout: "inherit",
|
||||
stderr: "inherit",
|
||||
});
|
||||
const exitCode = await proc.exited;
|
||||
if (exitCode !== 0) {
|
||||
throw new Error(`Command failed with exit code ${exitCode}: ${command.join(" ")}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function embedNative(target: BinaryTarget): Promise<void> {
|
||||
if (isDryRun) {
|
||||
console.log(`DRY RUN bun --cwd=packages/natives run embed:native [${target.platform}/${target.arch}]`);
|
||||
return;
|
||||
}
|
||||
|
||||
await $`bun --cwd=packages/natives run embed:native`
|
||||
.cwd(repoRoot)
|
||||
.env({
|
||||
...Bun.env,
|
||||
TARGET_PLATFORM: target.platform,
|
||||
TARGET_ARCH: target.arch,
|
||||
});
|
||||
await runCommand(["bun", "--cwd=packages/natives", "run", "embed:native"], repoRoot, {
|
||||
...Bun.env,
|
||||
TARGET_PLATFORM: target.platform,
|
||||
TARGET_ARCH: target.arch,
|
||||
});
|
||||
}
|
||||
|
||||
async function buildBinary(target: BinaryTarget): Promise<void> {
|
||||
@@ -71,9 +110,19 @@ async function buildBinary(target: BinaryTarget): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
await $`bun build --compile --define PI_COMPILED=true --root . --external mupdf --target=${target.target} ${entrypoint} --outfile ${target.outfile}`.cwd(
|
||||
const buildEnv = shouldAdhocSignDarwinBinary(target)
|
||||
? { ...Bun.env, BUN_NO_CODESIGN_MACHO_BINARY: "1" }
|
||||
: Bun.env;
|
||||
await runCommand(
|
||||
["bun", "build", "--compile", "--define", "PI_COMPILED=true", "--root", ".", "--external", "mupdf", "--target", target.target, entrypoint, "--outfile", target.outfile],
|
||||
repoRoot,
|
||||
buildEnv,
|
||||
);
|
||||
|
||||
// Bun 1.3.12 emits a truncated Mach-O signature on darwin builds.
|
||||
if (shouldAdhocSignDarwinBinary(target)) {
|
||||
await runCommand(["codesign", "--force", "--sign", "-", path.join(repoRoot, target.outfile)], repoRoot);
|
||||
}
|
||||
}
|
||||
|
||||
async function generateBundle(): Promise<void> {
|
||||
@@ -81,7 +130,7 @@ async function generateBundle(): Promise<void> {
|
||||
console.log("DRY RUN bun --cwd=packages/stats scripts/generate-client-bundle.ts --generate");
|
||||
return;
|
||||
}
|
||||
await $`bun --cwd=packages/stats scripts/generate-client-bundle.ts --generate`.cwd(repoRoot);
|
||||
await runCommand(["bun", "--cwd=packages/stats", "scripts/generate-client-bundle.ts", "--generate"], repoRoot);
|
||||
}
|
||||
|
||||
async function resetArtifacts(): Promise<void> {
|
||||
@@ -90,15 +139,33 @@ async function resetArtifacts(): Promise<void> {
|
||||
console.log("DRY RUN bun --cwd=packages/stats scripts/generate-client-bundle.ts --reset");
|
||||
return;
|
||||
}
|
||||
await $`bun --cwd=packages/natives run embed:native --reset`.cwd(repoRoot);
|
||||
await $`bun --cwd=packages/stats scripts/generate-client-bundle.ts --reset`.cwd(repoRoot);
|
||||
await runCommand(["bun", "--cwd=packages/natives", "run", "embed:native", "--reset"], repoRoot);
|
||||
await runCommand(["bun", "--cwd=packages/stats", "scripts/generate-client-bundle.ts", "--reset"], repoRoot);
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const requestedTargets = parseRequestedTargets();
|
||||
const selectedTargets = requestedTargets
|
||||
? targets.filter(target => requestedTargets.has(target.id))
|
||||
: targets;
|
||||
|
||||
if (requestedTargets) {
|
||||
const unknownTargets = [...requestedTargets].filter(
|
||||
requestedTarget => !targets.some(target => target.id === requestedTarget),
|
||||
);
|
||||
if (unknownTargets.length > 0) {
|
||||
throw new Error(`Unknown release target(s): ${unknownTargets.join(", ")}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedTargets.length === 0) {
|
||||
throw new Error("No release targets selected.");
|
||||
}
|
||||
|
||||
await fs.mkdir(binariesDir, { recursive: true });
|
||||
await generateBundle();
|
||||
try {
|
||||
for (const target of targets) {
|
||||
for (const target of selectedTargets) {
|
||||
await buildBinary(target);
|
||||
}
|
||||
} finally {
|
||||
|
||||
@@ -20,12 +20,10 @@ RUN bun install --frozen-lockfile
|
||||
RUN bun --cwd=packages/natives run build
|
||||
RUN cd packages/coding-agent && bun run build
|
||||
|
||||
# Install binary and native addon to PATH
|
||||
# Install binary to PATH
|
||||
RUN mkdir -p /root/.local/bin && \
|
||||
cp packages/coding-agent/dist/omp /root/.local/bin/ && \
|
||||
cp packages/natives/native/pi_natives.linux-x64-modern.node /root/.local/bin/ && \
|
||||
cp packages/natives/native/pi_natives.linux-x64-baseline.node /root/.local/bin/
|
||||
cp packages/coding-agent/dist/omp /root/.local/bin/
|
||||
ENV PATH="/root/.local/bin:$PATH"
|
||||
|
||||
# Verify
|
||||
RUN omp --version
|
||||
RUN HOME=/tmp/omp-home XDG_DATA_HOME=/tmp/omp-xdg omp --version
|
||||
|
||||
@@ -4,6 +4,9 @@ set -euo pipefail
|
||||
cd "$(dirname "$0")/../.."
|
||||
ROOT_DIR="$(pwd)"
|
||||
WORK_DIR="$(mktemp -d)"
|
||||
TMP_WORK_DIR="$WORK_DIR/tmp"
|
||||
mkdir -p "$TMP_WORK_DIR"
|
||||
export TMPDIR="$TMP_WORK_DIR"
|
||||
trap 'rm -rf "$WORK_DIR"' EXIT
|
||||
|
||||
section() {
|
||||
@@ -13,9 +16,11 @@ section() {
|
||||
|
||||
smoke_cli() {
|
||||
local omp_bin="$1"
|
||||
"$omp_bin" --version
|
||||
"$omp_bin" --help >/dev/null
|
||||
"$omp_bin" stats --summary >/dev/null
|
||||
local runtime_dir
|
||||
runtime_dir="$(mktemp -d "$WORK_DIR/compiled-runtime.XXXXXX")"
|
||||
XDG_DATA_HOME="$runtime_dir/xdg" HOME="$runtime_dir/home" "$omp_bin" --version
|
||||
XDG_DATA_HOME="$runtime_dir/xdg" HOME="$runtime_dir/home" "$omp_bin" --help >/dev/null
|
||||
XDG_DATA_HOME="$runtime_dir/xdg" HOME="$runtime_dir/home" "$omp_bin" stats --summary >/dev/null
|
||||
}
|
||||
|
||||
find_tarball() {
|
||||
@@ -40,15 +45,6 @@ bun --cwd=packages/coding-agent run build
|
||||
BINARY_DIR="$WORK_DIR/binary-bin"
|
||||
mkdir -p "$BINARY_DIR"
|
||||
cp packages/coding-agent/dist/omp "$BINARY_DIR/omp"
|
||||
shopt -s nullglob
|
||||
native_addons=(packages/natives/native/pi_natives.*.node)
|
||||
shopt -u nullglob
|
||||
if [ "${#native_addons[@]}" -eq 0 ]; then
|
||||
echo "No native addon files found in packages/natives/native"
|
||||
exit 1
|
||||
fi
|
||||
cp "${native_addons[@]}" "$BINARY_DIR/"
|
||||
|
||||
smoke_cli "$BINARY_DIR/omp"
|
||||
|
||||
section "Source install smoke"
|
||||
|
||||
Reference in New Issue
Block a user