mcpField
D
deploy-site

deploy-site

github.com/microsoft云与 DevOps1.1k233 次安装今天更新
代码仓库

关于 deploy-site

deploy-site 是用于部署 Power Pages 站点的技能,可将请求分流到 SPA 或非 SPA 工作流,并指导检查、上传和激活。适用于使用 PAC CLI 处理站点部署的 Agent。

主要功能

  1. 01SPA 与非 SPA 工作流分流
  2. 02PAC CLI 与身份验证检查
  3. 03确认目标环境
  4. 04构建并上传 SPA 站点
  5. 05验证部署与激活状态

适用场景

  1. 01部署 Power Pages SPA 站点
  2. 02为非 SPA 站点选择正确工作流
  3. 03上传前检查目标环境

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/microsoft/power-platform-skills --skill deploy-site

安装后在 Claude Code 中输入/deploy-site确认已加载。

附带文件workflows/non-spa-site.md

详细介绍

插件检查:运行 node "${PLUGIN_ROOT}/scripts/check-version.js" — 如果输出了消息,请先向用户展示,再继续。

部署 Power Pages 站点

在运行 SPA 构建、附件或激活逻辑之前,先跳转到正确的部署工作流。

核心原则

  • 先验证再操作:尝试部署之前,务必确认 PAC CLI 是否可用、身份验证状态以及目标环境。
  • 使用 TaskCreate/TaskUpdate:在所有阶段跟踪进度 — 开始任何工作之前,先创建包含所有阶段的待办列表。
  • 未经同意不得更改环境设置:如果部署需要修改环境配置(例如,取消阻止 JavaScript 附件),务必先说明更改内容并取得用户的明确许可。

初始请求: $ARGUMENTS


站点类型路由

先根据明确的请求信号进行分类:

  • React、Vue、Angular、Astro、SPA、代码站点或 powerpages.config.json → SPA 站点
  • 非 SPA、经典、传统、声明式、Enhanced、EDM、Standard 数据模型、.portalconfig, 或 website.yml → 非 SPA 站点

如果请求中没有明确说明,请在当前工作区中搜索:

  • 包含 powerpages.config.json 的 SPA 根目录;
  • 同时包含 .portalconfig/ 和 website.yml 的非 SPA 根目录,包括嵌套的 .powerpages-site/。

排除依赖、构建输出、临时、生成输出和版本控制目录。 使用请求路径和当前目录来确定一个项目。切勿随意选择第一个结果。

🚦 关卡(计划 · deploy-site:0.project-type): 如果 SPA 和非 SPA 站点或多个有效根目录仍然可能,请选择确切的项目。

触发条件: 发现后,项目类型或根目录仍有歧义。 原因: 两种站点类型需要使用互不兼容的 PAC 上传命令。 取消后状态: 无;尚未开始构建或上传。

如果存在歧义,请使用 AskUserQuestion 选择确切的项目根目录和检测到的类型。

  • 非 SPA 站点: 阅读并遵循 ${PLUGIN_ROOT}/skills/deploy-site/workflows/non-spa-site.md。不要继续执行下面的 SPA 阶段。
  • SPA 站点: 继续执行下面的现有工作流。
非 SPA 上传审批

权威标记和提示位于 workflows/non-spa-site.md。 关卡 deploy-site:non-spa-4.permissions-audit 会在上传前处理权限敏感型更改。 关卡 deploy-site:non-spa-5.upload 会在上传前立即审批确切的根目录、环境、网站标识、模型和本地更改摘要。

SPA 站点部署工作流

以下阶段保留现有的 SPA 行为。


阶段 1:验证 PAC CLI

目标:确保 PAC CLI 已安装,且在系统 PATH 中可用

操作:

  1. 创建包含全部 6 个阶段的待办列表(见进度跟踪表格)

  2. 运行 pac help,检查 PAC CLI 是否已安装并在系统 PATH 中可用。

    pac help
    
  3. 如果命令成功:PAC CLI 已安装。继续阶段 2。

  4. 如果命令失败(找不到命令 / 无法识别命令):

    1. 告知用户需要 PAC CLI,但尚未安装。

    2. 使用以下方法从 https://aka.ms/PowerPlatformCLI 获取安装说明:

      • 告诉用户:“PAC CLI 尚未安装。你可以运行以下命令进行安装:”

        dotnet tool install --global Microsoft.PowerApps.CLI.Tool
        
      • 如果 dotnet 也不可用,请引导用户访问 https://aka.ms/PowerPlatformCLI,查看包括 .NET SDK 设置在内的完整安装说明。

    3. 安装后,再次运行 pac help 进行验证。

    4. 如果仍然失败,请停止并让用户手动解决安装问题。

