ci: update last deployment commit SHA to cdcbbfd03cfd3f80c5a804425970… #180
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Deploy Jekyll site to Pages | |
| on: | |
| # 当收到 deepnotes 的触发事件时运行 | |
| repository_dispatch: | |
| types: [trigger-build] | |
| # 允许从 Actions 选项卡手动运行 | |
| workflow_dispatch: | |
| # 当直接推送到 main 分支时运行 | |
| push: | |
| branches: ["main"] | |
| # 设置 GITHUB_TOKEN 的权限以允许部署到 GitHub Pages | |
| permissions: | |
| contents: read | |
| pages: write | |
| id-token: write | |
| # 只允许一个并发部署,跳过正在运行和最新排队的运行之间的运行 | |
| # 但是,不要取消正在进行的运行,因为我们希望允许这些生产部署完成 | |
| concurrency: | |
| group: "pages" | |
| cancel-in-progress: false | |
| env: | |
| PYTHON_VERSION: "3.11" | |
| jobs: | |
| # 构建作业 | |
| build: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: 📥 Checkout | |
| uses: actions/checkout@v4 | |
| - name: 🐍 Setup Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: 📦 Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '18' | |
| cache: 'npm' | |
| - name: 📦 Install Python dependencies | |
| run: | | |
| pip install beautifulsoup4 PyYAML lxml Pillow requests python-dotenv | |
| - name: 📥 Checkout deepnotes repository (for _slides generation) | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: shenh10/deepnotes | |
| token: ${{ secrets.GH_PAT }} | |
| path: deepnotes-temp | |
| fetch-depth: 0 | |
| - name: 🔄 Generate _slides from deepnotes HTML files | |
| run: | | |
| echo "检查并生成 _slides..." | |
| # 检查 deepnotes 中是否有 slides HTML 文件 | |
| if [ -d "deepnotes-temp" ]; then | |
| # 查找所有包含 'slides' 的 HTML 文件 | |
| SLIDES_HTML=$(find deepnotes-temp -type f -name "*.html" -path "*/slides/*" 2>/dev/null | head -1) | |
| if [ -n "$SLIDES_HTML" ]; then | |
| echo "✅ 发现 deepnotes 中的 slides HTML 文件,开始生成 _slides..." | |
| # 创建临时输出目录 | |
| mkdir -p /tmp/jekyll_output/_slides | |
| mkdir -p /tmp/jekyll_output/_data | |
| # 运行转换脚本(会转换所有文件,但只使用 _slides 部分) | |
| cd deepnotes-temp | |
| python3 scripts/html_to_jekyll_converter.py . /tmp/jekyll_output | |
| cd .. | |
| # 检查是否生成了 _slides | |
| if [ -d "/tmp/jekyll_output/_slides" ] && [ "$(ls -A /tmp/jekyll_output/_slides 2>/dev/null)" ]; then | |
| echo "✅ _slides 生成成功,开始同步..." | |
| mkdir -p _slides | |
| cp -r /tmp/jekyll_output/_slides/* _slides/ | |
| # 同步 slides_collection_structure.yml(如果存在) | |
| if [ -f "/tmp/jekyll_output/_data/slides_collection_structure.yml" ]; then | |
| mkdir -p _data | |
| cp /tmp/jekyll_output/_data/slides_collection_structure.yml _data/ | |
| echo "✅ 已同步 slides_collection_structure.yml" | |
| fi | |
| # 显示同步的文件数量 | |
| SLIDES_COUNT=$(find _slides -type f -name '*.html' | wc -l | tr -d ' ') | |
| echo "✅ 已同步 $SLIDES_COUNT 个 slides 文件" | |
| else | |
| echo "⚠️ 转换脚本未生成 _slides,跳过" | |
| fi | |
| else | |
| echo "⚠️ deepnotes 中未找到 slides HTML 文件,跳过生成" | |
| fi | |
| else | |
| echo "⚠️ deepnotes 目录不存在,跳过生成" | |
| fi | |
| continue-on-error: true | |
| - name: 📦 Install Node.js dependencies | |
| run: | | |
| npm install | |
| - name: 📝 Generate excerpts mapping | |
| run: | | |
| echo "📝 生成摘要映射..." | |
| python3 scripts/generate_excerpts.py | |
| # 确保assets/data目录存在 | |
| mkdir -p assets/data | |
| # 复制摘要映射文件到assets/data/供客户端使用 | |
| cp _data/excerpts.json assets/data/excerpts.json | |
| echo "✅ 摘要映射生成完成" | |
| - name: 💎 Setup Ruby | |
| uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: "3.2" | |
| bundler-cache: true | |
| cache-version: 0 | |
| - name: 🔧 Setup Pages | |
| id: pages | |
| uses: actions/configure-pages@v4 | |
| - name: 🔧 Inject Supabase config from environment | |
| run: | | |
| if [ -n "${{ secrets.SUPABASE_URL }}" ] && [ -n "${{ secrets.SUPABASE_ANON_KEY }}" ]; then | |
| echo "注入 Supabase 配置..." | |
| python3 scripts/inject-env-to-config.py | |
| else | |
| echo "⚠️ Supabase 环境变量未设置,跳过配置注入" | |
| fi | |
| env: | |
| SUPABASE_URL: ${{ secrets.SUPABASE_URL }} | |
| SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }} | |
| - name: 🏗️ Build with Jekyll (first build for thumbnail extraction) | |
| run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}" | |
| env: | |
| JEKYLL_ENV: production | |
| - name: 🖼️ Generate thumbnails | |
| run: | | |
| echo "开始生成缩略图..." | |
| python3 scripts/gen_thumbs.py | |
| # 确保assets/data目录存在 | |
| mkdir -p assets/data | |
| # 复制缩略图映射文件到assets/data/供客户端使用 | |
| cp _data/thumbnails_by_path.yml assets/data/thumbnails_by_path.yml | |
| echo "缩略图生成完成!" | |
| - name: 📊 Check thumbnails | |
| run: | | |
| echo "检查生成的缩略图..." | |
| echo "thumbnails_by_path.yml 行数: $(wc -l < _data/thumbnails_by_path.yml)" | |
| echo "缩略图文件数量: $(ls -1 assets/data/ | wc -l)" | |
| echo "=== 缩略图 mapping 前10行预览 ===" | |
| head -n 10 _data/thumbnails_by_path.yml | |
| - name: 🧹 Clean Jekyll cache before rebuild | |
| run: | | |
| echo "清理 Jekyll 缓存..." | |
| rm -rf .jekyll-cache .jekyll-metadata _site | |
| - name: 🔧 Re-inject Supabase config (before rebuild) | |
| run: | | |
| if [ -n "${{ secrets.SUPABASE_URL }}" ] && [ -n "${{ secrets.SUPABASE_ANON_KEY }}" ]; then | |
| python3 scripts/inject-env-to-config.py | |
| fi | |
| env: | |
| SUPABASE_URL: ${{ secrets.SUPABASE_URL }} | |
| SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }} | |
| - name: 🏗️ Rebuild with Jekyll (second build to include thumbnails) | |
| run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}" | |
| env: | |
| JEKYLL_ENV: production | |
| - name: 📊 Verify build output (check slides and papers) | |
| run: | | |
| echo "检查构建输出..." | |
| echo "=== _site 目录结构 ===" | |
| ls -la _site/ | head -20 | |
| echo "" | |
| echo "=== 检查 slides 目录 ===" | |
| if [ -d "_site/slides" ]; then | |
| echo "✅ _site/slides 目录存在" | |
| SLIDES_COUNT=$(find _site/slides -type f -name '*.html' ! -name 'index.html' | wc -l | tr -d ' ') | |
| echo "Slides 文件数量(排除index.html): $SLIDES_COUNT" | |
| if [ "$SLIDES_COUNT" -eq "0" ]; then | |
| echo "⚠️ 警告:没有找到任何 slides 页面文件!" | |
| echo "检查 _slides 源文件:" | |
| ls -la _slides/ | head -10 | |
| echo "" | |
| echo "检查 _site/slides 目录结构:" | |
| find _site/slides -type d | head -10 | |
| echo "" | |
| echo "所有 _site/slides 下的文件:" | |
| find _site/slides -type f | head -10 | |
| else | |
| echo "✅ Slides 文件生成正常" | |
| echo "前10个 slides 文件:" | |
| find _site/slides -type f -name '*.html' ! -name 'index.html' | head -10 | |
| fi | |
| else | |
| echo "❌ _site/slides 目录不存在!" | |
| echo "检查 _slides 源文件:" | |
| ls -la _slides/ | head -10 | |
| exit 1 | |
| fi | |
| echo "" | |
| echo "=== 检查 papers 目录 ===" | |
| if [ -d "_site/papers" ]; then | |
| echo "✅ _site/papers 目录存在" | |
| PAPERS_COUNT=$(find _site/papers -type f -name '*.html' ! -name 'index.html' | wc -l | tr -d ' ') | |
| echo "Papers 文件数量(排除index.html): $PAPERS_COUNT" | |
| else | |
| echo "⚠️ _site/papers 目录不存在" | |
| fi | |
| # ⚠️ 暂时禁用清理步骤,避免误删数据 | |
| # 问题:URL 匹配可能不一致,导致所有记录被误删 | |
| # TODO: 修复 URL 规范化逻辑后再启用 | |
| # - name: 🧹 Sync Supabase with posts (cleanup orphan records) | |
| # run: | | |
| # if [ -n "${{ secrets.SUPABASE_URL }}" ] && [ -n "${{ secrets.SUPABASE_SERVICE_KEY }}" ]; then | |
| # echo "🔄 同步 Supabase 数据库..." | |
| # export SUPABASE_URL="${{ secrets.SUPABASE_URL }}" | |
| # export SUPABASE_SERVICE_KEY="${{ secrets.SUPABASE_SERVICE_KEY }}" | |
| # python3 scripts/sync_supabase_with_posts.py || echo "⚠️ Supabase 同步失败,继续部署..." | |
| # else | |
| # echo "⚠️ Supabase 配置未设置,跳过同步" | |
| # fi | |
| # continue-on-error: true | |
| # env: | |
| # SUPABASE_URL: ${{ secrets.SUPABASE_URL }} | |
| # SUPABASE_SERVICE_KEY: ${{ secrets.SUPABASE_SERVICE_KEY }} | |
| - name: 📤 Upload artifact | |
| uses: actions/upload-pages-artifact@v3 | |
| - name: 🚀 Deploy to Cloudflare Pages | |
| uses: cloudflare/pages-action@v1 | |
| with: | |
| apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| projectName: papercache | |
| directory: _site | |