Compare commits

...

6 Commits

Author SHA1 Message Date
Gregory Schier 2ac33e351b Close responses before request body history finishes 2026-07-04 17:13:36 -07:00
Gregory Schier e52853cc2d Always render commercial use banner placeholder 2026-07-04 14:44:49 -07:00
Gregory Schier 851d0a26f0 Enable release Tauri features in config 2026-07-04 14:09:41 -07:00
Gregory Schier 78de83c754 Track @yaakapp/cli via the latest dist-tag
The CLI is now version-locked to app releases, so the devDependency
follows the latest stable instead of a range that would strand on the
old 0.x line.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 10:54:19 -07:00
Gregory Schier 9f3fd46d49 Publish CLI on app release tags (version-locked)
The CLI now publishes to npm on every v* tag at the app's version,
instead of its own yaak-cli-* tag namespace. Stables go to the latest
dist-tag, prereleases to beta/alpha. workflow_dispatch remains for
manual publishes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 10:47:42 -07:00
Gregory Schier 6c42b27edb Build CEF Linux tarballs from debs 2026-07-03 17:35:56 -07:00
7 changed files with 87 additions and 25 deletions
+20 -4
View File
@@ -39,18 +39,18 @@ jobs:
targets: "" targets: ""
- platform: "ubuntu-22.04" - platform: "ubuntu-22.04"
args: >- args: >-
--bundles appimage --bundles deb
--config ./tauri.release.conf.json --config ./tauri.release.conf.json
--config '{"productName":"yaak-cef","mainBinaryName":"yaak-cef","identifier":"app.yaak.desktop.cef","build":{"features":["license","cef"]},"bundle":{"createUpdaterArtifacts":false,"linux":{"appimage":{"files":{"/usr/lib/libfreebl3.chk":"/usr/lib/x86_64-linux-gnu/libfreebl3.chk","/usr/lib/libfreebl3.so":"/usr/lib/x86_64-linux-gnu/libfreebl3.so","/usr/lib/libfreeblpriv3.chk":"/usr/lib/x86_64-linux-gnu/libfreeblpriv3.chk","/usr/lib/libfreeblpriv3.so":"/usr/lib/x86_64-linux-gnu/libfreeblpriv3.so","/usr/lib/libsoftokn3.chk":"/usr/lib/x86_64-linux-gnu/nss/libsoftokn3.chk","/usr/lib/libsoftokn3.so":"/usr/lib/x86_64-linux-gnu/nss/libsoftokn3.so","/usr/lib/nss/libfreebl3.chk":"/usr/lib/x86_64-linux-gnu/nss/libfreebl3.chk","/usr/lib/nss/libfreebl3.so":"/usr/lib/x86_64-linux-gnu/nss/libfreebl3.so","/usr/lib/nss/libfreeblpriv3.chk":"/usr/lib/x86_64-linux-gnu/nss/libfreeblpriv3.chk","/usr/lib/nss/libfreeblpriv3.so":"/usr/lib/x86_64-linux-gnu/nss/libfreeblpriv3.so","/usr/lib/nss/libnssckbi.so":"/usr/lib/x86_64-linux-gnu/nss/libnssckbi.so","/usr/lib/nss/libnssdbm3.chk":"/usr/lib/x86_64-linux-gnu/nss/libnssdbm3.chk","/usr/lib/nss/libnssdbm3.so":"/usr/lib/x86_64-linux-gnu/nss/libnssdbm3.so","/usr/lib/nss/libsoftokn3.chk":"/usr/lib/x86_64-linux-gnu/nss/libsoftokn3.chk","/usr/lib/nss/libsoftokn3.so":"/usr/lib/x86_64-linux-gnu/nss/libsoftokn3.so"}}}}}' --config '{"productName":"yaak-cef","mainBinaryName":"yaak-cef","identifier":"app.yaak.desktop.cef","build":{"features":["license","cef"]},"bundle":{"createUpdaterArtifacts":false}}'
yaak_arch: "x64" yaak_arch: "x64"
os: "ubuntu" os: "ubuntu"
runtime: "cef" runtime: "cef"
targets: "" targets: ""
- platform: "ubuntu-22.04-arm" - platform: "ubuntu-22.04-arm"
args: >- args: >-
--bundles appimage --bundles deb
--config ./tauri.release.conf.json --config ./tauri.release.conf.json
--config '{"productName":"yaak-cef","mainBinaryName":"yaak-cef","identifier":"app.yaak.desktop.cef","build":{"features":["license","cef"]},"bundle":{"createUpdaterArtifacts":false,"linux":{"appimage":{"files":{"/usr/lib/libfreebl3.chk":"/usr/lib/aarch64-linux-gnu/libfreebl3.chk","/usr/lib/libfreebl3.so":"/usr/lib/aarch64-linux-gnu/libfreebl3.so","/usr/lib/libfreeblpriv3.chk":"/usr/lib/aarch64-linux-gnu/libfreeblpriv3.chk","/usr/lib/libfreeblpriv3.so":"/usr/lib/aarch64-linux-gnu/libfreeblpriv3.so","/usr/lib/libsoftokn3.chk":"/usr/lib/aarch64-linux-gnu/nss/libsoftokn3.chk","/usr/lib/libsoftokn3.so":"/usr/lib/aarch64-linux-gnu/nss/libsoftokn3.so","/usr/lib/nss/libfreebl3.chk":"/usr/lib/aarch64-linux-gnu/nss/libfreebl3.chk","/usr/lib/nss/libfreebl3.so":"/usr/lib/aarch64-linux-gnu/nss/libfreebl3.so","/usr/lib/nss/libfreeblpriv3.chk":"/usr/lib/aarch64-linux-gnu/nss/libfreeblpriv3.chk","/usr/lib/nss/libfreeblpriv3.so":"/usr/lib/aarch64-linux-gnu/nss/libfreeblpriv3.so","/usr/lib/nss/libnssckbi.so":"/usr/lib/aarch64-linux-gnu/nss/libnssckbi.so","/usr/lib/nss/libnssdbm3.chk":"/usr/lib/aarch64-linux-gnu/nss/libnssdbm3.chk","/usr/lib/nss/libnssdbm3.so":"/usr/lib/aarch64-linux-gnu/nss/libnssdbm3.so","/usr/lib/nss/libsoftokn3.chk":"/usr/lib/aarch64-linux-gnu/nss/libsoftokn3.chk","/usr/lib/nss/libsoftokn3.so":"/usr/lib/aarch64-linux-gnu/nss/libsoftokn3.so"}}}}}' --config '{"productName":"yaak-cef","mainBinaryName":"yaak-cef","identifier":"app.yaak.desktop.cef","build":{"features":["license","cef"]},"bundle":{"createUpdaterArtifacts":false}}'
yaak_arch: "arm64" yaak_arch: "arm64"
os: "ubuntu" os: "ubuntu"
runtime: "cef" runtime: "cef"
@@ -190,6 +190,22 @@ jobs:
projectPath: ./crates-tauri/yaak-app-client projectPath: ./crates-tauri/yaak-app-client
args: "${{ matrix.args }}" args: "${{ matrix.args }}"
- name: Build and upload CEF tarball from deb (Linux only)
if: matrix.os == 'ubuntu' && matrix.runtime == 'cef'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
deb=$(find target/release/bundle/deb -maxdepth 1 -type f -name '*.deb' | head -n 1)
version="${GITHUB_REF_NAME#v}"
extract_dir="target/release/bundle/deb/yaak-cef-linux-${{ matrix.yaak_arch }}"
tarball="target/release/bundle/deb/yaak-cef_${version}_linux_${{ matrix.yaak_arch }}.tar.gz"
rm -rf "$extract_dir"
mkdir -p "$extract_dir"
dpkg-deb -x "$deb" "$extract_dir"
tar -C "$extract_dir" -czf "$tarball" .
gh release upload "${{ github.ref_name }}" "$tarball" --clobber
# Build a per-machine NSIS installer for enterprise deployment (PDQ, SCCM, Intune) # Build a per-machine NSIS installer for enterprise deployment (PDQ, SCCM, Intune)
- name: Build and upload machine-wide installer (Windows only) - name: Build and upload machine-wide installer (Windows only)
if: matrix.os == 'windows' if: matrix.os == 'windows'
+3 -3
View File
@@ -2,7 +2,7 @@ name: Release CLI to NPM
on: on:
push: push:
tags: [yaak-cli-*] tags: [v*]
workflow_dispatch: workflow_dispatch:
inputs: inputs:
version: version:
@@ -118,7 +118,7 @@ jobs:
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
VERSION="$WORKFLOW_VERSION" VERSION="$WORKFLOW_VERSION"
else else
VERSION="${GITHUB_REF_NAME#yaak-cli-}" VERSION="${GITHUB_REF_NAME}"
fi fi
VERSION="${VERSION#v}" VERSION="${VERSION#v}"
echo "Building yaak version: $VERSION" echo "Building yaak version: $VERSION"
@@ -175,7 +175,7 @@ jobs:
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
VERSION="$WORKFLOW_VERSION" VERSION="$WORKFLOW_VERSION"
else else
VERSION="${GITHUB_REF_NAME#yaak-cli-}" VERSION="${GITHUB_REF_NAME}"
fi fi
VERSION="${VERSION#v}" VERSION="${VERSION#v}"
if [[ "$VERSION" == *-* ]]; then if [[ "$VERSION" == *-* ]]; then
@@ -10,6 +10,7 @@ import { DismissibleBanner } from "./core/DismissibleBanner";
const COMMERCIAL_USE_SNOOZE_MS = 7 * 24 * 60 * 60 * 1000; const COMMERCIAL_USE_SNOOZE_MS = 7 * 24 * 60 * 60 * 1000;
const COMMERCIAL_USE_BANNER_MESSAGE = const COMMERCIAL_USE_BANNER_MESSAGE =
"Personal use of Yaak is free. If youre using Yaak at work, please purchase a license."; "Personal use of Yaak is free. If youre using Yaak at work, please purchase a license.";
const hiddenBanner = <span aria-hidden className="block h-0 w-0 shrink-0 overflow-hidden" />;
export function CommercialUseBanner({ export function CommercialUseBanner({
source, source,
@@ -55,7 +56,7 @@ export function CommercialUseBanner({
}, [setSnoozedAt, snoozed, source]); }, [setSnoozedAt, snoozed, source]);
if (!visible || isSnoozeLoading || (snoozed && !snoozeStartedRef.current)) { if (!visible || isSnoozeLoading || (snoozed && !snoozeStartedRef.current)) {
return null; return hiddenBanner;
} }
return ( return (
@@ -1,4 +1,7 @@
{ {
"build": {
"features": ["updater", "license", "wry"]
},
"app": { "app": {
"security": { "security": {
"capabilities": [ "capabilities": [
+57 -15
View File
@@ -511,7 +511,10 @@ pub async fn send_http_request<T: TemplateCallback>(
.map_err(SendHttpRequestError::PrepareSendableRequest)?; .map_err(SendHttpRequestError::PrepareSendableRequest)?;
} }
let request_content_length = sendable_body_length(sendable_request.body.as_ref()); let request_content_length = match sendable_request.body.as_ref() {
Some(SendableBody::Bytes(_)) => sendable_body_length(sendable_request.body.as_ref()),
Some(SendableBody::Stream { .. }) | None => None,
};
let mut response = params.existing_response.unwrap_or_default(); let mut response = params.existing_response.unwrap_or_default();
response.request_id = params.request.id.clone(); response.request_id = params.request.id.clone();
response.workspace_id = params.request.workspace_id.clone(); response.workspace_id = params.request.workspace_id.clone();
@@ -811,16 +814,6 @@ pub async fn send_http_request<T: TemplateCallback>(
})?; })?;
drop(body_stream); drop(body_stream);
if let Some(task) = request_body_capture_task.take() {
match task.await {
Ok(Ok(total)) => {
response.request_content_length = Some(usize_to_i32(total));
}
Ok(Err(err)) => request_body_capture_error = Some(err),
Err(err) => request_body_capture_error = Some(err.to_string()),
}
}
if let Some(err) = request_body_capture_error.take() { if let Some(err) = request_body_capture_error.take() {
response.error = Some(append_error_message( response.error = Some(append_error_message(
response.error.take(), response.error.take(),
@@ -828,10 +821,6 @@ pub async fn send_http_request<T: TemplateCallback>(
)); ));
} }
if let Err(join_err) = event_handle.await {
warn!("Failed to join response event task: {}", join_err);
}
if let Some(err) = body_read_error { if let Some(err) = body_read_error {
if persist_response { if persist_response {
let _ = persist_response_error( let _ = persist_response_error(
@@ -849,6 +838,16 @@ pub async fn send_http_request<T: TemplateCallback>(
cookie_jar.as_mut(), cookie_jar.as_mut(),
cookie_behavior.store.as_ref(), cookie_behavior.store.as_ref(),
)?; )?;
if let Some(task) = request_body_capture_task.take() {
match task.await {
Ok(Ok(_)) => {}
Ok(Err(err)) => warn!("Failed to store request body after response error: {err}"),
Err(err) => warn!("Failed to join request body capture task: {err}"),
}
}
if let Err(join_err) = event_handle.await {
warn!("Failed to join response event task: {}", join_err);
}
return Err(err); return Err(err);
} }
@@ -875,6 +874,49 @@ pub async fn send_http_request<T: TemplateCallback>(
persist_cookie_jar(params.query_manager, cookie_jar.as_mut(), cookie_behavior.store.as_ref())?; persist_cookie_jar(params.query_manager, cookie_jar.as_mut(), cookie_behavior.store.as_ref())?;
// Request-body history can be much larger than the response. It should not keep the
// response in a loading state after the network/response-body work has completed.
if let Some(task) = request_body_capture_task.take() {
let mut update_response = false;
match task.await {
Ok(Ok(total)) => {
let total = Some(usize_to_i32(total));
if response.request_content_length != total {
response.request_content_length = total;
update_response = true;
}
}
Ok(Err(err)) => {
response.error = Some(append_error_message(
response.error.take(),
format!("Request succeeded but failed to store request body: {err}"),
));
update_response = true;
}
Err(err) => {
response.error = Some(append_error_message(
response.error.take(),
format!("Request succeeded but failed to store request body: {err}"),
));
update_response = true;
}
}
if update_response && persist_response {
response = params
.query_manager
.connect()
.upsert_http_response(&response, &params.update_source, params.blob_manager)
.map_err(SendHttpRequestError::PersistResponse)?;
}
}
// Timeline events are useful history, but they should not keep the response in a loading state
// after the network/response-body work has completed.
if let Err(join_err) = event_handle.await {
warn!("Failed to join response event task: {}", join_err);
}
Ok(SendHttpRequestResult { rendered_request, response, response_body }) Ok(SendHttpRequestResult { rendered_request, response, response_body })
} }
+1 -1
View File
@@ -83,7 +83,7 @@
"@tauri-apps/cli": "npm:@tauri-apps/cli-cef@3.0.0-alpha.6", "@tauri-apps/cli": "npm:@tauri-apps/cli-cef@3.0.0-alpha.6",
"@types/babel__core": "^7.20.5", "@types/babel__core": "^7.20.5",
"@vitejs/plugin-react": "^6.0.1", "@vitejs/plugin-react": "^6.0.1",
"@yaakapp/cli": "^0.5.1", "@yaakapp/cli": "latest",
"babel-plugin-react-compiler": "^1.0.0", "babel-plugin-react-compiler": "^1.0.0",
"dotenv-cli": "^11.0.0", "dotenv-cli": "^11.0.0",
"nodejs-file-downloader": "^4.13.0", "nodejs-file-downloader": "^4.13.0",
+1 -1
View File
@@ -116,7 +116,7 @@
"@tauri-apps/cli": "npm:@tauri-apps/cli-cef@3.0.0-alpha.6", "@tauri-apps/cli": "npm:@tauri-apps/cli-cef@3.0.0-alpha.6",
"@types/babel__core": "^7.20.5", "@types/babel__core": "^7.20.5",
"@vitejs/plugin-react": "^6.0.1", "@vitejs/plugin-react": "^6.0.1",
"@yaakapp/cli": "^0.5.1", "@yaakapp/cli": "latest",
"babel-plugin-react-compiler": "^1.0.0", "babel-plugin-react-compiler": "^1.0.0",
"dotenv-cli": "^11.0.0", "dotenv-cli": "^11.0.0",
"nodejs-file-downloader": "^4.13.0", "nodejs-file-downloader": "^4.13.0",