From a6797edbc3a62f84a34572a923df542b2f88146b Mon Sep 17 00:00:00 2001 From: Gaubee Date: Mon, 26 Jan 2026 20:54:23 +0800 Subject: [PATCH] feat: complete implementation --- .github/workflows/cd.yml | 432 +++++++++++++++++++-------------------- 1 file changed, 216 insertions(+), 216 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 2a593094c..c29bc65c1 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -169,53 +169,53 @@ jobs: if [ -f "$DWEB_DIR/metadata.json" ]; then DWEB_DIR="$DWEB_DIR" DWEB_ZIP="$DWEB_ZIP" DWEB_PATH="$DWEB_PATH" SITE_ORIGIN="$SITE_ORIGIN" VITEPRESS_BASE="$VITEPRESS_BASE" node - <<'NODE' -const fs = require('fs'); -const path = require('path'); -const dwebDir = process.env.DWEB_DIR; -const zipName = process.env.DWEB_ZIP; -const dwebPath = process.env.DWEB_PATH || ''; -const siteOrigin = process.env.SITE_ORIGIN || ''; -const basePath = process.env.VITEPRESS_BASE || '/'; -const metadataPath = path.join(dwebDir, 'metadata.json'); -const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8')); -const logoFileName = 'logo-256.webp'; -const normalizedPath = dwebPath.replace(/^\/+/, '').replace(/\/$/, ''); -const baseUrl = siteOrigin ? new URL(basePath, siteOrigin).toString() : ''; -const logoPath = normalizedPath ? `${normalizedPath}/${logoFileName}` : logoFileName; -const logoUrl = baseUrl ? new URL(logoPath, baseUrl).toString() : logoFileName; -if (metadata.logo) { - const lower = String(metadata.logo).toLowerCase(); - if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { - metadata.logo = logoUrl; - } -} else { - metadata.logo = logoUrl; -} -if (Array.isArray(metadata.icons)) { - metadata.icons = metadata.icons.map((icon) => { - if (!icon?.src) return icon; - const src = String(icon.src); - const lower = src.toLowerCase(); - if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { - return { ...icon, src: logoUrl }; - } - return icon; - }); -} -const bundleUrl = typeof metadata.bundle_url === 'string' ? metadata.bundle_url : ''; -if (bundleUrl) { - const bundleFile = bundleUrl.replace(/^\.\//, ''); - const bundlePath = path.join(dwebDir, bundleFile); - if (fs.existsSync(bundlePath)) { - fs.copyFileSync(bundlePath, path.join(dwebDir, zipName)); - } else { - console.warn(`DWEB bundle not found: ${bundlePath}`); - } -} else { - console.warn('metadata.json missing bundle_url'); -} -fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)); -NODE + const fs = require('fs'); + const path = require('path'); + const dwebDir = process.env.DWEB_DIR; + const zipName = process.env.DWEB_ZIP; + const dwebPath = process.env.DWEB_PATH || ''; + const siteOrigin = process.env.SITE_ORIGIN || ''; + const basePath = process.env.VITEPRESS_BASE || '/'; + const metadataPath = path.join(dwebDir, 'metadata.json'); + const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8')); + const logoFileName = 'logo-256.webp'; + const normalizedPath = dwebPath.replace(/^\/+/, '').replace(/\/$/, ''); + const baseUrl = siteOrigin ? new URL(basePath, siteOrigin).toString() : ''; + const logoPath = normalizedPath ? `${normalizedPath}/${logoFileName}` : logoFileName; + const logoUrl = baseUrl ? new URL(logoPath, baseUrl).toString() : logoFileName; + if (metadata.logo) { + const lower = String(metadata.logo).toLowerCase(); + if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { + metadata.logo = logoUrl; + } + } else { + metadata.logo = logoUrl; + } + if (Array.isArray(metadata.icons)) { + metadata.icons = metadata.icons.map((icon) => { + if (!icon?.src) return icon; + const src = String(icon.src); + const lower = src.toLowerCase(); + if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { + return { ...icon, src: logoUrl }; + } + return icon; + }); + } + const bundleUrl = typeof metadata.bundle_url === 'string' ? metadata.bundle_url : ''; + if (bundleUrl) { + const bundleFile = bundleUrl.replace(/^\.\//, ''); + const bundlePath = path.join(dwebDir, bundleFile); + if (fs.existsSync(bundlePath)) { + fs.copyFileSync(bundlePath, path.join(dwebDir, zipName)); + } else { + console.warn(`DWEB bundle not found: ${bundlePath}`); + } + } else { + console.warn('metadata.json missing bundle_url'); + } + fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)); + NODE else echo "metadata.json missing in $DWEB_DIR" fi @@ -249,39 +249,39 @@ NODE fi if [ -f "gh-pages/dweb/metadata.json" ]; then DWEB_PATH="dweb" SITE_ORIGIN="$SITE_ORIGIN" VITEPRESS_BASE="$VITEPRESS_BASE" node - <<'NODE' -const fs = require('fs'); -const path = require('path'); -const metadataPath = path.join('gh-pages', 'dweb', 'metadata.json'); -const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8')); -const logoFileName = 'logo-256.webp'; -const dwebPath = process.env.DWEB_PATH || ''; -const siteOrigin = process.env.SITE_ORIGIN || ''; -const basePath = process.env.VITEPRESS_BASE || '/'; -const normalizedPath = dwebPath.replace(/^\/+/, '').replace(/\/$/, ''); -const baseUrl = siteOrigin ? new URL(basePath, siteOrigin).toString() : ''; -const logoPath = normalizedPath ? `${normalizedPath}/${logoFileName}` : logoFileName; -const logoUrl = baseUrl ? new URL(logoPath, baseUrl).toString() : logoFileName; -if (metadata.logo) { - const lower = String(metadata.logo).toLowerCase(); - if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { - metadata.logo = logoUrl; - } -} else { - metadata.logo = logoUrl; -} -if (Array.isArray(metadata.icons)) { - metadata.icons = metadata.icons.map((icon) => { - if (!icon?.src) return icon; - const src = String(icon.src); - const lower = src.toLowerCase(); - if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { - return { ...icon, src: logoUrl }; - } - return icon; - }); -} -fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)); -NODE + const fs = require('fs'); + const path = require('path'); + const metadataPath = path.join('gh-pages', 'dweb', 'metadata.json'); + const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8')); + const logoFileName = 'logo-256.webp'; + const dwebPath = process.env.DWEB_PATH || ''; + const siteOrigin = process.env.SITE_ORIGIN || ''; + const basePath = process.env.VITEPRESS_BASE || '/'; + const normalizedPath = dwebPath.replace(/^\/+/, '').replace(/\/$/, ''); + const baseUrl = siteOrigin ? new URL(basePath, siteOrigin).toString() : ''; + const logoPath = normalizedPath ? `${normalizedPath}/${logoFileName}` : logoFileName; + const logoUrl = baseUrl ? new URL(logoPath, baseUrl).toString() : logoFileName; + if (metadata.logo) { + const lower = String(metadata.logo).toLowerCase(); + if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { + metadata.logo = logoUrl; + } + } else { + metadata.logo = logoUrl; + } + if (Array.isArray(metadata.icons)) { + metadata.icons = metadata.icons.map((icon) => { + if (!icon?.src) return icon; + const src = String(icon.src); + const lower = src.toLowerCase(); + if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { + return { ...icon, src: logoUrl }; + } + return icon; + }); + } + fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)); + NODE fi fi fi @@ -338,34 +338,34 @@ NODE if [ -f "release/metadata.json" ]; then RELEASE_BASE_URL="$RELEASE_BASE_URL" node - <<'NODE' -const fs = require('fs'); -const path = require('path'); -const metadataPath = path.join('release', 'metadata.json'); -const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8')); -const logoFileName = 'logo-256.webp'; -const releaseBaseUrl = process.env.RELEASE_BASE_URL || ''; -const logoUrl = releaseBaseUrl ? new URL(logoFileName, releaseBaseUrl).toString() : logoFileName; -if (metadata.logo) { - const lower = String(metadata.logo).toLowerCase(); - if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { - metadata.logo = logoUrl; - } -} else { - metadata.logo = logoUrl; -} -if (Array.isArray(metadata.icons)) { - metadata.icons = metadata.icons.map((icon) => { - if (!icon?.src) return icon; - const src = String(icon.src); - const lower = src.toLowerCase(); - if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { - return { ...icon, src: logoUrl }; - } - return icon; - }); -} -fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)); -NODE + const fs = require('fs'); + const path = require('path'); + const metadataPath = path.join('release', 'metadata.json'); + const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8')); + const logoFileName = 'logo-256.webp'; + const releaseBaseUrl = process.env.RELEASE_BASE_URL || ''; + const logoUrl = releaseBaseUrl ? new URL(logoFileName, releaseBaseUrl).toString() : logoFileName; + if (metadata.logo) { + const lower = String(metadata.logo).toLowerCase(); + if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { + metadata.logo = logoUrl; + } + } else { + metadata.logo = logoUrl; + } + if (Array.isArray(metadata.icons)) { + metadata.icons = metadata.icons.map((icon) => { + if (!icon?.src) return icon; + const src = String(icon.src); + const lower = src.toLowerCase(); + if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { + return { ...icon, src: logoUrl }; + } + return icon; + }); + } + fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)); + NODE fi # 上传 DWEB 到 SFTP 服务器 @@ -643,53 +643,53 @@ NODE if [ -f "$DWEB_DIR/metadata.json" ]; then DWEB_DIR="$DWEB_DIR" DWEB_ZIP="$DWEB_ZIP" DWEB_PATH="$DWEB_PATH" SITE_ORIGIN="$SITE_ORIGIN" VITEPRESS_BASE="$VITEPRESS_BASE" node - <<'NODE' -const fs = require('fs'); -const path = require('path'); -const dwebDir = process.env.DWEB_DIR; -const zipName = process.env.DWEB_ZIP; -const dwebPath = process.env.DWEB_PATH || ''; -const siteOrigin = process.env.SITE_ORIGIN || ''; -const basePath = process.env.VITEPRESS_BASE || '/'; -const metadataPath = path.join(dwebDir, 'metadata.json'); -const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8')); -const logoFileName = 'logo-256.webp'; -const normalizedPath = dwebPath.replace(/^\/+/, '').replace(/\/$/, ''); -const baseUrl = siteOrigin ? new URL(basePath, siteOrigin).toString() : ''; -const logoPath = normalizedPath ? `${normalizedPath}/${logoFileName}` : logoFileName; -const logoUrl = baseUrl ? new URL(logoPath, baseUrl).toString() : logoFileName; -if (metadata.logo) { - const lower = String(metadata.logo).toLowerCase(); - if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { - metadata.logo = logoUrl; - } -} else { - metadata.logo = logoUrl; -} -if (Array.isArray(metadata.icons)) { - metadata.icons = metadata.icons.map((icon) => { - if (!icon?.src) return icon; - const src = String(icon.src); - const lower = src.toLowerCase(); - if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { - return { ...icon, src: logoUrl }; - } - return icon; - }); -} -const bundleUrl = typeof metadata.bundle_url === 'string' ? metadata.bundle_url : ''; -if (bundleUrl) { - const bundleFile = bundleUrl.replace(/^\.\//, ''); - const bundlePath = path.join(dwebDir, bundleFile); - if (fs.existsSync(bundlePath)) { - fs.copyFileSync(bundlePath, path.join(dwebDir, zipName)); - } else { - console.warn(`DWEB bundle not found: ${bundlePath}`); - } -} else { - console.warn('metadata.json missing bundle_url'); -} -fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)); -NODE + const fs = require('fs'); + const path = require('path'); + const dwebDir = process.env.DWEB_DIR; + const zipName = process.env.DWEB_ZIP; + const dwebPath = process.env.DWEB_PATH || ''; + const siteOrigin = process.env.SITE_ORIGIN || ''; + const basePath = process.env.VITEPRESS_BASE || '/'; + const metadataPath = path.join(dwebDir, 'metadata.json'); + const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8')); + const logoFileName = 'logo-256.webp'; + const normalizedPath = dwebPath.replace(/^\/+/, '').replace(/\/$/, ''); + const baseUrl = siteOrigin ? new URL(basePath, siteOrigin).toString() : ''; + const logoPath = normalizedPath ? `${normalizedPath}/${logoFileName}` : logoFileName; + const logoUrl = baseUrl ? new URL(logoPath, baseUrl).toString() : logoFileName; + if (metadata.logo) { + const lower = String(metadata.logo).toLowerCase(); + if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { + metadata.logo = logoUrl; + } + } else { + metadata.logo = logoUrl; + } + if (Array.isArray(metadata.icons)) { + metadata.icons = metadata.icons.map((icon) => { + if (!icon?.src) return icon; + const src = String(icon.src); + const lower = src.toLowerCase(); + if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { + return { ...icon, src: logoUrl }; + } + return icon; + }); + } + const bundleUrl = typeof metadata.bundle_url === 'string' ? metadata.bundle_url : ''; + if (bundleUrl) { + const bundleFile = bundleUrl.replace(/^\.\//, ''); + const bundlePath = path.join(dwebDir, bundleFile); + if (fs.existsSync(bundlePath)) { + fs.copyFileSync(bundlePath, path.join(dwebDir, zipName)); + } else { + console.warn(`DWEB bundle not found: ${bundlePath}`); + } + } else { + console.warn('metadata.json missing bundle_url'); + } + fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)); + NODE else echo "metadata.json missing in $DWEB_DIR" fi @@ -723,39 +723,39 @@ NODE fi if [ -f "gh-pages/dweb/metadata.json" ]; then DWEB_PATH="dweb" SITE_ORIGIN="$SITE_ORIGIN" VITEPRESS_BASE="$VITEPRESS_BASE" node - <<'NODE' -const fs = require('fs'); -const path = require('path'); -const metadataPath = path.join('gh-pages', 'dweb', 'metadata.json'); -const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8')); -const logoFileName = 'logo-256.webp'; -const dwebPath = process.env.DWEB_PATH || ''; -const siteOrigin = process.env.SITE_ORIGIN || ''; -const basePath = process.env.VITEPRESS_BASE || '/'; -const normalizedPath = dwebPath.replace(/^\/+/, '').replace(/\/$/, ''); -const baseUrl = siteOrigin ? new URL(basePath, siteOrigin).toString() : ''; -const logoPath = normalizedPath ? `${normalizedPath}/${logoFileName}` : logoFileName; -const logoUrl = baseUrl ? new URL(logoPath, baseUrl).toString() : logoFileName; -if (metadata.logo) { - const lower = String(metadata.logo).toLowerCase(); - if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { - metadata.logo = logoUrl; - } -} else { - metadata.logo = logoUrl; -} -if (Array.isArray(metadata.icons)) { - metadata.icons = metadata.icons.map((icon) => { - if (!icon?.src) return icon; - const src = String(icon.src); - const lower = src.toLowerCase(); - if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { - return { ...icon, src: logoUrl }; - } - return icon; - }); -} -fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)); -NODE + const fs = require('fs'); + const path = require('path'); + const metadataPath = path.join('gh-pages', 'dweb', 'metadata.json'); + const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8')); + const logoFileName = 'logo-256.webp'; + const dwebPath = process.env.DWEB_PATH || ''; + const siteOrigin = process.env.SITE_ORIGIN || ''; + const basePath = process.env.VITEPRESS_BASE || '/'; + const normalizedPath = dwebPath.replace(/^\/+/, '').replace(/\/$/, ''); + const baseUrl = siteOrigin ? new URL(basePath, siteOrigin).toString() : ''; + const logoPath = normalizedPath ? `${normalizedPath}/${logoFileName}` : logoFileName; + const logoUrl = baseUrl ? new URL(logoPath, baseUrl).toString() : logoFileName; + if (metadata.logo) { + const lower = String(metadata.logo).toLowerCase(); + if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { + metadata.logo = logoUrl; + } + } else { + metadata.logo = logoUrl; + } + if (Array.isArray(metadata.icons)) { + metadata.icons = metadata.icons.map((icon) => { + if (!icon?.src) return icon; + const src = String(icon.src); + const lower = src.toLowerCase(); + if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { + return { ...icon, src: logoUrl }; + } + return icon; + }); + } + fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)); + NODE fi fi fi @@ -816,34 +816,34 @@ NODE if [ -f "release/metadata.json" ]; then RELEASE_BASE_URL="$RELEASE_BASE_URL" node - <<'NODE' -const fs = require('fs'); -const path = require('path'); -const metadataPath = path.join('release', 'metadata.json'); -const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8')); -const logoFileName = 'logo-256.webp'; -const releaseBaseUrl = process.env.RELEASE_BASE_URL || ''; -const logoUrl = releaseBaseUrl ? new URL(logoFileName, releaseBaseUrl).toString() : logoFileName; -if (metadata.logo) { - const lower = String(metadata.logo).toLowerCase(); - if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { - metadata.logo = logoUrl; - } -} else { - metadata.logo = logoUrl; -} -if (Array.isArray(metadata.icons)) { - metadata.icons = metadata.icons.map((icon) => { - if (!icon?.src) return icon; - const src = String(icon.src); - const lower = src.toLowerCase(); - if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { - return { ...icon, src: logoUrl }; - } - return icon; - }); -} -fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)); -NODE + const fs = require('fs'); + const path = require('path'); + const metadataPath = path.join('release', 'metadata.json'); + const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8')); + const logoFileName = 'logo-256.webp'; + const releaseBaseUrl = process.env.RELEASE_BASE_URL || ''; + const logoUrl = releaseBaseUrl ? new URL(logoFileName, releaseBaseUrl).toString() : logoFileName; + if (metadata.logo) { + const lower = String(metadata.logo).toLowerCase(); + if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { + metadata.logo = logoUrl; + } + } else { + metadata.logo = logoUrl; + } + if (Array.isArray(metadata.icons)) { + metadata.icons = metadata.icons.map((icon) => { + if (!icon?.src) return icon; + const src = String(icon.src); + const lower = src.toLowerCase(); + if (lower.endsWith(`/${logoFileName}`) || lower.endsWith(logoFileName)) { + return { ...icon, src: logoUrl }; + } + return icon; + }); + } + fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)); + NODE fi echo "=== Release artifacts ==="