name: 'PR Preview: Deploy'
on:
workflow_run:
workflows:
- 'PR Preview: Build'
types:
- completed
permissions:
actions: read
pull-requests: write
jobs:
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
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 -->'
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 -->'
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 -->'