🎨 Simplify test usage and change names

This commit is contained in:
Tw93
2025-08-22 12:47:37 +08:00
parent 8a15e989b0
commit 1761802105
13 changed files with 472 additions and 900 deletions

188
script/app_config.mjs vendored
View File

@@ -1,188 +0,0 @@
import pakeJson from "../src-tauri/pake.json" assert { type: "json" };
import tauriJson from "../src-tauri/tauri.conf.json" assert { type: "json" };
import windowsJson from "../src-tauri/tauri.windows.conf.json" assert { type: "json" };
import macosJson from "../src-tauri/tauri.macos.conf.json" assert { type: "json" };
import linuxJson from "../src-tauri/tauri.linux.conf.json" assert { type: "json" };
import { writeFileSync, existsSync, copyFileSync } from "fs";
import os from "os";
const desktopEntry = `[Desktop Entry]
Encoding=UTF-8
Categories=Office
Exec=com-pake-${process.env.NAME}
Icon=com-pake-${process.env.NAME}
Name=com-pake-${process.env.NAME}
Name[zh_CN]=${process.env.NAME_ZH}
StartupNotify=true
Terminal=false
Type=Application
`;
const variables = {
url: process.env.URL,
name: process.env.NAME,
title: process.env.TITLE,
nameZh: process.env.NAME_ZH,
pakeConfigPath: "src-tauri/pake.json",
tauriConfigPath: "src-tauri/tauri.conf.json",
identifier: `com.pake.${process.env.NAME}`,
linux: {
configFilePath: "src-tauri/tauri.linux.conf.json",
iconPath: `src-tauri/png/${process.env.NAME}_512.png`,
productName: `com-pake-${process.env.NAME}`,
defaultIconPath: "src-tauri/png/icon_512.png",
icon: [`png/${process.env.NAME}_512.png`],
desktopEntry,
desktopEntryPath: `src-tauri/assets/com-pake-${process.env.NAME}.desktop`,
desktopEntryConfig: {
configKey: `/usr/share/applications/com-pake-${process.env.NAME}.desktop`,
configValue: `assets/com-pake-${process.env.NAME}.desktop`,
},
},
macos: {
configFilePath: "src-tauri/tauri.macos.conf.json",
iconPath: `src-tauri/icons/${process.env.NAME}.icns`,
defaultPath: "src-tauri/icons/icon.icns",
icon: [`icons/${process.env.NAME}.icns`],
},
windows: {
configFilePath: "src-tauri/tauri.windows.conf.json",
iconPath: `src-tauri/png/${process.env.NAME}_32.ico`,
defaultPath: "src-tauri/png/icon_32.ico",
hdIconPath: `src-tauri/png/${process.env.NAME}_256.ico`,
hdDefaultPath: "src-tauri/png/icon_256.ico",
icon: [`png/${process.env.NAME}_256.ico`, `png/${process.env.NAME}_32.ico`],
resources: [`png/${process.env.NAME}_32.ico`],
},
};
validate();
updatePakeJson();
updateTauriJson();
let platformVariables;
let platformConfig;
switch (os.platform()) {
case "linux":
platformVariables = variables.linux;
platformConfig = linuxJson;
updateDesktopEntry();
break;
case "darwin":
platformVariables = variables.macos;
platformConfig = macosJson;
break;
case "win32":
platformConfig = windowsJson;
platformVariables = variables.windows;
updateResources();
updateIconFile(
platformVariables.hdIconPath,
platformVariables.hdDefaultPath,
);
break;
}
updateIconFile(platformVariables.iconPath, platformVariables.defaultIconPath);
updatePlatformConfig(platformConfig, platformVariables);
save();
function validate() {
if (!("URL" in process.env)) {
console.log("URL is not set");
process.exit(1);
}
console.log(`URL: ${process.env.URL}`);
if (!("NAME" in process.env)) {
console.log("NAME is not set");
process.exit(1);
}
console.log(`NAME: ${process.env.NAME}`);
if (!("TITLE" in process.env)) {
console.log("TITLE is not set");
process.exit(1);
}
console.log(`TITLE: ${process.env.TITLE}`);
if (!("NAME_ZH" in process.env)) {
console.log("NAME_ZH is not set");
process.exit(1);
}
console.log(`NAME_ZH: ${process.env.NAME_ZH}`);
}
function updatePakeJson() {
pakeJson.windows[0].url = variables.url;
}
function updateTauriJson() {
tauriJson.productName = variables.title;
writeFileSync(
"src-tauri/tauri.conf.json",
JSON.stringify(tauriJson, null, 2),
);
}
function updateIconFile(iconPath, defaultIconPath) {
if (!existsSync(iconPath)) {
console.warn(
`Icon for ${process.env.NAME} not found, will use default icon`,
);
copyFileSync(defaultIconPath, iconPath);
}
}
function updatePlatformConfig(platformConfig, platformVariables) {
platformConfig.bundle["icon"] = platformVariables.icon;
platformConfig.identifier = variables.identifier;
}
function save() {
writeFileSync(variables.pakeConfigPath, JSON.stringify(pakeJson, null, 2));
writeFileSync(variables.tauriConfigPath, JSON.stringify(tauriJson, null, 2));
writeFileSync(
variables.linux.configFilePath,
JSON.stringify(linuxJson, null, 2),
);
writeFileSync(
platformVariables.configFilePath,
JSON.stringify(platformConfig, null, 2),
);
writeFileSync(
variables.macos.configFilePath,
JSON.stringify(macosJson, null, 2),
);
writeFileSync(
variables.windows.configFilePath,
JSON.stringify(windowsJson, null, 2),
);
}
function updateDesktopEntry() {
linuxJson.bundle.linux.deb.files = {};
linuxJson.bundle.linux.deb.files[
variables.linux.desktopEntryConfig.configKey
] = variables.linux.desktopEntryConfig.configValue;
writeFileSync(variables.linux.desktopEntryPath, variables.linux.desktopEntry);
}
function updateResources() {
windowsJson.bundle.resources = variables.windows.resources;
}