输出:PAC CLI 已安装并通过验证


阶段 2:验证身份验证

目标:确保用户已通过 PAC CLI 完成身份验证,并拥有有效会话

操作:

  1. 运行 pac auth who,检查当前身份验证状态。

    pac auth who
    
  2. 如果已完成身份验证:从输出中提取以下值:

    • 环境名称和URL
    • 环境 ID——Environment ID: 后的 GUID
    • 云——Cloud: 后的值(例如,Public、UsGov、UsGovHigh、UsGovDod、China)

    继续执行阶段 3。

  3. 如果尚未完成身份验证:

    1. 告知用户其尚未通过 PAC CLI 完成身份验证。

    2. 使用 AskUserQuestion 询问环境 URL:

      问题标题选项
      你尚未通过 PAC CLI 完成身份验证。请提供 Power Pages 环境 URL(例如,https://org12345.crm.dynamics.com),以便我为你完成身份验证。身份验证(通过“Other”输入文本)

      提供两个占位选项以引导用户:

      • “我会粘贴 URL”(说明:“在下方选择‘Other’,然后粘贴环境 URL”)
      • “我不知道 URL”(说明:“你可以在 Power Platform 管理中心的‘环境 > 你的环境 > 环境 URL’下找到它”)
    3. 用户提供 URL 后,运行身份验证命令:

      pac auth create --environment "<USER_PROVIDED_URL>"
      

      这将打开浏览器窗口,供用户登录。

    4. 命令完成后,再次运行 pac auth who 进行验证。

    5. 如果身份验证成功,继续执行阶段 3。

    6. 如果身份验证失败,向用户显示错误并协助排查。

输出:已完成身份验证的 PAC CLI 会话,并已提取环境名称和 URL


阶段 3:确认环境

目标:确保用户要部署到正确的目标环境

操作:

🚦 关卡(同意 · deploy-site:3.confirm-env): 回显当前环境,并在上传前要求用户明确确认。本关卡也涵盖同一部分中的后续“选择其他环境”子提示——部署到错误环境是此技能中最常见的共享状态破坏性故障,因此即使 PAC CLI 显示的是可识别的环境,也必须触发此关卡。

触发条件: 进入阶段 3;已从 PAC CLI 确定环境。 询问原因: 网站被上传到错误的租户或环境——提交到了用户无意使用的 Dataverse 实例;清理需要手动删除,或从其他环境重新部署。 取消后的状态: 无——尚未触发上传。

  1. 向用户显示当前环境信息,并请其确认。

    使用 AskUserQuestion,采用以下结构:

    问题标题选项
    你当前连接到环境:<ENV_NAME>(<ENV_URL>)。要部署到此环境吗?环境是,使用此环境;否,让我选择其他环境
  2. 如果选择“是,使用此环境”:继续执行阶段 4。

  3. 如果选择“否,让我选择其他环境”:

    1. 运行 pac org list,获取所有可用环境:

      pac org list
      
    2. 解析输出,提取环境名称和 URL。

    3. 使用 AskUserQuestion 将可用环境作为选项展示(最多选择 4 个最相关的环境,或允许用户自行指定)。

    4. 用户选择环境后,切换到该环境:

      pac org select --environment "<SELECTED_ENV_ID_OR_URL>"
      
    5. 再次运行 pac auth who,验证环境切换。

输出:已确认的部署目标环境


阶段 4:部署 SPA 网站

目标:定位项目、构建项目并上传到 Power Pages

操作:

4.1 定位项目根目录

确定项目根目录。项目根目录是包含 powerpages.config.json 的目录。使用 Glob 搜索:

**/powerpages.config.json

🚦 Gate(plan · deploy-site:4.1.multi-project): 找到多个 powerpages.config.json 候选项 — 选择要部署的项目。

触发条件: Phase 4.1 的 glob 返回了多个匹配项。 询问原因: 上传了错误的项目 — 会将其他站点的文件混入目标环境。 取消后: 不会有任何影响 — 尚未开始上传。

如果在当前工作目录或其子目录中找到该文件,请将对应目录用作 PROJECT_ROOT。如果找到多个,请使用 AskUserQuestion 询问用户要部署哪一个。

如果未找到,请要求用户提供项目根目录的路径。

4.2 提供权限审计(仅限重新部署)

如果 .powerpages-site 已存在(即这不是首次部署),表权限和站点设置可能已经与上次部署以来的代码不一致。请在部署前提供审计选项。

🚦 Gate(plan · deploy-site:4.2.audit-permissions): 检测到重新部署 — 提供运行 /audit-permissions 的选项,以便在推送前检查代码与表权限之间是否存在差异。

触发条件: .powerpages-site 已存在(不是首次部署)。 询问原因: 过时的权限 YAML 会被部署,导致用户遇到 403 错误,直到下次运行审计。 取消后: 不会有任何影响 — 审计为只读操作;选择跳过后将继续构建并上传。

使用 AskUserQuestion:

问题标题选项
此站点之前已部署过。是否要运行权限审计,验证表权限是否与当前代码相符,然后再部署?审计是,审计权限(推荐);跳过 — 权限已是最新

如果选择“是”:调用 /audit-permissions 运行审计。审计完成后,从步骤 4.3 继续。 如果选择“跳过”:继续执行步骤 4.3。

如果 .powerpages-site 不存在(首次部署),则跳过此步骤 — 没有现有权限需要审计。

4.3 构建站点

上传前,请确保已构建站点:

cd "<PROJECT_ROOT>"
npm run build

如果构建失败,请停止操作并协助用户修复构建错误,然后再重试。

4.4 上传到 Power Pages

运行上传命令:

pac pages upload-code-site --rootPath "<PROJECT_ROOT>"

如果上传成功:继续执行 Phase 5,验证部署。

如果上传失败:检查错误消息:

  • 如果失败与 JavaScript(.js)附件被阻止有关 → 继续执行 Phase 6
  • 如果错误提到 当前禁止使用 .html 类型附件 → 这是一个误导性错误。请参阅下文的故障排除:HTML 附件被阻止错误
  • 对于其他错误 → 向用户展示错误并协助排查

输出:站点已构建并上传到 Power Pages


Phase 5:验证部署

目标:确认部署成功并处理部署后的步骤

操作:

5.1 验证 .powerpages-site 文件夹

确认 .powerpages-site 存在,并列出其内容(web-roles/、site-settings/、table-permissions/)。

5.2 记录技能使用情况

参考:${PLUGIN_ROOT}/references/skill-tracking-reference.md

按照参考文档中的技能跟踪说明,记录此技能的使用情况。使用 --skillName "DeploySite"。

5.3 确认上传结果

检查 Phase 4(或 Phase 6 重试)中的 pac pages upload-code-site 命令输出。确认命令报告上传成功且没有错误。

5.4 提交更改

暂存并提交部署产物:

git add -A
git commit -m "Deploy site to Power Pages"
5.5 检查激活状态

运行激活状态检查:

node "${PLUGIN_ROOT}/scripts/check-activation-status.js" --projectRoot "<PROJECT_ROOT>"

评估 JSON 结果:

  • 如果 activated 为 true:告知用户其网站已激活(如果存在 websiteUrl,则显示该网址)。继续执行步骤 5.6,然后跳转到建议后续步骤。不要询问是否激活。
  • 如果 activated 为 false:继续执行步骤 5.5.1。
  • 如果存在 error:转到步骤 5.5.1。不要阻止部署流程。
5.5.1 询问是否激活(仅当网站尚未激活时)

🚦 关卡(plan · deploy-site:5.5.1.activate): 网站已部署但尚未激活 — 提议调用 /activate-site 来配置子域名。

触发条件: 第 5.5 阶段在全新部署中检测到 activated:false。 询问原因: 自动激活会写入错误的子域名(该子域名对网站来说是永久的);自动跳过则会导致网站没有可访问的 URL。 取消后状态: 无 — 未调用激活 API。

使用 AskUserQuestion 询问用户是否要激活网站:

问题标题选项
网站已成功部署!您想现在激活(配置)网站,以便获得可访问的 URL 吗?激活立即激活(推荐)— 为网站配置子域名并使其上线;暂时跳过 — 我稍后激活

如果选择“立即激活”:调用 /activate-site 技能。激活完成后,继续执行步骤 5.6 以清除网站缓存。 如果选择“暂时跳过”:建议后续步骤(参见建议后续步骤)。

5.6 清除网站缓存(仅在已激活时)

确认网站已激活后(无论是步骤 5.5 中网站已处于激活状态,还是用户刚在步骤 5.5.1 中激活了网站),都应提议清除运行时缓存,以便立即显示已部署的更改。

前提条件:网站必须已激活,并且必须知道项目根目录(来自第 4.1 阶段)。

🚦 关卡(plan · deploy-site:5.6.restart-cache): 重启已部署的网站以清除其运行时缓存。会造成短暂的生产环境停机(几秒钟)— 即使此操作可恢复,也必须征得用户明确同意。

触发条件: 已确认网站处于激活状态(之前已激活,或刚在步骤 5.5.1 中激活)。 询问原因: 缓存 TTL 到期前,生产环境用户可能会看到几分钟的旧内容。 取消后状态: 无 — 部署本身已成功;缓存会自行刷新。

继续前,使用 AskUserQuestion 征求确认:

问题标题选项
您想重启网站,以便立即显示最新更改吗?这可能会导致短暂停机(几秒钟)。重启是,重启网站(推荐);跳过 — 我稍后重启

如果选择“跳过”:跳转到建议后续步骤。

如果选择“是”:运行清除缓存脚本,并传入项目根目录:

node "${PLUGIN_ROOT}/scripts/clear-site-cache.js" --projectRoot "<PROJECT_ROOT>"

该脚本从 powerpages.config.json 读取 siteName,通过 Power Platform API 查找网站,然后重启网站以清除运行时缓存。

评估结果:

  • 如果 success 为 true:告知用户:“网站缓存已清除 — 您的最新更改现在应已显示在 。”
  • 如果 success 为 false:警告用户缓存清除失败,并显示错误,但不要阻止部署流程。部署本身已成功;缓存最终会自行刷新。如有需要,建议用户在 Power Pages 管理中心手动清除缓存。

输出:已验证部署、已提交更改、已提供激活选项、已清除缓存


第 6 阶段:处理被阻止的 JavaScript

目标:解决 JavaScript 附加被阻止的错误并重试部署

操作:

6.1 说明问题

告知用户:

“上传失败,因为 Power Pages 环境禁止附加 JavaScript(.js)文件。这是一项用于阻止上传 .js 文件的安全设置。要部署 SPA 网站,需要放宽对 .js 文件的限制。”

6.2 请求许可

🚦 Gate(同意 · deploy-site:6.2.unblock-js): 修改 blockedattachments — 具有破坏性的共享状态更改(影响整个租户的环境设置)。与 deploy-pipeline:7.6.2.blocked-attachments 相同。

触发条件: 上传失败,并出现 .js 文件被阻止的错误。 请求原因: 自动解除阻止会在未经明确同意的情况下修改租户安全设置,影响整个环境,而不仅仅是此网站。 取消后的状态: 只有在用户批准后,下游步骤部分完成时,才可能出现 attachment-block-modified。在此处直接取消不会留下任何更改 — 原始 blockedattachments 值保持不变。

使用 AskUserQuestion:

问题标题选项
是否要从环境的阻止附加文件列表中移除 JavaScript(.js)文件限制?这是部署 SPA 网站的必要条件。解除 JS 阻止是,移除 .js 限制(推荐);否,不更改环境设置

如果选择“否”:停止操作,并告知用户,若不解除 .js 附件的阻止,就无法继续部署。

如果选择“是”:继续执行 6.3。

6.3 更新阻止的附加文件
  1. 运行 pac env list-settings,获取当前环境设置:

    pac env list-settings
    
  2. 在输出中找到 blockedattachments 属性。其值为以分号分隔的文件扩展名列表(例如,ade;adp;app;asa;ashx;asmx;asp;bas;bat;cdx;cer;chm;class;cmd;com;config;cnt;cpl;crt;csh;der;dll;exe;fxp;hlp;hta;htr;htw;ida;idc;idq;inf;ins;isp;its;js;jse;ksh;lnk;mad;maf;mag;mam;maq;mar;mas;mat;mau;mav;maw;mda;mdb;mde;mdt;mdw;mdz;msc;msh;msh1;msh1xml;msh2;msh2xml;mshxml;msi;msp;mst;ops;pcd;pif;prf;prg;printer;pst;reg;rem;scf;scr;sct;shb;shs;shtm;shtml;soap;stm;tmp;url;vb;vbe;vbs;vsmacros;vss;vst;vsw;ws;wsc;wsf;wsh)。

  3. 从列表中移除 js。解析以分号分隔的值,筛除 js,然后用分号重新连接。

  4. 更新设置:

    pac env update-settings --name blockedattachments --value "<UPDATED_LIST_WITHOUT_JS>"
    
  5. 确认更新成功。

6.4 重试上传

再次运行上传命令:

pac pages upload-code-site --rootPath "<PROJECT_ROOT>"

如果成功:继续执行阶段 5,验证部署。

如果再次失败并出现其他错误,请向用户展示该错误并协助排查。

输出:已解除对 JavaScript 的阻止,且网站已成功部署


故障排查:HTML 附加文件被阻止错误

如果上传失败并出现类似以下错误:

Error: Unable to upload webfile name 'index.html' with record Id <GUID> as '.html' type attachments are currently blocked on this environment.

此错误具有误导性。 .html 扩展名实际上并未被阻止 — 真正的原因是 .powerpages-site 文件夹中的环境清单文件已过时。此清单会将本地文件映射到 Dataverse 记录 ID。如果映射已过期(例如,在环境更改或记录删除后),上传就会失败,并显示此令人困惑的错误。

修复方法
  1. 在 .powerpages-site 文件夹中找到特定于环境的清单文件。其命名格式为 <environment-host>-manifest.yml(例如,demo1.crm.dynamics.com-manifest.yml)。使用文件搜索工具(例如,使用模式 <PROJECT_ROOT>/.powerpages-site/*-manifest.yml 调用 Glob)查找该文件。

  2. 删除 <PROJECT_ROOT>/.powerpages-site/<environment-host>-manifest.yml 处的清单文件。

  3. 重试上传:

    pac pages upload-code-site --rootPath "<PROJECT_ROOT>"
    

如果重试成功,继续执行阶段 5。如果失败并出现其他错误,请向用户展示该错误并协助排查。

重要: 请勿尝试在环境的阻止附加文件列表中解除对 .html 的阻止 — 此错误并非由附加文件阻止设置导致。


建议的后续步骤

如果用户跳过激活(或激活完成后),请建议:

  • /activate-site — 为网站配置子域名并使其上线(如果尚未激活)
  • /test-site — 在浏览器中测试已部署的网站(确认页面能否加载,检查 API 调用)
  • /audit-permissions — 根据当前代码审计表权限(建议在重新部署后执行)
  • /setup-datamodel — 为动态内容创建 Dataverse 表
  • /add-seo — 添加 meta 标签、robots.txt、sitemap.xml 和 favicon

重要说明

绝不要使用 pac pages upload

始终使用 pac pages upload-code-site——绝不要使用 pac pages upload。pac pages upload 命令专为 portal-studio 风格的网站设计,如果用于 SPA 网站项目,会损坏 SPA 网站元数据。本技能中的每个上传步骤(阶段 4.4、阶段 6.4 和故障排除重试)都适用此规则。

所有阶段中
  • 使用 TaskCreate/TaskUpdate 跟踪每个阶段的进度
  • 在关键决策点征求用户确认(见下方列表)
  • 清楚地展示错误——命令失败时,向用户显示相关错误输出,并在建议修复方法前说明问题所在
关键决策点(等待用户确认)
  1. 阶段 2 之后:如果尚未通过身份验证,请向用户获取环境 URL
  2. 阶段 3:确认或切换目标环境
  3. 阶段 4.1:如果找到多个 powerpages.config.json,询问要部署哪个项目
  4. 阶段 4.2:现在审计权限还是跳过(仅适用于重新部署)
  5. 阶段 5.5:现在激活网站还是稍后激活
  6. 阶段 6:修改被阻止的附件设置前,请先征得许可
进度跟踪

开始阶段 1 之前,使用 TaskCreate 创建包含所有阶段的任务列表:

任务主题activeForm说明
验证 PAC CLI 安装正在验证 PAC CLI检查是否已安装 PAC CLI;如果没有,则进行安装
验证身份验证正在验证身份验证检查当前身份验证状态;如有需要,进行身份验证
确认目标环境正在确认环境显示当前环境,让用户确认或切换
部署 SPA 网站正在部署网站定位项目根目录、构建项目,并通过 pac pages upload-code-site 上传
验证部署正在验证部署确认 .powerpages-site 文件夹存在,检查上传输出,提交更改,并提供激活选项
处理被阻止的 JavaScript正在解决 JS 阻止问题如果上传因 JS 被阻止而失败,则提供解除阻止并重试的选项

每项任务开始时通过 TaskUpdate 将其标记为 in_progress,完成后标记为 completed。如果未遇到 JavaScript 阻止问题,阶段 6 可立即标记为 completed。这样用户可以了解进度,并使工作流保持确定性。


从阶段 1 开始:验证 PAC CLI

评论

支持 Markdown