PR Preview: Deploy #270
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
| # ============================================================================= | |
| # PR Preview: Deploy — 部署预览并发布 PR 评论 | |
| # | |
| # 触发时机: 由 pr-preview-build 完成后自动触发 (workflow_run) | |
| # 功能: | |
| # 1. Playground → 部署到 surge.sh → 独立评论 | |
| # 2. Client → 收集多平台 artifact 链接 → 独立评论 | |
| # 3. VSCode Plugin → 收集 .vsix 链接 → 独立评论 | |
| # 设计原则: | |
| # 每个产物的评论互相独立,某个构建失败不影响其他成功产物的评论 | |
| # 通过不同的 body-include 标记区分三条评论 | |
| # ============================================================================= | |
| name: 'PR Preview: Deploy' | |
| on: | |
| workflow_run: | |
| workflows: | |
| - 'PR Preview: Build' | |
| types: | |
| - completed | |
| permissions: | |
| actions: read | |
| pull-requests: write | |
| jobs: | |
| # ── 获取 PR 编号 ── | |
| get-pr-id: | |
| if: github.repository == 'Tencent/cherry-markdown' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| outputs: | |
| pr_id: ${{ steps.pr.outputs.id }} | |
| steps: | |
| - name: Download PR ID | |
| uses: dawidd6/action-download-artifact@v8 | |
| with: | |
| workflow: ${{ github.event.workflow_run.workflow_id }} | |
| run_id: ${{ github.event.workflow_run.id }} | |
| name: pr-id | |
| - name: Output PR ID | |
| id: pr | |
| run: echo "id=$(<pr-id.txt)" >> $GITHUB_OUTPUT | |
| # ── Playground: 部署 + 评论 ── | |
| deploy-playground: | |
| needs: get-pr-id | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Download playground artifact | |
| id: download | |
| uses: dawidd6/action-download-artifact@v8 | |
| continue-on-error: true | |
| with: | |
| workflow: ${{ github.event.workflow_run.workflow_id }} | |
| run_id: ${{ github.event.workflow_run.id }} | |
| name: playground | |
| - name: Deploy to surge.sh | |
| if: steps.download.outcome == 'success' | |
| id: deploy | |
| continue-on-error: true | |
| run: | | |
| export DEPLOY_DOMAIN=https://preview-pr-${{ needs.get-pr-id.outputs.pr_id }}-cherry-markdown.surge.sh | |
| npx surge --project ./ --domain $DEPLOY_DOMAIN --token ${{ secrets.SURGE_TOKEN }} | |
| echo "url=$DEPLOY_DOMAIN" >> $GITHUB_OUTPUT | |
| - name: Comment playground links | |
| if: steps.deploy.outcome == 'success' | |
| uses: TDesignOteam/workflows/actions/maintain-one-comment@main | |
| with: | |
| token: ${{ secrets.BOT_TOKEN }} | |
| body: | | |
| ### 🌐 Playground 预览 | |
| * [AI Chat 流式输入(标准版)](${{steps.deploy.outputs.url}}/ai_chat.html) | |
| * [AI Chat 流式输入(Stream 版 + 插件懒加载)](${{steps.deploy.outputs.url}}/ai_chat_stream.html) | |
| * [API 演示](${{steps.deploy.outputs.url}}/api.html) | |
| * [基础](${{steps.deploy.outputs.url}}/basic.html) | |
| * [图表工具栏](${{steps.deploy.outputs.url}}/chart_toolbar_demo.html) | |
| * [可视化配置生成器](${{steps.deploy.outputs.url}}/config_helper/index.html) | |
| * [自定义代码块外层容器](${{steps.deploy.outputs.url}}/custom_codeblock_wrapper.html) | |
| * [Draw.io 集成](${{steps.deploy.outputs.url}}/drawio_demo.html) | |
| * [移动端](${{steps.deploy.outputs.url}}/h5.html) | |
| * [自动编号标题](${{steps.deploy.outputs.url}}/head_num.html) | |
| * [图片编辑](${{steps.deploy.outputs.url}}/img.html) | |
| * [完整版](${{steps.deploy.outputs.url}}/index.html) | |
| * [Mermaid 流程图](${{steps.deploy.outputs.url}}/mermaid.html) | |
| * [多实例](${{steps.deploy.outputs.url}}/multiple.html) | |
| * [无工具栏](${{steps.deploy.outputs.url}}/notoolbar.html) | |
| * [纯预览模式](${{steps.deploy.outputs.url}}/preview_only.html) | |
| * [输入建议](${{steps.deploy.outputs.url}}/suggester.html) | |
| * [表格编辑](${{steps.deploy.outputs.url}}/table.html) | |
| * [VIM 编辑模式](${{steps.deploy.outputs.url}}/vim.html) | |
| * [XSS 测试](${{steps.deploy.outputs.url}}/xss.html)(默认禁用,需配置后允许) | |
| <!-- AUTO_PREVIEW_PLAYGROUND --> | |
| number: ${{ needs.get-pr-id.outputs.pr_id }} | |
| body-include: '<!-- AUTO_PREVIEW_PLAYGROUND -->' | |
| # ── Client: 收集链接 + 评论 ── | |
| comment-client: | |
| needs: get-pr-id | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Collect client artifacts | |
| id: collect | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| const runId = ${{ github.event.workflow_run.id }}; | |
| const { data: artifactList } = await github.rest.actions.listWorkflowRunArtifacts({ | |
| owner, repo, run_id: runId | |
| }); | |
| const clientArtifacts = artifactList.artifacts | |
| .filter(a => a.name.startsWith('client-')) | |
| .map(a => ({ | |
| name: a.name, | |
| url: `https://github.com/${owner}/${repo}/actions/runs/${runId}/artifacts/${a.id}`, | |
| size: a.size_in_bytes | |
| })); | |
| core.setOutput('count', clientArtifacts.length); | |
| if (clientArtifacts.length === 0) return; | |
| const platformMap = { 'macos': 'macOS', 'windows': 'Windows', 'linux': 'Linux' }; | |
| const archMap = { 'arm64': 'Apple Silicon', 'x64': 'x64' }; | |
| const typeLabels = { | |
| 'dmg': 'DMG 安装包', 'app': 'App 应用', | |
| 'msi': 'MSI 安装包', 'exe': 'EXE 安装程序', | |
| 'appimage': 'AppImage', 'deb': 'Deb 包' | |
| }; | |
| const platformOrder = ['macos', 'windows', 'linux']; | |
| const archOrder = ['arm64', 'x64']; | |
| clientArtifacts.sort((a, b) => { | |
| const [aP, aA] = a.name.replace('client-', '').split('-'); | |
| const [bP, bA] = b.name.replace('client-', '').split('-'); | |
| return (platformOrder.indexOf(aP) - platformOrder.indexOf(bP)) | |
| || (archOrder.indexOf(aA) - archOrder.indexOf(bA)); | |
| }); | |
| let rows = ''; | |
| for (const a of clientArtifacts) { | |
| const parts = a.name.replace('client-', '').split('-'); | |
| const p = platformMap[parts[0]] || parts[0]; | |
| const arch = archMap[parts[1]] || parts[1]; | |
| const type = typeLabels[parts.slice(2).join('-')] || parts.slice(2).join('-'); | |
| rows += `| ${p} | ${arch} | ${type} | [下载](${a.url}) |\n`; | |
| } | |
| core.setOutput('rows', rows); | |
| - name: Comment client artifacts | |
| if: steps.collect.outputs.count > 0 | |
| uses: TDesignOteam/workflows/actions/maintain-one-comment@main | |
| with: | |
| token: ${{ secrets.BOT_TOKEN }} | |
| body: | | |
| ### 💻 Client 构建产物 | |
| | 平台 | 架构 | 产物类型 | 下载 | | |
| |------|------|----------|------| | |
| ${{ steps.collect.outputs.rows }} | |
| > ⏰ 产物保留 5 天 | |
| <!-- AUTO_PREVIEW_CLIENT --> | |
| number: ${{ needs.get-pr-id.outputs.pr_id }} | |
| body-include: '<!-- AUTO_PREVIEW_CLIENT -->' | |
| # ── VSCode Plugin: 收集链接 + 评论 ── | |
| comment-vscode: | |
| needs: get-pr-id | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Collect vscode artifact | |
| id: collect | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| const runId = ${{ github.event.workflow_run.id }}; | |
| const { data: artifactList } = await github.rest.actions.listWorkflowRunArtifacts({ | |
| owner, repo, run_id: runId | |
| }); | |
| const vscode = artifactList.artifacts.find(a => a.name === 'vscode-plugin-vsix'); | |
| if (vscode) { | |
| const url = `https://github.com/${owner}/${repo}/actions/runs/${runId}/artifacts/${vscode.id}`; | |
| core.setOutput('found', 'true'); | |
| core.setOutput('url', url); | |
| } else { | |
| core.setOutput('found', 'false'); | |
| } | |
| - name: Comment vscode plugin artifact | |
| if: steps.collect.outputs.found == 'true' | |
| uses: TDesignOteam/workflows/actions/maintain-one-comment@main | |
| with: | |
| token: ${{ secrets.BOT_TOKEN }} | |
| body: | | |
| ### 🔌 VSCode Plugin 构建产物 | |
| [下载 .vsix](${{ steps.collect.outputs.url }}) | |
| > ⏰ 产物保留 5 天 | |
| <!-- AUTO_PREVIEW_VSCODE --> | |
| number: ${{ needs.get-pr-id.outputs.pr_id }} | |
| body-include: '<!-- AUTO_PREVIEW_VSCODE -->' |