关于 assemble-ppmplugin
assemble-ppmplugin 面向已准备清单和原生平台二进制文件的开发者。它对照实际构建结果校准清单中的平台声明,再生成并验证 .ppmplugin 成品。
主要功能
- 01核对清单与暂存二进制文件
- 02验证清单规则
- 03打包选定的原生平台文件
- 04检查最终软件包内容
适用场景
- 01打包已构建的 Android 或 iOS 二进制文件
- 02发现缺失或未声明的平台构建产物
- 03生成用于交付或上传的软件包
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ microsoft/ power-platform-skills --skill assemble-ppmplugin安装后在 Claude Code 中输入/assemble-ppmplugin确认已加载。
详细介绍
/assemble-ppmplugin
最后一步:获取标签(/generate-ppmplugin-manifest 生成的 manifest.json)和构建技能生成的二进制文件,将它们打包成单个 <name>.ppmplugin 文件,并验证压缩包中恰好包含正确的项目。输出就是交付物——可供交接或上传的文件。打包前,它会核对清单中声明的平台与实际构建出的二进制文件,确保交付的包不会声称支持其中并未包含的平台。
阅读 shared/ppmplugin-format.md §1,了解此技能生成并验证的包布局。
此技能不会做什么
- 不会编写清单或构建任何二进制文件——它使用先前第三方控制技能暂存的输出(清单 + 构建技能)。
- 不会上传到 Dataverse 或接入 canvas app(第 3 阶段——暂缓)。
- 不会构建任何二进制文件——它会使用构建技能暂存的文件(来自
/build-android-binary的android/<Pascal>Plugin.dex和/或来自/build-ios-binary的ios/<Pascal>Plugin.framework/),并将现有文件打包。
第 1 步——阅读共享文档和前置条件说明
- 阅读
shared/shared-instructions.md和shared/ppmplugin-format.md。 - 前置条件:
jar(随 JDK 一同提供)。打印可见说明块(shared-instructions §9.2):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Prereq check — /assemble-ppmplugin
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🟢 ✓ jar (JDK) available
🟢 1 check passed, 0 failed. Ready to proceed.
如果找不到 jar,立即停止并提示 BLOCKED: jar not found — install a JDK (JDK 17)。
第 2 步 — 核对声明的入口点与暂存的二进制文件(门禁)
已发布包的 manifest.json 必须且只能声明 zip 中实际存在二进制文件的平台。manifest 是根据意图(目标选择)编写的;此步骤会让它与实际情况(实际构建结果)一致。此处是唯一能看到最终二进制文件集合的地方,因此由此处负责确保一致性。
- 读取
ppmplugin/staging/manifest.json;如果不存在,则停止并提示NEEDS_CONTEXT: manifest missing — run /generate-ppmplugin-manifest。读取name,用于输出文件名<name>.ppmplugin(文件名中不包含版本号——版本号在 manifest 的version字段中;封装流水线会从该字段读取版本号。仍需读取version,以便在交付报告中显示)。 - 已声明的平台:是否存在
entrypoints.android?是否存在entrypoints.ios? - 已暂存的二进制文件:
- Android:存在
ppmplugin/staging/android/<dex>,其中<dex>=entrypoints.android.dex。 - iOS:存在
ppmplugin/staging/ios/<framework>.framework/(必须是扁平的.framework,而不是.xcframework——见 §5b),其中<framework>=entrypoints.ios.framework。如果暂存的是.xcframework,则将其作为门禁问题报告——封装 CI 无法处理;重新运行/build-ios-binary,以生成扁平的设备切片框架。
- Android:存在
- 按平台核对:
| 已声明 | 已暂存 | 操作 |
|---|---|---|
| 是 | 是 | 发布 ✓ |
| 是 | 否 | 不匹配 → 门禁(见下文) |
| 否 | 是 | 二进制文件存在,但 manifest 不会将请求路由到它——请说明情况;可选择重新运行 /generate-ppmplugin-manifest 来声明该平台,或将其排除 |
| 否 | 否 | 不属于此包——忽略 |
- 如果没有任何平台同时满足已声明且已暂存,则停止并提示
NEEDS_CONTEXT: no built binary to ship — run a build skill first。
不匹配门禁(已声明但未暂存)。 不要悄悄发布指向缺失二进制文件的 manifest。情况确实不明确(是改变了主意,还是忘了构建),因此应说明情况并通过 AskUserQuestion 询问:
"Manifest declares
<platform>but no<platform>binary is staged."
- 先构建
<platform>— 运行构建技能(/build-android-binary;iOS 则运行/build-ios-binary,仅限 Mac)[通过 Skill 工具调用它——执行,而不是描述]- 不包含
<platform>发布 — 从暂存的manifest.json中移除entrypoints.<platform>,发布已构建的平台- 停止
如果用户选择“不包含该平台发布”,则在继续之前编辑暂存的 manifest.json,移除该入口点。此步骤完成后,manifest 的 entrypoints 集合必须与暂存的二进制文件集合完全一致。
第 3 步 — 最终验证
针对已核对的暂存 manifest.json 重新运行 ppmplugin-format §4 验证规则(它可能已在第 2 步中或手动编辑)。此外,对每个要发布的平台进行交叉检查:
- Android:
entrypoints.android.dex必须与暂存的 DEX 文件名完全一致。 - iOS:
entrypoints.ios.framework必须与暂存的…/<framework>.framework目录名一致;该.framework/必须包含二进制文件、Headers/<framework>.h、Modules/module.modulemap和Info.plist(封装 CI 的要求——/audit-ppmplugin会进行深入检查;如果明显缺少其中任何内容,请在此处标出)。
如果验证失败,则停止并提示 BLOCKED: manifest validation — <rule>,不要生成包。未通过本地兼容性检查的 .ppmplugin 尚未准备好上传。
第 4 步 — 打包并验证
**打包前:**如果输出文件 ppmplugin/<name>.ppmplugin 已存在,切勿静默覆盖——通过 AskUserQuestion 询问:Replace[默认]/ Keep existing(停止,不改动原有包)。只有选择 Replace 后才继续打包。
-
打包清单,以及仅限第 2 步中确认随包分发的平台文件夹。请明确传入这些目录,以免将构建目录(
android-build/、ios-build/)一并打包。jar(JDK)会递归处理目录,因此可以处理 iOS.framework目录树;它在所有操作系统上的行为完全一致——仅 shell 命令有所不同(§5):macOS / Linux(bash):
mkdir -p ppmplugin # list only the shipped platforms, e.g. `android` for Android-only, `android ios` for Both: ( cd ppmplugin/staging && jar cMf "../<name>.ppmplugin" manifest.json android ios )Windows(PowerShell):
New-Item -ItemType Directory -Force ppmplugin | Out-Null Push-Location ppmplugin\staging jar cMf ..\<name>.ppmplugin manifest.json android ios Pop-Location(
-M表示不添加 JAR 清单条目;包内的manifest.json是我们自己的清单。如果不分发某个平台,请从参数列表中删除ios(或android)。)选择 Replace(已在上方确认)后,将覆盖原有包。 -
验证布局——列出内容并断言其与确认后的清单完全一致:
jar tf ppmplugin/<name>.ppmplugin仅包含 Android 的包应恰好包含:
manifest.json android/<Pascal>Plugin.dexBoth 包还会包含
ios/<Pascal>Plugin.framework/…条目(扁平 framework——二进制文件 +Headers/+Modules/module.modulemap+Info.plist)。如果出现以下情况,请停止并报告BLOCKED: unexpected bundle contents(同时提供实际列表):混入了构建目录(android-build/、ios-build/)、出现了多余文件(.DS_Store、META-INF/)、存在ios/<…>.xcframework/(必须是扁平.framework),或声明平台的二进制文件缺失。包中必须且只能包含清单和各入口点的二进制文件。
第 5 步 — 报告
更新 .extension-state.md 中的 ## ppmplugin (third-party controls) 块:Bundle: <name>.ppmplugin assembled <ISO timestamp> (v<version>, platforms: <android[,ios]>)。以可见的围栏代码块形式显示交付物(shared-instructions §9.1,信息展示格式):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
.ppmplugin ready
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ppmplugin/pen-input.ppmplugin (v0.1.4, Android-only)
Contents:
manifest.json
android/PenInputPlugin.dex
Next: /audit-ppmplugin — verify the bundle is upload-ready before shipping it.
(Then: deploy the dispatcher PCF via /publish-pcf-companion, and upload the
.ppmplugin via the wrap wizard — Stage 3, not yet a skill.)
然后通过 AskUserQuestion 提供下一步选项(shared-instructions §9.1——使用 Skill 工具调用所选技能;直接执行,不要描述):
- 运行 /audit-ppmplugin(推荐——最终上传就绪检查:验证器规则 + DEX SDK 泄漏扫描 + iOS framework 检查)
- 运行 /publish-pcf-companion(将调度器 PCF 部署到 Power Platform 环境)
- 暂不操作——我先检查包
(当 /assemble-ppmplugin 作为 /generate-ppmplugin 的内部阶段运行时,协调器会自动调用 /audit-ppmplugin,因此会跳过此步骤。)返回 DONE 和包路径。