fix(tauri): require standalone server in desktop bundles
This commit is contained in:
37
.github/workflows/build-and-upload.yml
vendored
37
.github/workflows/build-and-upload.yml
vendored
@@ -652,42 +652,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build Linux bundle (Tauri)
|
- name: Build Linux bundle (Tauri)
|
||||||
working-directory: packages/tauri-app
|
working-directory: packages/tauri-app
|
||||||
shell: bash
|
run: npm exec -- tauri build
|
||||||
env:
|
|
||||||
RUST_BACKTRACE: full
|
|
||||||
RUST_LOG: tauri_bundler=trace
|
|
||||||
TAURI_LOG_LEVEL: debug
|
|
||||||
run: |
|
|
||||||
set -uo pipefail
|
|
||||||
|
|
||||||
build_log="$RUNNER_TEMP/tauri-linux-build.log"
|
|
||||||
status=0
|
|
||||||
|
|
||||||
npm exec -- tauri build 2>&1 | tee "$build_log" || status=$?
|
|
||||||
|
|
||||||
if [ "$status" -eq 0 ]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Tauri Linux bundle failed with exit code $status" >&2
|
|
||||||
|
|
||||||
echo "::group::Tauri build log tail"
|
|
||||||
tail -n 200 "$build_log" || true
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
echo "::group::Bundle output tree"
|
|
||||||
find target -maxdepth 6 \( -type d -o -type f \) | sort || true
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
echo "::group::Likely linuxdeploy temp files"
|
|
||||||
find /tmp -maxdepth 3 \( -iname '*linuxdeploy*' -o -iname '*appimage*' -o -iname '*.desktop' -o -iname '*.log' \) | sort || true
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
echo "::group::Bundle metadata files"
|
|
||||||
find target -maxdepth 8 -type f \( -name '*.desktop' -o -name 'AppRun' -o -name '*.AppImage' -o -name '*.log' -o -name '*.json' \) | sort || true
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
exit "$status"
|
|
||||||
|
|
||||||
- name: Package Tauri artifacts (Linux)
|
- name: Package Tauri artifacts (Linux)
|
||||||
if: ${{ inputs.upload || inputs.upload_actions_artifacts }}
|
if: ${{ inputs.upload || inputs.upload_actions_artifacts }}
|
||||||
|
|||||||
@@ -87,10 +87,6 @@ function ensureStandaloneServerBuild() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function shouldBuildStandaloneServer() {
|
|
||||||
return process.platform !== "linux"
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureUiBuild() {
|
function ensureUiBuild() {
|
||||||
const loadingHtml = path.join(uiDist, "loading.html")
|
const loadingHtml = path.join(uiDist, "loading.html")
|
||||||
if (fs.existsSync(loadingHtml)) {
|
if (fs.existsSync(loadingHtml)) {
|
||||||
@@ -146,17 +142,6 @@ function ensureServerDependencies() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeStaleStandaloneServerBuild() {
|
|
||||||
const staleNames = ["codenomad-server", "codenomad-server.exe"]
|
|
||||||
for (const name of staleNames) {
|
|
||||||
const stalePath = path.join(serverRoot, "dist", name)
|
|
||||||
if (fs.existsSync(stalePath)) {
|
|
||||||
fs.rmSync(stalePath, { force: true })
|
|
||||||
console.log(`[prebuild] removed stale standalone server artifact ${stalePath}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureUiDevDependencies() {
|
function ensureUiDevDependencies() {
|
||||||
if (fs.existsSync(viteBinPath)) {
|
if (fs.existsSync(viteBinPath)) {
|
||||||
return
|
return
|
||||||
@@ -328,12 +313,7 @@ function copyUiLoadingAssets() {
|
|||||||
ensureRollupPlatformBinary()
|
ensureRollupPlatformBinary()
|
||||||
ensureEsbuildPlatformBinary()
|
ensureEsbuildPlatformBinary()
|
||||||
ensureServerBuild()
|
ensureServerBuild()
|
||||||
if (shouldBuildStandaloneServer()) {
|
ensureStandaloneServerBuild()
|
||||||
ensureStandaloneServerBuild()
|
|
||||||
} else {
|
|
||||||
removeStaleStandaloneServerBuild()
|
|
||||||
console.log("[prebuild] skipping standalone server executable for Linux packaging; linuxdeploy fails on the bundled ELF")
|
|
||||||
}
|
|
||||||
ensureServerDependencies()
|
ensureServerDependencies()
|
||||||
ensureUiBuild()
|
ensureUiBuild()
|
||||||
syncServerUiBundle()
|
syncServerUiBundle()
|
||||||
|
|||||||
@@ -635,12 +635,12 @@ impl CliProcessManager {
|
|||||||
|
|
||||||
let use_user_shell = supports_user_shell();
|
let use_user_shell = supports_user_shell();
|
||||||
|
|
||||||
if resolution.runner != Runner::Standalone
|
if resolution.runner == Runner::Tsx
|
||||||
&& !use_user_shell
|
&& !use_user_shell
|
||||||
&& which::which(&resolution.node_binary).is_err()
|
&& which::which(&resolution.node_binary).is_err()
|
||||||
{
|
{
|
||||||
return Err(anyhow::anyhow!(
|
return Err(anyhow::anyhow!(
|
||||||
"Node binary '{}' not found. CodeNomad desktop currently requires Node.js installed on the system, or set NODE_BINARY to a valid runtime path.",
|
"Node binary '{}' not found. CodeNomad development mode requires Node.js installed on the system, or set NODE_BINARY to a valid runtime path.",
|
||||||
resolution.node_binary
|
resolution.node_binary
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -943,7 +943,7 @@ impl CliProcessManager {
|
|||||||
let mut locked = status.lock();
|
let mut locked = status.lock();
|
||||||
if locked.error.is_none() {
|
if locked.error.is_none() {
|
||||||
locked.error = Some(format!(
|
locked.error = Some(format!(
|
||||||
"Node binary '{}' not found in the desktop shell environment. CodeNomad desktop currently requires Node.js installed on the system, or set NODE_BINARY to a valid runtime path.",
|
"Node binary '{}' not found in the desktop shell environment. CodeNomad development mode requires Node.js installed on the system, or set NODE_BINARY to a valid runtime path.",
|
||||||
node_binary.trim()
|
node_binary.trim()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -1066,7 +1066,6 @@ struct CliEntry {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
enum Runner {
|
enum Runner {
|
||||||
Node,
|
|
||||||
Standalone,
|
Standalone,
|
||||||
Tsx,
|
Tsx,
|
||||||
}
|
}
|
||||||
@@ -1097,17 +1096,8 @@ impl CliEntry {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(entry) = resolve_dist_entry(app) {
|
|
||||||
return Ok(Self {
|
|
||||||
entry,
|
|
||||||
runner: Runner::Node,
|
|
||||||
runner_path: None,
|
|
||||||
node_binary,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(anyhow::anyhow!(
|
Err(anyhow::anyhow!(
|
||||||
"Unable to locate CodeNomad CLI build. Please run `npm run build --workspace @neuralnomads/codenomad`."
|
"Unable to locate the packaged CodeNomad standalone server. Please rebuild the desktop bundle."
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1275,52 +1265,6 @@ fn resolve_standalone_entry(_app: &AppHandle) -> Option<String> {
|
|||||||
first_existing(candidates)
|
first_existing(candidates)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_dist_entry(_app: &AppHandle) -> Option<String> {
|
|
||||||
let base = workspace_root();
|
|
||||||
let mut candidates: Vec<Option<PathBuf>> = vec![
|
|
||||||
base.as_ref().map(|p| p.join("packages/server/dist/bin.js")),
|
|
||||||
base.as_ref()
|
|
||||||
.map(|p| p.join("packages/server/dist/index.js")),
|
|
||||||
base.as_ref().map(|p| p.join("server/dist/bin.js")),
|
|
||||||
base.as_ref().map(|p| p.join("server/dist/index.js")),
|
|
||||||
];
|
|
||||||
|
|
||||||
if let Ok(exe) = std::env::current_exe() {
|
|
||||||
if let Some(dir) = exe.parent() {
|
|
||||||
candidates.push(Some(dir.join("resources/server/dist/bin.js")));
|
|
||||||
candidates.push(Some(dir.join("resources/server/dist/index.js")));
|
|
||||||
candidates.push(Some(dir.join("resources/server/dist/server/bin.js")));
|
|
||||||
candidates.push(Some(dir.join("resources/server/dist/server/index.js")));
|
|
||||||
|
|
||||||
let resources = dir.join("../Resources");
|
|
||||||
candidates.push(Some(resources.join("server/dist/bin.js")));
|
|
||||||
candidates.push(Some(resources.join("server/dist/index.js")));
|
|
||||||
candidates.push(Some(resources.join("server/dist/server/bin.js")));
|
|
||||||
candidates.push(Some(resources.join("server/dist/server/index.js")));
|
|
||||||
candidates.push(Some(resources.join("resources/server/dist/bin.js")));
|
|
||||||
candidates.push(Some(resources.join("resources/server/dist/index.js")));
|
|
||||||
candidates.push(Some(resources.join("resources/server/dist/server/bin.js")));
|
|
||||||
candidates.push(Some(
|
|
||||||
resources.join("resources/server/dist/server/index.js"),
|
|
||||||
));
|
|
||||||
|
|
||||||
let linux_resource_roots = [dir.join("../lib/CodeNomad"), dir.join("../lib/codenomad")];
|
|
||||||
for root in linux_resource_roots {
|
|
||||||
candidates.push(Some(root.join("server/dist/bin.js")));
|
|
||||||
candidates.push(Some(root.join("server/dist/index.js")));
|
|
||||||
candidates.push(Some(root.join("server/dist/server/bin.js")));
|
|
||||||
candidates.push(Some(root.join("server/dist/server/index.js")));
|
|
||||||
candidates.push(Some(root.join("resources/server/dist/bin.js")));
|
|
||||||
candidates.push(Some(root.join("resources/server/dist/index.js")));
|
|
||||||
candidates.push(Some(root.join("resources/server/dist/server/bin.js")));
|
|
||||||
candidates.push(Some(root.join("resources/server/dist/server/index.js")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
first_existing(candidates)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_shell_command_string(
|
fn build_shell_command_string(
|
||||||
entry: &CliEntry,
|
entry: &CliEntry,
|
||||||
cli_args: &[String],
|
cli_args: &[String],
|
||||||
|
|||||||
Reference in New Issue
Block a user