Compare commits

...

4 Commits

Author SHA1 Message Date
Gregory Schier
5e9aebda6f Embed CLI plugin assets and share bundled plugin registration 2026-02-22 14:44:40 -08:00
Gregory Schier
a1e84c7785 Bump @yaakapp/cli to 0.4.0-beta.2 2026-02-22 14:28:49 -08:00
Gregory Schier
fea4411afa Remove recursive API npm publish script 2026-02-22 14:21:07 -08:00
Gregory Schier
8315e4afad Add API release workflow and harden CLI npm publish 2026-02-22 14:11:26 -08:00
12 changed files with 165 additions and 58 deletions

59
.github/workflows/release-api-npm.yml vendored Normal file
View File

@@ -0,0 +1,59 @@
name: Release API to NPM
on:
push:
tags: [yaak-api-*]
workflow_dispatch:
inputs:
version:
description: API version to publish (for example 0.9.0 or v0.9.0)
required: true
type: string
permissions:
contents: read
jobs:
publish-npm:
name: Publish @yaakapp/api
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: lts/*
registry-url: https://registry.npmjs.org
- name: Install dependencies
run: npm ci
- name: Set @yaakapp/api version
shell: bash
env:
WORKFLOW_VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
VERSION="$WORKFLOW_VERSION"
else
VERSION="${GITHUB_REF_NAME#yaak-api-}"
fi
VERSION="${VERSION#v}"
echo "Preparing @yaakapp/api version: $VERSION"
cd packages/plugin-runtime-types
npm version "$VERSION" --no-git-tag-version --allow-same-version
- name: Build @yaakapp/api
working-directory: packages/plugin-runtime-types
run: npm run build
- name: Publish @yaakapp/api
working-directory: packages/plugin-runtime-types
run: npm publish --provenance --access public

View File

@@ -1,4 +1,4 @@
name: Generate Artifacts
name: Release App Artifacts
on:
push:
tags: [v*]

1
Cargo.lock generated
View File

@@ -10149,6 +10149,7 @@ dependencies = [
"env_logger",
"futures",
"hex",
"include_dir",
"keyring",
"log 0.4.29",
"oxc_resolver",

View File

@@ -16,6 +16,7 @@ dirs = "6"
env_logger = "0.11"
futures = "0.3"
hex = { workspace = true }
include_dir = "0.7"
keyring = { workspace = true, features = ["apple-native", "windows-native", "sync-secret-service"] }
log = { workspace = true }
rand = "0.8"

View File

@@ -4,6 +4,7 @@ use std::path::PathBuf;
#[derive(Parser)]
#[command(name = "yaak")]
#[command(about = "Yaak CLI - API client from the command line")]
#[command(version)]
pub struct Cli {
/// Use a custom data directory
#[arg(long, global = true)]

View File

@@ -1,4 +1,6 @@
use crate::plugin_events::CliPluginEventBridge;
use include_dir::{Dir, include_dir};
use std::fs;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use tokio::sync::Mutex;
@@ -9,6 +11,13 @@ use yaak_models::query_manager::QueryManager;
use yaak_plugins::events::PluginContext;
use yaak_plugins::manager::PluginManager;
const EMBEDDED_PLUGIN_RUNTIME: &str = include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/../../crates-tauri/yaak-app/vendored/plugin-runtime/index.cjs"
));
static EMBEDDED_VENDORED_PLUGINS: Dir<'_> =
include_dir!("$CARGO_MANIFEST_DIR/../../crates-tauri/yaak-app/vendored/plugins");
pub struct CliContext {
data_dir: PathBuf,
query_manager: QueryManager,
@@ -33,10 +42,13 @@ impl CliContext {
let installed_plugin_dir = data_dir.join("installed-plugins");
let node_bin_path = PathBuf::from("node");
prepare_embedded_vendored_plugins(&vendored_plugin_dir)
.expect("Failed to prepare bundled plugins");
let plugin_runtime_main =
std::env::var("YAAK_PLUGIN_RUNTIME").map(PathBuf::from).unwrap_or_else(|_| {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../../crates-tauri/yaak-app/vendored/plugin-runtime/index.cjs")
prepare_embedded_plugin_runtime(&data_dir)
.expect("Failed to prepare embedded plugin runtime")
});
let plugin_manager = Arc::new(
@@ -50,6 +62,13 @@ impl CliContext {
.await,
);
{
let db = query_manager.connect();
if let Err(err) = plugin_manager.ensure_bundled_plugins_registered(&db).await {
eprintln!("Warning: Failed to register bundled plugins: {err}");
}
}
let plugins = query_manager.connect().list_plugins().unwrap_or_default();
if !plugins.is_empty() {
let errors = plugin_manager
@@ -113,3 +132,17 @@ impl CliContext {
}
}
}
fn prepare_embedded_plugin_runtime(data_dir: &Path) -> std::io::Result<PathBuf> {
let runtime_dir = data_dir.join("vendored").join("plugin-runtime");
fs::create_dir_all(&runtime_dir)?;
let runtime_main = runtime_dir.join("index.cjs");
fs::write(&runtime_main, EMBEDDED_PLUGIN_RUNTIME)?;
Ok(runtime_main)
}
fn prepare_embedded_vendored_plugins(vendored_plugin_dir: &Path) -> std::io::Result<()> {
fs::create_dir_all(vendored_plugin_dir)?;
EMBEDDED_VENDORED_PLUGINS.extract(vendored_plugin_dir)?;
Ok(())
}

View File

@@ -23,7 +23,6 @@ use tokio::sync::Mutex;
use ts_rs::TS;
use yaak_api::yaak_api_client;
use yaak_models::models::Plugin;
use yaak_models::util::UpdateSource;
use yaak_plugins::api::{
PluginNameVersion, PluginSearchResponse, PluginUpdatesResponse, check_plugin_updates,
search_plugins,
@@ -281,28 +280,11 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
)
.await;
// Initialize all plugins after manager is created
let bundled_dirs = manager
.list_bundled_plugin_dirs()
.await
.expect("Failed to list bundled plugins");
// Ensure all bundled plugins make it into the database
let db = app_handle_clone.db();
for dir in &bundled_dirs {
if db.get_plugin_by_directory(dir).is_none() {
db.upsert_plugin(
&Plugin {
directory: dir.clone(),
enabled: true,
url: None,
..Default::default()
},
&UpdateSource::Background,
)
.expect("Failed to upsert bundled plugin");
}
}
manager
.ensure_bundled_plugins_registered(&db)
.await
.expect("Failed to register bundled plugins");
// Get all plugins from database and initialize
let plugins = db.list_plugins().expect("Failed to list plugins from database");

View File

@@ -33,8 +33,9 @@ use tokio::net::TcpListener;
use tokio::sync::mpsc::error::TrySendError;
use tokio::sync::{Mutex, mpsc, oneshot};
use tokio::time::{Instant, timeout};
use yaak_models::db_context::DbContext;
use yaak_models::models::Plugin;
use yaak_models::util::generate_id;
use yaak_models::util::{UpdateSource, generate_id};
use yaak_templates::error::Error::RenderError;
use yaak_templates::error::Result as TemplateResult;
@@ -180,6 +181,33 @@ impl PluginManager {
read_plugins_dir(&plugins_dir).await
}
/// Ensure all bundled plugin directories are present in the plugins table.
/// Returns a list of newly registered plugin directories.
pub async fn ensure_bundled_plugins_registered(
&self,
db: &DbContext<'_>,
) -> Result<Vec<String>> {
let bundled_dirs = self.list_bundled_plugin_dirs().await?;
let mut registered = Vec::new();
for dir in bundled_dirs {
if db.get_plugin_by_directory(&dir).is_none() {
db.upsert_plugin(
&Plugin {
directory: dir.clone(),
enabled: true,
url: None,
..Default::default()
},
&UpdateSource::Background,
)?;
registered.push(dir);
}
}
Ok(registered)
}
pub async fn uninstall(&self, plugin_context: &PluginContext, dir: &str) -> Result<()> {
let plugin = self.get_plugin_by_dir(dir).await.ok_or(PluginNotFoundErr(dir.to_string()))?;
self.remove_plugin(plugin_context, &plugin).await

View File

@@ -1,4 +1,4 @@
const { copyFileSync, existsSync, readFileSync, writeFileSync } = require("node:fs");
const { chmodSync, copyFileSync, existsSync, readFileSync, writeFileSync } = require("node:fs");
const { join } = require("node:path");
const version = process.env.YAAK_CLI_VERSION?.replace(/^v/, "");
@@ -50,6 +50,9 @@ for (const { src, dest } of binaries) {
process.exit(1);
}
copyFileSync(src, dest);
if (!dest.endsWith(".exe")) {
chmodSync(dest, 0o755);
}
}
for (const pkg of packages) {

58
package-lock.json generated
View File

@@ -37,7 +37,6 @@
"plugins/template-function-cookie",
"plugins/template-function-ctx",
"plugins/template-function-encode",
"plugins/template-function-faker",
"plugins/template-function-fs",
"plugins/template-function-hash",
"plugins/template-function-json",
@@ -74,7 +73,7 @@
"devDependencies": {
"@biomejs/biome": "^2.3.13",
"@tauri-apps/cli": "^2.9.6",
"@yaakapp/cli": "^0.3.4",
"@yaakapp/cli": "^0.4.0-beta.2",
"dotenv-cli": "^11.0.0",
"husky": "^9.1.7",
"nodejs-file-downloader": "^4.13.0",
@@ -4327,27 +4326,28 @@
"link": true
},
"node_modules/@yaakapp/cli": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.3.4.tgz",
"integrity": "sha512-bSSL3noEfyoPC0M+bj34jbBZbB+gwYLCHL9cf6BYHgkRQKlHFpvN6z8M2jQZljb+CTQdHK0NzosmwHLpjMmAVA==",
"version": "0.4.0-beta.2",
"resolved": "https://registry.npmjs.org/@yaakapp/cli/-/cli-0.4.0-beta.2.tgz",
"integrity": "sha512-UXPxTS9oWVCIr4rShC7HjcAX+gSmw/BQ5F1Xp3Rub3vY/G7+513JJsc1HhLGVZqFfOVRSMEKRxtF9/9okSyiHg==",
"dev": true,
"hasInstallScript": true,
"bin": {
"yaak": "bin/cli.js",
"yaakcli": "bin/cli.js"
},
"optionalDependencies": {
"@yaakapp/cli-darwin-arm64": "0.3.4",
"@yaakapp/cli-darwin-x64": "0.3.4",
"@yaakapp/cli-linux-arm64": "0.3.4",
"@yaakapp/cli-linux-x64": "0.3.4",
"@yaakapp/cli-win32-arm64": "0.3.4",
"@yaakapp/cli-win32-x64": "0.3.4"
"@yaakapp/cli-darwin-arm64": "0.4.0-beta.2",
"@yaakapp/cli-darwin-x64": "0.4.0-beta.2",
"@yaakapp/cli-linux-arm64": "0.4.0-beta.2",
"@yaakapp/cli-linux-x64": "0.4.0-beta.2",
"@yaakapp/cli-win32-arm64": "0.4.0-beta.2",
"@yaakapp/cli-win32-x64": "0.4.0-beta.2"
}
},
"node_modules/@yaakapp/cli-darwin-arm64": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.3.4.tgz",
"integrity": "sha512-iTohEO7XSVZwSvTgEQE9my3wGyWtTl1q8yfol7hHwVFTX7G8Geh8X2j2vVokHhj7J9OZL9jtYQWIsM1ekOHSEQ==",
"version": "0.4.0-beta.2",
"resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-arm64/-/cli-darwin-arm64-0.4.0-beta.2.tgz",
"integrity": "sha512-mqkyH5tIPRLs9JumP9ZmzjB5gIwmOL1yCDoJ1qVU8DIJ7mwlcQaPGYTK98pVdBcKOjofVakBTcpol9P8rBv4qw==",
"cpu": [
"arm64"
],
@@ -4358,9 +4358,9 @@
]
},
"node_modules/@yaakapp/cli-darwin-x64": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.3.4.tgz",
"integrity": "sha512-gz7IcjFGKA0cCAum1Aq8kmVg7erYYSrZ9pliDw0NZyObjrBysJcsDXLodEU437u0pihtdCfoLsq3rsYYs8uwCA==",
"version": "0.4.0-beta.2",
"resolved": "https://registry.npmjs.org/@yaakapp/cli-darwin-x64/-/cli-darwin-x64-0.4.0-beta.2.tgz",
"integrity": "sha512-QI/H2yUF8CkJq+cnRthoUWWTEJPH4QPA78FYcGjFRhvBaj1m2G/GlCA5NkTXm/fvIjNkQEODSihXrhU+zoSSCw==",
"cpu": [
"x64"
],
@@ -4371,9 +4371,9 @@
]
},
"node_modules/@yaakapp/cli-linux-arm64": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-arm64/-/cli-linux-arm64-0.3.4.tgz",
"integrity": "sha512-Yiwz8PBkXngmr0lTMW1pgy+F/kUISkzvqofdoBseXTrS/GDxoW3ILnG3If30LuIyWWPgqpuU+qKMtbVDzuncPQ==",
"version": "0.4.0-beta.2",
"resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-arm64/-/cli-linux-arm64-0.4.0-beta.2.tgz",
"integrity": "sha512-nvAp97LkgRpqVHyMwDdpkzlKOWG2kJXezCLRZaRWaEpbnNuviSF+0yzCuFGZRHEEspj7B0TiM+sKGkpvjNlweA==",
"cpu": [
"arm64"
],
@@ -4384,9 +4384,9 @@
]
},
"node_modules/@yaakapp/cli-linux-x64": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.3.4.tgz",
"integrity": "sha512-j7/r18UYNlFChDVU5N5ye3mmL+OR9Uu3LY72JxW+s/SyV69Bo8Griii75Wt19z/jj2ES8pxD+4IJq56VF3wJ7w==",
"version": "0.4.0-beta.2",
"resolved": "https://registry.npmjs.org/@yaakapp/cli-linux-x64/-/cli-linux-x64-0.4.0-beta.2.tgz",
"integrity": "sha512-9/qAMNrtE9glxih3XWGfFssIJpQ4mHNUTuWYKroc0aZZUrunnCw3tX1tQtFDxy0QRIZcGlBeBRtgxuuBd2fYbg==",
"cpu": [
"x64"
],
@@ -4397,9 +4397,9 @@
]
},
"node_modules/@yaakapp/cli-win32-arm64": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-arm64/-/cli-win32-arm64-0.3.4.tgz",
"integrity": "sha512-OUSKOKrSnzrTAGW0c+2ZCwA4yhgw/bA+gyeTvpf7cELVuB0qooGkEcJ3lM7fPMKmUbFU0r+K/Ggq1QMUr7cJLQ==",
"version": "0.4.0-beta.2",
"resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-arm64/-/cli-win32-arm64-0.4.0-beta.2.tgz",
"integrity": "sha512-eM1zL+hl0y3NBLxWO90y9VyaFsAf0HAsECBWvhKhvEdd6KG4K1XzpXrC30cHQBGePIrCa/az8eSuvTde0Z2C/g==",
"cpu": [
"arm64"
],
@@ -4410,9 +4410,9 @@
]
},
"node_modules/@yaakapp/cli-win32-x64": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.3.4.tgz",
"integrity": "sha512-sVYnW1rROLbzFUCyeZ++ibN+8gJS7FdPnBRHIE0KORfeI4e7Gw/aMUji2qpSZ1gt3DrAU95DDNjBkDvGBAgqag==",
"version": "0.4.0-beta.2",
"resolved": "https://registry.npmjs.org/@yaakapp/cli-win32-x64/-/cli-win32-x64-0.4.0-beta.2.tgz",
"integrity": "sha512-ySdiK0h216EqURkM5KZoqbPTgbIX4eNK/IgrKwSazxRb369HOZYQ8X68as+VRxEL4NCMmWlQNdbBDuf+apg/mg==",
"cpu": [
"x64"
],

View File

@@ -98,7 +98,7 @@
"devDependencies": {
"@biomejs/biome": "^2.3.13",
"@tauri-apps/cli": "^2.9.6",
"@yaakapp/cli": "^0.3.4",
"@yaakapp/cli": "^0.4.0-beta.2",
"dotenv-cli": "^11.0.0",
"husky": "^9.1.7",
"nodejs-file-downloader": "^4.13.0",

View File

@@ -27,7 +27,6 @@
"build:copy-types": "run-p build:copy-types:*",
"build:copy-types:root": "cpy --flat ../../crates/yaak-plugins/bindings/*.ts ./src/bindings",
"build:copy-types:next": "cpy --flat ../../crates/yaak-plugins/bindings/serde_json/*.ts ./src/bindings/serde_json",
"publish": "npm publish",
"prepublishOnly": "npm run build"
},
"dependencies": {