View File

@@ -1,158 +0,0 @@
import fs from "fs";
import path from "path";
import { execa } from "execa";
// Configuration logging
const logConfiguration = () => {
console.log("Welcome to use pake-cli to build app");
console.log("Node.js info in your localhost:", process.version);
console.log("\n=======================\n");
console.log("Pake parameters:");
console.log("url:", process.env.URL);
console.log("name:", process.env.NAME);
console.log("icon:", process.env.ICON);
console.log("height:", process.env.HEIGHT);
console.log("width:", process.env.WIDTH);
console.log("fullscreen:", process.env.FULLSCREEN);
console.log("hide-title-bar:", process.env.HIDE_TITLE_BAR);
console.log("is multi arch? only for Mac:", process.env.MULTI_ARCH);
console.log("targets type? only for Linux:", process.env.TARGETS);
console.log("===========================\n");
};
// Main execution
const main = async () => {
try {
logConfiguration();
const cliPath = path.join(process.cwd(), "node_modules/pake-cli");
// Check if pake-cli directory exists
if (!fs.existsSync(cliPath)) {
console.error("Error: pake-cli not found at", cliPath);
console.error(
"Please make sure pake-cli is installed: npm install pake-cli",
);
process.exit(1);
}
process.chdir(cliPath);
// Clean up any previous configuration to ensure fresh build
const pakeDirPath = path.join("src-tauri", ".pake");
// Remove .pake directory to force fresh config generation
if (fs.existsSync(pakeDirPath)) {
fs.rmSync(pakeDirPath, { recursive: true, force: true });
console.log("Cleaned previous .pake directory for fresh build");
}
// Also clean any potential target directories that might contain cached configs
const targetDirs = [
"src-tauri/target",
"src-tauri/target/debug",
"src-tauri/target/release",
"src-tauri/target/universal-apple-darwin",
];
targetDirs.forEach((dir) => {
if (fs.existsSync(dir)) {
// Only remove .pake subdirectories, not the entire target directory
const targetPakeDir = path.join(dir, ".pake");
if (fs.existsSync(targetPakeDir)) {
fs.rmSync(targetPakeDir, { recursive: true, force: true });
console.log(`Cleaned .pake directory in ${dir}`);
}
}
});
// Build CLI parameters
let params = [
"dist/cli.js",
process.env.URL,
"--name",
process.env.NAME,
"--height",
process.env.HEIGHT,
"--width",
process.env.WIDTH,
];
if (
process.env.HIDE_TITLE_BAR === "true" &&
process.platform === "darwin"
) {
params.push("--hide-title-bar");
}
if (process.env.FULLSCREEN === "true") {
params.push("--fullscreen");
}
if (process.env.MULTI_ARCH === "true" && process.platform === "darwin") {
params.push("--multi-arch");
}
if (process.env.TARGETS && process.platform === "linux") {
params.push("--targets", process.env.TARGETS);
}
if (process.platform === "win32" || process.platform === "linux") {
params.push("--show-system-tray");
}
// Add icon parameter if provided - CLI will handle download and conversion
if (process.env.ICON && process.env.ICON !== "") {
params.push("--icon", process.env.ICON);
} else {
console.log(
"No icon provided, pake-cli will attempt to fetch favicon or use default",
);
}
console.log("Pake parameters:", params.join(" "));
console.log("Expected app name:", process.env.NAME);
console.log("Compiling....");
// Execute the CLI command
await execa("node", params, { stdio: "inherit" });
// Create output directory and move built files
if (!fs.existsSync("output")) {
fs.mkdirSync("output");
}
// pake-cli outputs files to current directory with various naming patterns
const files = fs.readdirSync(".");
const appName = process.env.NAME;
const escapedAppName = appName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // Escape regex special chars
// Create comprehensive pattern for app files
const appFilePattern = new RegExp(
`^(${escapedAppName}|${escapedAppName.toLowerCase()})(_.*|\\..*)$`,
"i",
);
let foundFiles = false;
for (const file of files) {
if (appFilePattern.test(file)) {
const destPath = path.join("output", file);
fs.renameSync(file, destPath);
console.log(`Moved: ${file} -> output/${file}`);
foundFiles = true;
}
}
if (!foundFiles) {
console.log("Warning: No output files found matching pattern");
}
console.log("Build Success");
process.chdir("../..");
} catch (error) {
console.error("Build failed:", error);
process.exit(1);
}
};
main();

