chore: refresh docs pages publishing flow

This commit is contained in:
snomiao
2025-10-14 03:58:38 +00:00
parent cd714151fd
commit 807a395b29
10 changed files with 485 additions and 194 deletions

14
docs/pages/.gitignore vendored Normal file
View File

@@ -0,0 +1,14 @@
*
!/.gitignore
!/README.md
!/index.html
!/knip/
!/knip/index.html
knip/report.md
!/vite.config.ts
!/tsconfig.json
/storybook/
/nx-graph/
/coverage/
/vitest-ui/
/playwright-reports/

View File

@@ -33,11 +33,7 @@ The deployment is managed by the `.github/workflows/deploy-gh-pages.yml` workflo
2. **Build Process**:
- Installs dependencies with pnpm
- Builds Storybook static site
- Generates Nx dependency graph
- Creates TypeDoc documentation
- Runs tests and generates coverage reports
- Generates Knip analysis report
- Runs `scripts/build-pages.sh` to generate Storybook, Nx dependency graph, Vitest reports, coverage, and Knip analysis
- Creates a landing page with links to all tools
3. **Deployment**:
@@ -49,7 +45,7 @@ The deployment is managed by the `.github/workflows/deploy-gh-pages.yml` workflo
### Build Steps
Each tool is built in its own step with `continue-on-error: true`, ensuring that if one tool fails to build, the others will still be deployed.
The build script handles optional tooling gracefully—if an individual tool fails to build, the remainder of the deployment still proceeds and the failure is logged as a warning.
#### Storybook (Required)
```bash
@@ -63,12 +59,12 @@ pnpm nx graph --file=dist/nx-graph/index.html
#### Test Coverage (Optional)
```bash
pnpm test:unit --run --coverage --coverage.reporter=html
pnpm exec vitest --run --coverage --coverage.reporter=html
```
#### Vitest Results (Optional)
```bash
pnpm test:unit --run --reporter=html
pnpm exec vitest --run --reporter=html --outputFile dist/vitest-ui/index.html
```
#### Knip Report (Optional)

215
docs/pages/index.html Normal file
View File

@@ -0,0 +1,215 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ComfyUI Frontend - Development Tools</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 2rem;
/* bg: gray + white lines net */
background: #909090;
background-image: radial-gradient(circle, rgba(255, 255, 255, 0.05) 2px, transparent 2px), radial-gradient(circle, rgba(255, 255, 255, 0.05) 2px, transparent 2px);
background-position: 0 0, 25px 25px;
background-size: 50px 50px;
}
.container {
max-width: 1200px;
width: 100%;
}
.header {
text-align: center;
color: white;
margin-bottom: 3rem;
}
.header h1 {
font-size: 2.5rem;
margin-bottom: 0.5rem;
font-weight: 700;
}
.header p {
font-size: 1.125rem;
opacity: 0.9;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
}
p,h1,h2,h3,h4,h5,h6 {
transform: matrix(1, 0, -0.25, 1, 0, 0);
}
.card {
background: white;
border-radius: 12px;
padding: 2rem;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
transition: transform 0.2s, box-shadow 0.2s;
text-decoration: none;
color: inherit;
display: block;
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.15);
}
.card-icon {
font-size: 2.5rem;
margin-bottom: 1rem;
}
.card-title {
font-size: 1.5rem;
font-weight: 600;
margin-bottom: 0.5rem;
color: #1a202c;
}
.card-description {
color: #718096;
line-height: 1.6;
}
.card-status {
display: inline-block;
margin-top: 1rem;
padding: 0.25rem 0.75rem;
border-radius: 20px;
font-size: 0.875rem;
font-weight: 500;
}
.status-available {
background: #c6f6d5;
color: #22543d;
}
.status-loading {
background: #e9d8fd;
color: #44337a;
}
.status-unavailable {
background: #fed7d7;
color: #742a2a;
}
.footer {
text-align: center;
color: white;
margin-top: 3rem;
opacity: 0.8;
}
.footer a {
color: white;
text-decoration: underline;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>🎨 ComfyUI Frontend</h1>
<p>Development Tools & Documentation</p>
</div>
<div class="grid">
<a href="./storybook/index.html" class="card" data-status="storybook" data-fetch="./storybook/index.html">
<div class="card-icon">📚</div>
<h2 class="card-title">Storybook</h2>
<p class="card-description">Interactive component library and design system documentation</p>
<span class="card-status status-loading" data-status-indicator>Checking…</span>
</a>
<a href="./nx-graph/index.html" class="card" data-status="nx-graph" data-fetch="./nx-graph/index.html">
<div class="card-icon">🔗</div>
<h2 class="card-title">Nx Dependency Graph</h2>
<p class="card-description">Visual representation of project dependencies and build structure</p>
<span class="card-status status-loading" data-status-indicator>Checking…</span>
</a>
<a href="./coverage/index.html" class="card" data-status="coverage" data-fetch="./coverage/index.html">
<div class="card-icon">📊</div>
<h2 class="card-title">Test Coverage</h2>
<p class="card-description">Code coverage reports from Vitest unit tests</p>
<span class="card-status status-loading" data-status-indicator>Checking…</span>
</a>
<a href="./playwright-reports/index.html" class="card" data-status="playwright" data-fetch="./playwright-reports/index.html">
<div class="card-icon">🎭</div>
<h2 class="card-title">Playwright E2E</h2>
<p class="card-description">Browser end-to-end test reports generated by Playwright</p>
<span class="card-status status-loading" data-status-indicator>Checking…</span>
</a>
<a href="./vitest-ui/index.html" class="card" data-status="vitest-ui" data-fetch="./vitest-ui/index.html">
<div class="card-icon">🧪</div>
<h2 class="card-title">Vitest Results</h2>
<p class="card-description">Interactive test results and reports</p>
<span class="card-status status-loading" data-status-indicator>Checking…</span>
</a>
<a href="./knip/index.html" class="card" data-status="knip" data-fetch="./knip/report.md">
<div class="card-icon">🔍</div>
<h2 class="card-title">Knip Report</h2>
<p class="card-description">Unused code and dependency analysis</p>
<span class="card-status status-loading" data-status-indicator>Checking…</span>
</a>
</div>
<div class="footer">
<p>
Built from the <strong>main</strong> branch &bull;
<a href="https://github.com/Comfy-Org/ComfyUI_frontend" target="_blank">GitHub Repository</a> &bull;
<a href="https://docs.comfy.org" target="_blank">Official Documentation</a>
</p>
</div>
</div>
<script>
const cards = Array.from(document.querySelectorAll('.card[data-status]'))
const setStatus = (card, variant, text) => {
const indicator = card.querySelector('[data-status-indicator]')
if (!indicator) return
indicator.classList.remove('status-loading', 'status-available', 'status-unavailable')
indicator.classList.add(`status-${variant}`)
indicator.textContent = text
}
const absoluteUrl = (href) => new URL(href, window.location.href).toString()
const controller = new AbortController()
const timeout = setTimeout(() => controller.abort(), 10000)
cards.forEach((card) => {
const href = card.dataset.fetch || card.getAttribute('href')
if (!href) {
setStatus(card, 'unavailable', 'No link configured')
return
}
fetch(absoluteUrl(href), { cache: 'no-store', signal: controller.signal })
.then((response) => {
if (response.ok) {
setStatus(card, 'available', 'Available')
} else {
setStatus(card, 'unavailable', `Unavailable (${response.status})`)
}
})
.catch((error) => {
const reason = error.name === 'AbortError' ? 'Timed out' : 'Unavailable'
setStatus(card, 'unavailable', reason)
})
})
window.addEventListener('beforeunload', () => {
clearTimeout(timeout)
controller.abort()
})
</script>
</body>
</html>

9
docs/pages/tsconfig.json Normal file
View File

@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"composite": false
},
"include": [
"./vite.config.ts"
]
}

46
docs/pages/vite.config.ts Normal file
View File

@@ -0,0 +1,46 @@
import fs from 'node:fs'
import { resolve } from 'node:path'
import { defineConfig } from 'vite'
const rootDir = __dirname
const outDir = resolve(rootDir, '../pages-dist')
const discoverHtmlEntries = () => {
const entries = new Map<string, string>()
const topLevel = resolve(rootDir, 'index.html')
if (fs.existsSync(topLevel)) entries.set('index', topLevel)
for (const dirent of fs.readdirSync(rootDir, { withFileTypes: true })) {
if (!dirent.isDirectory() || dirent.name.startsWith('.')) continue
const candidate = resolve(rootDir, dirent.name, 'index.html')
if (fs.existsSync(candidate)) entries.set(dirent.name, candidate)
}
return entries.size > 0 ? Object.fromEntries(entries) : undefined
}
export default defineConfig({
root: rootDir,
base: '/ComfyUI_frontend',
appType: 'mpa',
logLevel: 'info',
publicDir: false,
server: {
open: '/index.html',
fs: {
allow: [rootDir],
strict: false
}
},
preview: {
open: '/index.html'
},
build: {
emptyOutDir: false,
outDir,
copyPublicDir: false,
rollupOptions: {
input: discoverHtmlEntries()
}
}
})