diff --git a/.github/config.template.ts b/.github/config.template.ts new file mode 100644 index 0000000..5ec5faa --- /dev/null +++ b/.github/config.template.ts @@ -0,0 +1,9 @@ +import { defineConfig } from 'vitepress'; +import sidebar from './sidebar.mjs'; + +export default defineConfig({ + title: 'Sec-Interview', + description: '安全面试笔记', + base: '/Sec-Interview/', + themeConfig: { sidebar } +}); diff --git a/.github/scripts/prepare.mjs b/.github/scripts/prepare.mjs new file mode 100644 index 0000000..1000724 --- /dev/null +++ b/.github/scripts/prepare.mjs @@ -0,0 +1,62 @@ +import fs from 'node:fs' +import path from 'node:path' + +const summary = fs.readFileSync('SUMMARY.md','utf8') +const ROOT = '.' +fs.mkdirSync(path.join(ROOT,'.vitepress'),{recursive:true}) + +function touch(mdPath){ + fs.mkdirSync(path.dirname(mdPath),{recursive:true}) + if (!fs.existsSync(mdPath)) fs.writeFileSync(mdPath,'# \n\n内容待补充。\n') +} + +/* ===== 生成可折叠 sidebar ===== */ +const sidebar = [] +let stack = [{ children: sidebar, level: -1 }] // 栈顶父节点 +const r = /^(\s*)-\s+\[([^\]]+)\]\(([^)]+)\)/gm +let m + +while ((m = r.exec(summary)) !== null) { + const [, sp, text, file] = m + const level = sp.length / 2 + const url = '/' + file.replace(/\.md$/,'') + + // 找到父节点 + while (level <= stack.at(-1).level) stack.pop() + const parent = stack.at(-1) + + // 一级目录 → 折叠对象;子项直接 push + const node = + level === 0 + ? { text, items: [{ text, link: url }], collapsed: true } // 默认折叠 + : { text, link: url } + + parent.children.push(node) + + // 预留子级挂载点 + if (level === 0) { + node.items = node.items || [] + stack.push({ children: node.items, level }) + } else { + stack.push({ children: parent.children, level }) + } + + touch(path.join(ROOT, file)) +} +/* ================================= */ + +// frontmatter 处理同上 +function walk(dir){ + for (const f of fs.readdirSync(dir)){ + const full = path.join(dir,f) + if (fs.statSync(full).isDirectory()){ walk(full); continue } + if (!f.endsWith('.md')) continue + const cnt = fs.readFileSync(full,'utf8') + if (!cnt.trimStart().startsWith('---')) + fs.writeFileSync(full, `---\n---\n${cnt}`) + } +} +walk(ROOT) + +fs.writeFileSync(path.join(ROOT,'.vitepress','sidebar.mjs'), + `export default ${JSON.stringify(sidebar,null,2)}`) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..738fd03 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,46 @@ +name: Build & Deploy VitePress +on: + push: + branches: [main] + +permissions: + contents: read + pages: write + id-token: write + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 20 + + - run: echo '{"type":"module","devDependencies":{"vitepress":"^1.0.0"}}' > package.json + - run: npm i + + - run: touch .nojekyll + + - run: node .github/scripts/prepare.mjs # 生成 sidebar.mjs + + # 关键替换:直接复制模板,避开 heredoc + - run: | + mkdir -p .vitepress + cp .github/config.template.ts .vitepress/config.ts + - run: npx vitepress build . + + - uses: actions/upload-pages-artifact@v3 + with: + path: .vitepress/dist + + deploy: + needs: build + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.d.outputs.page_url }} + steps: + - uses: actions/deploy-pages@v4 + id: d diff --git a/Chapter22/22-3.md b/Chapter22/22-3.md index b52ad46..dabe6e0 100644 --- a/Chapter22/22-3.md +++ b/Chapter22/22-3.md @@ -29,4 +29,4 @@ | 产生原因 | 父进程没有调用 wait() 或 waitpid()。 | 父进程在子进程之前退出。 | | 系统影响 | 占用 PID,大量存在会导致 PID 资源耗尽。 | 通常无害,会被 init 进程收养。 | | 处理方式 | 杀死其父进程。 | 由 init 进程自动收养并管理,无需人工干预。 | -| ps 状态 | Z 或 | 运行中,但其 PPID(父进程 ID)为 1。 | \ No newline at end of file +| ps 状态 | Z 或 `` | 运行中,但其 PPID(父进程 ID)为 1。 | diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts new file mode 100644 index 0000000..27182f0 --- /dev/null +++ b/docs/.vitepress/config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from 'vitepress' +import sidebar from './sidebar.mjs' + +export default defineConfig({ + title: 'Sec-Interview', + description: '安全面试笔记', + base: '/Sec-Interview/', + themeConfig: { sidebar } +})