From 0044683d44e29953652b7fd56bdbf632a0d29f5f Mon Sep 17 00:00:00 2001 From: Kbscript Date: Tue, 3 Jun 2025 18:00:08 +0800 Subject: [PATCH] chore: build and publish editor dependencies --- .github/workflows/release-editor-kit.yml | 61 +++++++ scripts/build-editor-preload.js | 220 +++++++++++++++++++++++ scripts/editor-preload-config.js | 75 ++++++++ 3 files changed, 356 insertions(+) create mode 100644 .github/workflows/release-editor-kit.yml create mode 100644 scripts/build-editor-preload.js create mode 100644 scripts/editor-preload-config.js diff --git a/.github/workflows/release-editor-kit.yml b/.github/workflows/release-editor-kit.yml new file mode 100644 index 000000000..0eb4eb689 --- /dev/null +++ b/.github/workflows/release-editor-kit.yml @@ -0,0 +1,61 @@ +name: Release Editor Kit + +on: + workflow_dispatch: + inputs: + version: + description: 'Version to use for editor-preload package' + required: true + use_npm: + description: 'Use npm packages instead of building from source' + type: boolean + default: false + +jobs: + release: + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + steps: + - name: Checkout repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + run_install: true + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '>=22.6.0' + registry-url: https://registry.npmjs.org/ + cache: pnpm + + - name: Make build script executable + run: chmod +x ./scripts/build-editor-preload.js + + - name: Build editor-preload package + run: | + USE_NPM_ARG="" + if [ "${{ github.event.inputs.use_npm }}" == "true" ]; then + USE_NPM_ARG="--use-npm" + fi + + ./scripts/build-editor-preload.js --version=${{ github.event.inputs.version }} $USE_NPM_ARG + + - name: Release editor-preload package and Sync to CDN + uses: galacean/publish@main + with: + publish: false + packages: | + editor-preload + env: + NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} + NPM_CONFIG_PROVENANCE: true + OASISBE_UPLOAD_URL: https://oasisbe.alipay.com/api/file/no-auth/crypto/upload + OASISBE_REQUEST_HEADER: ${{secrets.OASISBE_REQUEST_HEADER}} + OASISBE_PUBLIC_KEY: ${{secrets.OASISBE_PUBLIC_KEY}} diff --git a/scripts/build-editor-preload.js b/scripts/build-editor-preload.js new file mode 100644 index 000000000..dc7a3f75a --- /dev/null +++ b/scripts/build-editor-preload.js @@ -0,0 +1,220 @@ +#!/usr/bin/env node + +const fs = require("fs"); +const path = require("path"); +const { execSync } = require("child_process"); +const config = require("./editor-preload-config"); + +// Parse command line arguments +const args = process.argv.slice(2); +const versionArg = args.find((arg) => arg.startsWith("--version=")); +const version = versionArg ? versionArg.split("=")[1] : "1.0.0"; +const useNpmArg = args.includes("--use-npm"); +const skipBuildArg = args.includes("--skip-build"); + +// Paths +const rootDir = process.cwd(); +const outputDir = path.join(rootDir, "editor-preload"); +const outputDistDir = path.join(outputDir, "dist"); +const outputFile = path.join(outputDistDir, "browser.js"); + +console.log(`Building editor-preload v${version}`); + +// Create output directories +if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); +} +if (!fs.existsSync(outputDistDir)) { + fs.mkdirSync(outputDistDir, { recursive: true }); +} + +// Create package.json +const packageJson = { + name: "@galacean/editor-preload", + version: version, + description: "Preloaded packages for Galacean Editor", + main: "dist/browser.js", + files: ["dist"] +}; + +fs.writeFileSync(path.join(outputDir, "package.json"), JSON.stringify(packageJson, null, 2)); + +// Initialize output file with header +fs.writeFileSync(outputFile, `// @galacean/editor-preload v${version}\n`); + +// Build first-party packages if needed +if (!skipBuildArg) { + console.log("Building first-party packages..."); + try { + execSync("pnpm b:all", { stdio: "inherit", cwd: rootDir }); + } catch (error) { + console.error("Failed to build first-party packages:", error); + process.exit(1); + } +} + +// Concatenate first-party packages +console.log("Concatenating first-party packages..."); +config.firstParty.forEach((pkg) => { + const browserFile = path.join(rootDir, pkg.path, pkg.browserPath); + + if (fs.existsSync(browserFile)) { + const content = fs.readFileSync(browserFile); + fs.appendFileSync(outputFile, content); + console.log(`Added ${pkg.name} (${browserFile})`); + } else { + console.warn(`Warning: ${browserFile} not found for ${pkg.name}`); + } +}); + +// Handle second-party packages +if (useNpmArg) { + // Install from npm + console.log("Installing second-party packages from npm..."); + + const tempDir = path.join(rootDir, "temp-install"); + if (!fs.existsSync(tempDir)) { + fs.mkdirSync(tempDir, { recursive: true }); + } + + // Create package.json for temp install + const tempPackageJson = { + name: "temp-install", + private: true, + dependencies: {} + }; + + // Collect all package names from second-party configs + config.secondParty.forEach((pkg) => { + if (pkg.isMonorepo && pkg.packages) { + pkg.packages.forEach((subPkg) => { + tempPackageJson.dependencies[subPkg.name] = version; + }); + } else { + tempPackageJson.dependencies[pkg.name] = version; + } + }); + + fs.writeFileSync(path.join(tempDir, "package.json"), JSON.stringify(tempPackageJson, null, 2)); + + // Install packages + try { + execSync("npm install", { stdio: "inherit", cwd: tempDir }); + } catch (error) { + console.error("Failed to install second-party packages:", error); + process.exit(1); + } + + // Concatenate second-party packages + console.log("Concatenating second-party packages..."); + config.secondParty.forEach((pkg) => { + if (pkg.isMonorepo && pkg.packages) { + pkg.packages.forEach((subPkg) => { + const browserFile = path.join(tempDir, "node_modules", subPkg.name, subPkg.browserPath); + + if (fs.existsSync(browserFile)) { + const content = fs.readFileSync(browserFile); + fs.appendFileSync(outputFile, content); + console.log(`Added ${subPkg.name} (${browserFile})`); + } else { + console.warn(`Warning: ${browserFile} not found for ${subPkg.name}`); + } + }); + } else { + const browserFile = path.join(tempDir, "node_modules", pkg.name, pkg.browserPath); + + if (fs.existsSync(browserFile)) { + const content = fs.readFileSync(browserFile); + fs.appendFileSync(outputFile, content); + console.log(`Added ${pkg.name} (${browserFile})`); + } else { + console.warn(`Warning: ${browserFile} not found for ${pkg.name}`); + } + } + }); +} else { + // Build from source + console.log("Building second-party packages from source..."); + + config.secondParty.forEach((pkg) => { + const repoDir = path.join(rootDir, path.basename(pkg.repo, ".git")); + + // Clone repo if it doesn't exist + if (!fs.existsSync(repoDir)) { + console.log(`Cloning ${pkg.name} from ${pkg.repo}...`); + const cloneCmd = pkg.branch + ? `git clone ${pkg.repo} ${repoDir} -b ${pkg.branch}` + : `git clone ${pkg.repo} ${repoDir}`; + + try { + execSync(cloneCmd, { stdio: "inherit" }); + } catch (error) { + console.error(`Failed to clone ${pkg.name}:`, error); + return; + } + } + + // Link engine + console.log(`Linking engine to ${pkg.name}...`); + try { + execSync("pnpm link ../packages/galacean", { + stdio: "inherit", + cwd: repoDir + }); + } catch (error) { + console.warn(`Warning: Failed to link engine to ${pkg.name}:`, error); + } + + // Install dependencies + console.log(`Installing dependencies for ${pkg.name}...`); + try { + execSync("pnpm install", { stdio: "inherit", cwd: repoDir }); + } catch (error) { + console.error(`Failed to install dependencies for ${pkg.name}:`, error); + return; + } + + // Build package + if (!skipBuildArg) { + console.log(`Building ${pkg.name}...`); + try { + execSync(pkg.buildCommand, { stdio: "inherit", cwd: repoDir }); + } catch (error) { + console.error(`Failed to build ${pkg.name}:`, error); + return; + } + } + + // Concatenate browser files + if (pkg.isMonorepo && pkg.packages) { + pkg.packages.forEach((subPkg) => { + const packageDir = path.join(repoDir, subPkg.packagePath); + const browserFile = path.join(packageDir, subPkg.browserPath); + + if (fs.existsSync(browserFile)) { + const content = fs.readFileSync(browserFile); + fs.appendFileSync(outputFile, content); + console.log(`Added ${subPkg.name} (${browserFile})`); + } else { + console.warn(`Warning: ${browserFile} not found for ${subPkg.name}`); + } + }); + } else { + const packageDir = pkg.packagePath === "." ? repoDir : path.join(repoDir, pkg.packagePath); + const browserFile = path.join(packageDir, pkg.browserPath); + + if (fs.existsSync(browserFile)) { + const content = fs.readFileSync(browserFile); + fs.appendFileSync(outputFile, content); + console.log(`Added ${pkg.name} (${browserFile})`); + } else { + console.warn(`Warning: ${browserFile} not found for ${pkg.name}`); + } + } + }); +} + +// Output file stats +const stats = fs.statSync(outputFile); +console.log(`\nCreated ${outputFile} (${(stats.size / 1024 / 1024).toFixed(2)} MB)`); +console.log("Done!"); diff --git a/scripts/editor-preload-config.js b/scripts/editor-preload-config.js new file mode 100644 index 000000000..26606987b --- /dev/null +++ b/scripts/editor-preload-config.js @@ -0,0 +1,75 @@ +module.exports = { + firstParty: [ + { + name: "@galacean/engine", + path: "packages/galacean", + browserPath: "dist/browser.js" + }, + { + name: "@galacean/engine-xr", + path: "packages/xr", + browserPath: "dist/browser.js" + }, + { + name: "@galacean/engine-ui", + path: "packages/ui", + browserPath: "dist/browser.js" + }, + { + name: "@galacean/engine-physics-lite", + path: "packages/physics-lite", + browserPath: "dist/browser.js" + }, + { + name: "@galacean/engine-physics-physx", + path: "packages/physics-physx", + browserPath: "dist/browser.js" + }, + { + name: "@galacean/engine-shaderlab", + path: "packages/shader-lab", + browserPath: "dist/browser.js" + }, + { + name: "@galacean/engine-shader-shaderlab", + path: "packages/shader-shaderlab", + browserPath: "dist/browser.js" + } + ], + + secondParty: [ + { + name: "@galacean/engine-toolkit", + repo: "https://github.com/galacean/engine-toolkit.git", + isMonorepo: true, + buildCommand: "pnpm b:all", + packages: [ + { + name: "@galacean/engine-toolkit", + packagePath: "packages/galacean-engine-toolkit", + browserPath: "dist/umd/browser.js" + }, + { + name: "@galacean/engine-toolkit-xr", + packagePath: "packages/xr", + browserPath: "dist/umd/browser.js" + } + ] + }, + { + name: "@galacean/engine-lottie", + repo: "https://github.com/galacean/engine-lottie.git", + packagePath: ".", + browserPath: "dist/browser.js", + buildCommand: "pnpm build" + }, + { + name: "@galacean/engine-spine", + repo: "https://github.com/galacean/engine-spine.git", + branch: "4.2", + packagePath: ".", + browserPath: "dist/browser.js", + buildCommand: "pnpm build" + } + ] +};