Skip to content

Commit c1bf16c

Browse files
committed
fix(release): ship 0.1.41 desktop bundles
1 parent dc32848 commit c1bf16c

File tree

7 files changed

+75
-41
lines changed

7 files changed

+75
-41
lines changed

.github/workflows/release.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ concurrency:
1414

1515
env:
1616
TURBO_TELEMETRY_DISABLED: 1
17-
OPENLINEAR_SKIP_OPENCODE_DOWNLOAD: 1
1817

1918
jobs:
2019
build-release:

apps/desktop/src-tauri/tauri.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schema.tauri.app/config/2",
33
"productName": "OpenLinear",
4-
"version": "0.1.40",
4+
"version": "0.1.41",
55
"identifier": "com.openlinear.app",
66
"build": {
77
"beforeDevCommand": "PORT=3000 pnpm --filter @openlinear/desktop-ui dev",

packages/openlinear/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "openlinear",
3-
"version": "0.1.40",
3+
"version": "0.1.41",
44
"description": "OpenLinear launcher, installer, and validation utilities",
55
"license": "MIT",
66
"repository": {

packaging/aur/openlinear-bin/.SRCINFO

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pkgbase = openlinear-bin
22
pkgdesc = AI-powered project management that actually writes the code — desktop app
3-
pkgver = 0.1.40
3+
pkgver = 0.1.41
44
pkgrel = 1
55
url = https://github.com/kaizen403/openlinear
66
arch = x86_64
@@ -14,9 +14,9 @@ pkgbase = openlinear-bin
1414
conflicts = openlinear
1515
options = !strip
1616
options = !debug
17-
source = openlinear-0.1.40-x86_64-linux.tar.gz::https://github.com/kaizen403/openlinear/releases/download/v0.1.40/openlinear-0.1.40-x86_64-linux.tar.gz
17+
source = openlinear-0.1.41-x86_64-linux.tar.gz::https://github.com/kaizen403/openlinear/releases/download/v0.1.41/openlinear-0.1.41-x86_64-linux.tar.gz
1818
source = openlinear.desktop
19-
source = openlinear.png::https://raw.githubusercontent.com/kaizen403/openlinear/v0.1.40/apps/desktop/src-tauri/icons/icon.png
19+
source = openlinear.png::https://raw.githubusercontent.com/kaizen403/openlinear/v0.1.41/apps/desktop/src-tauri/icons/icon.png
2020
sha256sums = SKIP
2121
sha256sums = SKIP
2222
sha256sums = SKIP

packaging/aur/openlinear-bin/PKGBUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Maintainer: kaizen403 <kaizen403@proton.me>
22
pkgname=openlinear-bin
3-
pkgver=0.1.40
3+
pkgver=0.1.41
44
pkgrel=1
55
pkgdesc="AI-powered project management that actually writes the code — desktop app"
66
arch=('x86_64')

scripts/build-sidecar.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,5 +129,10 @@ else
129129
echo " Get it from: https://github.com/anomalyco/opencode/releases"
130130
fi
131131

132+
if [ ! -f "$OPENCODE_BIN" ]; then
133+
echo " ! opencode binary is required for desktop packaging" >&2
134+
exit 1
135+
fi
136+
132137
echo "==> Build complete!"
133138
ls -la "$BINARIES_DIR"

scripts/smoke-test-sidecar.mjs

Lines changed: 64 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
#!/usr/bin/env node
22

3-
import { spawnSync } from "node:child_process";
4-
import { constants as fsConstants, mkdtempSync, readFileSync, rmSync } from "node:fs";
3+
import { spawn } from "node:child_process";
4+
import { constants as fsConstants } from "node:fs";
55
import { access } from "node:fs/promises";
6-
import os from "node:os";
76
import path from "node:path";
87
import process from "node:process";
98
import { fileURLToPath } from "node:url";
109

1110
const ROOT_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
11+
const READINESS_LINE = "Server running on http://localhost:3001";
12+
const STARTUP_TIMEOUT_MS = 15_000;
1213

1314
function resolveBinaryPath() {
1415
if (process.platform === "linux") {
@@ -46,47 +47,76 @@ function resolveBinaryPath() {
4647
throw new Error(`Unsupported smoke test platform: ${process.platform}/${process.arch}`);
4748
}
4849

49-
function shellQuote(value) {
50-
return `'${value.replace(/'/g, `'\\''`)}'`;
51-
}
52-
5350
async function main() {
5451
const binaryPath = resolveBinaryPath();
5552
await access(binaryPath, fsConstants.X_OK);
5653

57-
const tmpDir = mkdtempSync(path.join(os.tmpdir(), "openlinear-sidecar-smoke-"));
58-
const logPath = path.join(tmpDir, "sidecar.log");
59-
60-
try {
61-
const command = [
62-
`timeout 15s ${shellQuote(binaryPath)} > ${shellQuote(logPath)} 2>&1 || true`,
63-
`cat ${shellQuote(logPath)}`,
64-
`grep -q 'Server running on http://localhost:3001' ${shellQuote(logPath)}`,
65-
].join("; ");
66-
67-
const result = spawnSync("bash", ["-lc", command], {
54+
await new Promise((resolve, reject) => {
55+
const child = spawn(binaryPath, [], {
6856
cwd: ROOT_DIR,
6957
env: { ...process.env },
70-
encoding: "utf8",
58+
stdio: ["ignore", "pipe", "pipe"],
7159
});
7260

73-
if (result.stdout) {
74-
process.stdout.write(result.stdout);
75-
}
61+
let settled = false;
62+
let output = "";
7663

77-
if (result.stderr) {
78-
process.stderr.write(result.stderr);
79-
}
64+
const settle = (callback) => {
65+
if (settled) {
66+
return;
67+
}
8068

81-
if (result.status !== 0) {
82-
const logOutput = readFileSync(logPath, "utf8");
83-
throw new Error(
84-
`Sidecar smoke test failed before readiness. Exit code: ${result.status}\n${logOutput}`,
85-
);
86-
}
87-
} finally {
88-
rmSync(tmpDir, { recursive: true, force: true });
89-
}
69+
settled = true;
70+
clearTimeout(timeoutId);
71+
72+
if (!child.killed) {
73+
child.kill("SIGTERM");
74+
}
75+
76+
callback();
77+
};
78+
79+
const onChunk = (chunk, writer) => {
80+
const text = chunk.toString();
81+
output += text;
82+
writer.write(text);
83+
84+
if (output.includes(READINESS_LINE)) {
85+
settle(resolve);
86+
}
87+
};
88+
89+
child.stdout?.on("data", (chunk) => onChunk(chunk, process.stdout));
90+
child.stderr?.on("data", (chunk) => onChunk(chunk, process.stderr));
91+
92+
child.on("error", (error) => {
93+
settle(() => reject(error));
94+
});
95+
96+
child.on("exit", (code, signal) => {
97+
if (settled) {
98+
return;
99+
}
100+
101+
settle(() => {
102+
reject(
103+
new Error(
104+
`Sidecar smoke test failed before readiness. Exit code: ${code ?? "null"}, signal: ${signal ?? "null"}\n${output}`,
105+
),
106+
);
107+
});
108+
});
109+
110+
const timeoutId = setTimeout(() => {
111+
settle(() => {
112+
reject(
113+
new Error(
114+
`Sidecar smoke test timed out after ${STARTUP_TIMEOUT_MS}ms before readiness.\n${output}`,
115+
),
116+
);
117+
});
118+
}, STARTUP_TIMEOUT_MS);
119+
});
90120
}
91121

92122
main().catch((error) => {

0 commit comments

Comments
 (0)