196
script/configure-tauri.mjs vendored Executable file
View File

@@ -0,0 +1,196 @@
import pakeJson from "../src-tauri/pake.json" with { type: "json" };
import tauriJson from "../src-tauri/tauri.conf.json" with { type: "json" };
import windowsJson from "../src-tauri/tauri.windows.conf.json" with { type: "json" };
import macosJson from "../src-tauri/tauri.macos.conf.json" with { type: "json" };
import linuxJson from "../src-tauri/tauri.linux.conf.json" with { type: "json" };
import { writeFileSync, existsSync, copyFileSync } from "fs";
import os from "os";
/**
* Configuration script for Tauri app generation
* Sets up platform-specific configurations, icons, and desktop entries
*/
// Environment validation
const requiredEnvVars = ["URL", "NAME", "TITLE", "NAME_ZH"];
function validateEnvironment() {
const missing = requiredEnvVars.filter((key) => !(key in process.env));
if (missing.length > 0) {
console.error(
`Missing required environment variables: ${missing.join(", ")}`,
);
process.exit(1);
}
console.log("Environment variables:");
requiredEnvVars.forEach((key) => {
console.log(` ${key}: ${process.env[key]}`);
});
}
// Configuration constants
const CONFIG = {
get identifier() {
return `com.pake.${process.env.NAME}`;
},
get productName() {
return `com-pake-${process.env.NAME}`;
},
paths: {
pakeConfig: "src-tauri/pake.json",
tauriConfig: "src-tauri/tauri.conf.json",
},
platforms: {
linux: {
configFile: "src-tauri/tauri.linux.conf.json",
iconPath: `src-tauri/png/${process.env.NAME}_512.png`,
defaultIcon: "src-tauri/png/icon_512.png",
icons: [`png/${process.env.NAME}_512.png`],
get desktopEntry() {
return `[Desktop Entry]
Encoding=UTF-8
Categories=Office
Exec=${CONFIG.productName}
Icon=${CONFIG.productName}
Name=${CONFIG.productName}
Name[zh_CN]=${process.env.NAME_ZH}
StartupNotify=true
Terminal=false
Type=Application
`;
},
get desktopEntryPath() {
return `src-tauri/assets/${CONFIG.productName}.desktop`;
},
get desktopConfig() {
return {
key: `/usr/share/applications/${CONFIG.productName}.desktop`,
value: `assets/${CONFIG.productName}.desktop`,
};
},
},
darwin: {
configFile: "src-tauri/tauri.macos.conf.json",
iconPath: `src-tauri/icons/${process.env.NAME}.icns`,
defaultIcon: "src-tauri/icons/icon.icns",
icons: [`icons/${process.env.NAME}.icns`],
},
windows: {
configFile: "src-tauri/tauri.windows.conf.json",
iconPath: `src-tauri/png/${process.env.NAME}_32.ico`,
hdIconPath: `src-tauri/png/${process.env.NAME}_256.ico`,
defaultIcon: "src-tauri/png/icon_32.ico",
hdDefaultIcon: "src-tauri/png/icon_256.ico",
icons: [
`png/${process.env.NAME}_256.ico`,
`png/${process.env.NAME}_32.ico`,
],
resources: [`png/${process.env.NAME}_32.ico`],
},
},
};
// Core configuration functions
function updateBaseConfigs() {
// Update pake.json
pakeJson.windows[0].url = process.env.URL;
// Update tauri.conf.json
tauriJson.productName = process.env.TITLE;
tauriJson.identifier = CONFIG.identifier;
}
function ensureIconExists(iconPath, defaultPath, description = "icon") {
if (!existsSync(iconPath)) {
console.warn(
`${description} for ${process.env.NAME} not found, using default`,
);
copyFileSync(defaultPath, iconPath);
}
}
function updatePlatformConfig(platformConfig, platformVars) {
platformConfig.bundle.icon = platformVars.icons;
platformConfig.identifier = CONFIG.identifier;
}
// Platform-specific handlers
const platformHandlers = {
linux: (config) => {
ensureIconExists(config.iconPath, config.defaultIcon, "Linux icon");
// Update desktop entry
linuxJson.bundle.linux.deb.files = {
[config.desktopConfig.key]: config.desktopConfig.value,
};
writeFileSync(config.desktopEntryPath, config.desktopEntry);
updatePlatformConfig(linuxJson, config);
},
darwin: (config) => {
ensureIconExists(config.iconPath, config.defaultIcon, "macOS icon");
updatePlatformConfig(macosJson, config);
},
win32: (config) => {
ensureIconExists(config.iconPath, config.defaultIcon, "Windows icon");
ensureIconExists(
config.hdIconPath,
config.hdDefaultIcon,
"Windows HD icon",
);
windowsJson.bundle.resources = config.resources;
updatePlatformConfig(windowsJson, config);
},
};
function saveConfigurations() {
const configs = [
{ path: CONFIG.paths.pakeConfig, data: pakeJson },
{ path: CONFIG.paths.tauriConfig, data: tauriJson },
{ path: CONFIG.platforms.linux.configFile, data: linuxJson },
{ path: CONFIG.platforms.darwin.configFile, data: macosJson },
{ path: CONFIG.platforms.windows.configFile, data: windowsJson },
];
configs.forEach(({ path, data }) => {
writeFileSync(path, JSON.stringify(data, null, 2));
});
}
// Main execution
function main() {
try {
validateEnvironment();
updateBaseConfigs();
const platform = os.platform();
const platformConfig = CONFIG.platforms[platform];
if (!platformConfig) {
throw new Error(`Unsupported platform: ${platform}`);
}
const handler = platformHandlers[platform];
if (handler) {
handler(platformConfig);
}
saveConfigurations();
console.log(`✅ Tauri configuration complete for ${platform}`);
} catch (error) {
console.error("❌ Configuration failed:", error.message);
process.exit(1);
}
}
main();

