通过 webhook 触发原生构建
复制一个包含安装步骤和本插件的完整 Markdown 指南的配置提示。
Capgo 构建通常从笔记本电脑或 CI 任务开始。团队从管理控制台 管理控制台,CMS或内部门户常常希望有一个单一 HTTP webhook:在他们自己的UI中按一下一个按钮,一个签名的本地构建就会开始。这一指南展示了标准模式——一个薄的认证HTTP调用到您的code主机,后者运行您已经使用的相同Capgo构建工作流
sequenceDiagram participant Admin as Admin dashboard participant Hook as Webhook endpoint participant CI as GitHub / GitLab participant Capgo as Capgo Build Admin->>Hook: POST /native-build (secret) Hook->>CI: repository_dispatch / pipeline trigger CI->>CI: checkout, npm ci, cap sync CI->>Capgo: build request Capgo-->>CI: signed binary / store upload
您可以 不 需要Capgo公开一个公共的“构建 webhook”。您的CI已经有了签名密钥; webhook的唯一任务是安全地启动CI任务。
前提条件
名为“前提条件”的部分- Capgo构建工作流程 从CI UI 或在推送(GitHub Actions)
- 创建一个细粒度的GitHub令牌、GitLab触发令牌或等效令牌的权限
- 管理员控制台将发送的共享密钥(头部或正文)
选项A — GitHub repository_dispatch (推荐)
标题为“选项A — GitHub repository_dispatch(推荐)”的部分GitHub接受一个已验证的API调用,启动一个监听webhook的工作流程 repository_dispatch.任何可以 POST JSON可以触发它。
1.监听webhook的工作流程
标题为“1.监听webhook的工作流程”验证载荷 在工作流程中,webhook的载荷需要在接收到webhook之前验证 checkout 和任何带有机密信息的步骤之前。 将接受的值通过作业输出 / 环境变量传递 — 不要进行插值 client_payload 直接进入 run: 脚本(脚本注入指南).
name: Capgo Build (Webhook)
on: repository_dispatch: types: [capgo-native-build]
jobs: validate: runs-on: ubuntu-latest outputs: platform: ${{ steps.check.outputs.platform }} mode: ${{ steps.check.outputs.mode }} ref: ${{ steps.check.outputs.ref }} platforms_json: ${{ steps.check.outputs.platforms_json }} steps: - id: check env: RAW_PLATFORM: ${{ github.event.client_payload.platform }} RAW_MODE: ${{ github.event.client_payload.mode }} RAW_REF: ${{ github.event.client_payload.ref }} DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} run: | PLATFORM="${RAW_PLATFORM:-android}" MODE="${RAW_MODE:-release}" REF="${RAW_REF:-$DEFAULT_BRANCH}" case "$PLATFORM" in ios|android|both) ;; *) echo "Invalid platform: $PLATFORM" >&2; exit 1;; esac case "$MODE" in debug|release) ;; *) echo "Invalid mode: $MODE" >&2; exit 1;; esac # Allowlist branches / tags / full SHAs only if [[ ! "$REF" =~ ^(main|master|production|release/[A-Za-z0-9._-]+|[0-9a-f]{40})$ ]]; then echo "Ref not allowlisted: $REF" >&2 exit 1 fi if [ "$PLATFORM" = "both" ]; then PLATFORMS_JSON='["ios","android"]' else PLATFORMS_JSON=$(printf '["%s"]' "$PLATFORM") fi { echo "platform=$PLATFORM" echo "mode=$MODE" echo "ref=$REF" echo "platforms_json=$PLATFORMS_JSON" } >> "$GITHUB_OUTPUT"
build: needs: validate runs-on: ubuntu-latest environment: ${{ needs.validate.outputs.mode == 'release' && 'production' || 'build-debug' }} strategy: fail-fast: false matrix: platform: ${{ fromJSON(needs.validate.outputs.platforms_json) }} steps: - uses: actions/checkout@v4 with: ref: ${{ needs.validate.outputs.ref }}
- uses: actions/setup-node@v6 with: node-version: '24' cache: 'npm'
- run: npm ci - run: npm run build - name: Sync native project env: PLATFORM: ${{ matrix.platform }} run: npx cap sync "$PLATFORM"
- name: Capgo Build env: CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }} BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }} P12_PASSWORD: ${{ secrets.P12_PASSWORD }} CAPGO_IOS_PROVISIONING_MAP: ${{ secrets.CAPGO_IOS_PROVISIONING_MAP }} APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }} APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }} APPLE_KEY_CONTENT: ${{ secrets.APPLE_KEY_CONTENT }} APP_STORE_CONNECT_TEAM_ID: ${{ secrets.APP_STORE_CONNECT_TEAM_ID }} ANDROID_KEYSTORE_FILE: ${{ secrets.ANDROID_KEYSTORE_FILE }} KEYSTORE_KEY_ALIAS: ${{ secrets.KEYSTORE_KEY_ALIAS }} KEYSTORE_KEY_PASSWORD: ${{ secrets.KEYSTORE_KEY_PASSWORD }} KEYSTORE_STORE_PASSWORD: ${{ secrets.KEYSTORE_STORE_PASSWORD }} PLAY_CONFIG_JSON: ${{ secrets.PLAY_CONFIG_JSON }} PLATFORM: ${{ matrix.platform }} MODE: ${{ needs.validate.outputs.mode }} run: | npx @capgo/cli@latest build request com.example.app \ --platform "$PLATFORM" \ --build-mode "$MODE"2. 创建一个 GitHub token
标题:2. 创建一个 GitHub token创建一个细粒度的个人访问令牌(或 GitHub 应用程序安装令牌) 内容:读取和写入 在仓库上(必需的 repository_dispatch)存储它,只在你的后台管理中 — 不要在浏览器中
3. 从您的管理控制台调用 webhook
Section titled “3. 从您的管理控制台调用 webhook”您的后端(不包括用户浏览器)应发送:
curl -X POST \ -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer $GITHUB_TOKEN" \ -H "X-GitHub-Api-Version: 2022-11-28" \ https://api.github.com/repos/OWNER/REPO/dispatches \ -d '{ "event_type": "capgo-native-build", "client_payload": { "platform": "both", "mode": "release", "ref": "main", "requested_by": "admin@example.com" } }'| 字段 | 目的 |
|---|---|
event_type | 目的 types 必须匹配capgo-native-build) |
client_payload.platform | ios, android在工作流程( both |
client_payload.mode | debug 或 release |
client_payload.ref | 或 |
将相同的 JSON POST 与您的管理 UI(“Build native apps”)中的按钮连接起来。 仪表盘只需要到达 您的 后端; 后端持有 GITHUB_TOKEN.
选项 B — 小型代理 webhook(任何主机)
标题:选项 B — 小型代理 webhook(任何主机)如果管理工具只能将 POST 发送到您控制的 URL(Zapier,Make,Cloudflare Worker,Express 路由),在 GitHub 前面放置一个短代理:
// Example Cloudflare Worker / Node handler (sketch)export default { async fetch(request, env) { if (request.method !== 'POST') { return new Response('Method not allowed', { status: 405 }) } if (request.headers.get('x-webhook-secret') !== env.WEBHOOK_SECRET) { return new Response('Unauthorized', { status: 401 }) } const body = await request.json().catch(() => ({})) const platform = body.platform || 'both' const mode = body.mode || 'release' const ref = body.ref || 'main' if (!['ios', 'android', 'both'].includes(platform)) { return new Response('Invalid platform', { status: 400 }) } if (!['debug', 'release'].includes(mode)) { return new Response('Invalid mode', { status: 400 }) } if (!/^(main|master|production|release\/[A-Za-z0-9._-]+|[0-9a-f]{40})$/.test(ref)) { return new Response('Ref not allowlisted', { status: 400 }) } const res = await fetch( `https://api.github.com/repos/${env.GITHUB_OWNER}/${env.GITHUB_REPO}/dispatches`, { method: 'POST', headers: { Accept: 'application/vnd.github+json', Authorization: `Bearer ${env.GITHUB_TOKEN}`, 'X-GitHub-Api-Version': '2022-11-28', }, body: JSON.stringify({ event_type: 'capgo-native-build', client_payload: { platform, mode, ref }, }), }, ) return new Response(res.status === 204 ? 'Build queued' : await res.text(), { status: res.status === 204 ? 200 : res.status, }) },}然后配置管理产品:
| 设置 | 值 |
|---|---|
| URL | https://your-worker.example.com/native-build |
| 方法 | POST |
| 头 | x-webhook-secret: <shared secret> |
| 体 | { "platform": "both", "mode": "release" } |
连接一个 webhook 到一个管理后台的典型形状是:后台存储一个 URL 和一个密钥;Capgo 凭证在 GitHub 动作中。
GitLab Pipeline 触发器
GitLab Pipeline 触发器GitLab 公开 pipeline 触发器令牌 这些令牌是自然的 webhook 目标。
# .gitlab-ci.yml fragmentcapgo_native_webhook: stage: build script: - npm ci && npm run build - npx cap sync "${PLATFORM:-android}" - npx @capgo/cli@latest build request com.example.app --platform "${PLATFORM:-android}" --build-mode "${BUILD_MODE:-release}" rules: - if: '$CI_PIPELINE_SOURCE == "trigger"'在下面创建一个触发令牌 设置 → CI/CD → Pipeline触发令牌,然后从管理员后台:
curl -X POST \ -F token=$GITLAB_TRIGGER_TOKEN \ -F ref=main \ -F "variables[PLATFORM]=android" \ -F "variables[BUILD_MODE]=release" \ https://gitlab.com/api/v4/projects/PROJECT_ID/trigger/pipeline对于两种平台,或者触发两个触发器或者将作业扩展为并行矩阵,类似于GitHub示例。
Bitbucket和Azure
标题为“Bitbucket和Azure”的部分| 平台 | Webhook机制 |
|---|---|
| Bitbucket | Pipeline触发URL 或自定义管道 + 应用密码 POST |
| Azure DevOps | Pipeline 运行 REST API 使用 PAT; 使用手动管道 从 CI UI 触发 |
模式相同:管理员 → 你的机密检查 → 主机 API → Capgo Build 任务
管理员工具的 Payload 检查清单
标题:管理员工具的 Payload 检查清单当仪表板表单构建时,收集至少:
- 平台 — ios / android / both
- 模式 —— debug (QA) 或 release (商店)
- Git 引用 —— 分支或标签来构建
- 执行者 —— 用于审计日志的电子邮件或用户 ID (通过)
client_payload)
可选:在运行后,让 CI 将下载 URL 从 API 发送给管理员 --output-record / build last-output.
安全性
安全性部分- 验证每个 webhook (
x-webhook-secret白名单 - , 和
platform,modeHMAC签名, 或 mTLSref在代理和工作流程中都使用。validate工作流 — 将其client_payload作为未经信任的输入。 - 通过环境变量/工作流输出传递接受的值; 不要将载荷字段插入
run:脚本中。 - 仅在服务器端保留 GitHub/GitLab token。
- 优先使用针对单个仓库的令牌。
- 限制代理的速率; 原生构建耗费构建分钟。
- 上下文: Capgo Builder / 原生云构建产品页面。 角色: 网站副本句子。 见于: 页面原生构建.astro。 消息键 `native_build_builder_build_minutes` (原生构建构建分钟)。
releaseto a protected GitHub Environment (as in the sample) or require an extra confirmation flag checked invalidate.