224
script/github-action-build.js vendored Executable file
View File

@@ -0,0 +1,224 @@
import fs from "fs";
import path from "path";
import { execa } from "execa";
/**
* GitHub Actions build script for Pake CLI
* Handles environment setup, parameter building, and output management
*/
// Environment variables expected from GitHub Actions
const ENV_VARS = {
required: ["URL", "NAME", "HEIGHT", "WIDTH"],
optional: ["ICON", "FULLSCREEN", "HIDE_TITLE_BAR", "MULTI_ARCH", "TARGETS"],
};
// Platform-specific configurations
const PLATFORM_CONFIG = {
darwin: {
supportsHideTitleBar: true,
supportsMultiArch: true,
needsSystemTray: false,
},
linux: {
supportsTargets: true,
needsSystemTray: true,
},
win32: {
needsSystemTray: true,
},
};
class PakeBuildManager {
constructor() {
this.platform = process.platform;
this.config = PLATFORM_CONFIG[this.platform] || {};
}
logConfiguration() {
console.log("🚀 Pake CLI Build Started");
console.log(`📋 Node.js version: ${process.version}`);
console.log(`🖥️ Platform: ${this.platform}`);
console.log("\n" + "=".repeat(50));
console.log("📝 Build Parameters:");
ENV_VARS.required.forEach((key) => {
console.log(` ${key}: ${process.env[key]}`);
});
ENV_VARS.optional.forEach((key) => {
if (process.env[key]) {
console.log(` ${key}: ${process.env[key]}`);
}
});
console.log("=".repeat(50) + "\n");
}
validateEnvironment() {
const missing = ENV_VARS.required.filter((key) => !process.env[key]);
if (missing.length > 0) {
throw new Error(
`Missing required environment variables: ${missing.join(", ")}`,
);
}
}
setupWorkspace() {
const cliPath = path.join(process.cwd(), "node_modules/pake-cli");
if (!fs.existsSync(cliPath)) {
throw new Error(
`pake-cli not found at ${cliPath}. Run: npm install pake-cli`,
);
}
process.chdir(cliPath);
this.cleanPreviousBuilds();
return cliPath;
}
cleanPreviousBuilds() {
const cleanupPaths = [
"src-tauri/.pake",
"src-tauri/target/.pake",
"src-tauri/target/debug/.pake",
"src-tauri/target/release/.pake",
"src-tauri/target/universal-apple-darwin/.pake",
];
cleanupPaths.forEach((dirPath) => {
if (fs.existsSync(dirPath)) {
fs.rmSync(dirPath, { recursive: true, force: true });
console.log(`🧹 Cleaned: ${dirPath}`);
}
});
}
buildCliParameters() {
const params = [
"dist/cli.js",
process.env.URL,
"--name",
process.env.NAME,
"--height",
process.env.HEIGHT,
"--width",
process.env.WIDTH,
];
// Platform-specific parameters
if (
this.config.supportsHideTitleBar &&
process.env.HIDE_TITLE_BAR === "true"
) {
params.push("--hide-title-bar");
}
if (process.env.FULLSCREEN === "true") {
params.push("--fullscreen");
}
if (this.config.supportsMultiArch && process.env.MULTI_ARCH === "true") {
params.push("--multi-arch");
}
if (this.config.supportsTargets && process.env.TARGETS) {
params.push("--targets", process.env.TARGETS);
}
if (this.config.needsSystemTray) {
params.push("--show-system-tray");
}
// Icon handling
if (process.env.ICON?.trim()) {
params.push("--icon", process.env.ICON);
} else {
console.log(
" No icon provided, will attempt to fetch favicon or use default",
);
}
return params;
}
async executeBuild(params) {
console.log(`🔧 Command: node ${params.join(" ")}`);
console.log(`📱 Building app: ${process.env.NAME}`);
console.log("⏳ Compiling...\n");
await execa("node", params, { stdio: "inherit" });
}
organizeOutput() {
const outputDir = "output";
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir);
}
const appName = process.env.NAME;
const filePattern = new RegExp(
`^(${this.escapeRegex(appName)}|${this.escapeRegex(appName.toLowerCase())})(_.*|\\..*)$`,
"i",
);
const files = fs.readdirSync(".");
let movedFiles = 0;
files.forEach((file) => {
if (filePattern.test(file)) {
const destPath = path.join(outputDir, file);
fs.renameSync(file, destPath);
console.log(`📦 Packaged: ${file}`);
movedFiles++;
}
});
if (movedFiles === 0) {
console.warn(
"⚠️ Warning: No output files found matching expected pattern",
);
}
return movedFiles;
}
escapeRegex(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
async run() {
try {
this.logConfiguration();
this.validateEnvironment();
this.setupWorkspace();
const params = this.buildCliParameters();
await this.executeBuild(params);
const fileCount = this.organizeOutput();
console.log(`\n✅ Build completed successfully!`);
console.log(`📦 Generated ${fileCount} output file(s)`);
// Return to original directory
process.chdir("../..");
} catch (error) {
console.error("\n❌ Build failed:", error.message);
if (error.stderr) {
console.error("Error details:", error.stderr);
}
process.exit(1);
}
}
}
// Execute build
const buildManager = new PakeBuildManager();
buildManager.run();