xrxs-dsh-harmony-publish:把鴻蒙發佈流水線安全地交給 DSH Agent

前言

鴻蒙端的一次發版,通常串着一串不能出錯的動作:簽名檢查、版本號校驗、release 打包、Bugly 符號表上傳、AppGallery Connect(AGC)上傳、最後提交審覈。把這套流程交給 DSH Agent 直接跑,風險點很明顯——它要讀證書和密鑰,還要往 AGC 的線上寫入(上傳包、提審)動手,一旦參數被模型編錯,代價不低。

已有的做法是把這些步驟寫成腳本,或者做成 Codex skill(harmony-agc-publish),憑據放在項目裏的 .agc_env / .bugly_env。模型拿到的是無差別的執行權限。這個插件做的是在這兩者之間加一層:沿用 skill 的流水線,但把憑據收進 DSH 憑據庫,把寫線上的動作全部收回人工審批,並把每一步的變化落成審計日誌。

下面介紹 angchow/xrxs-dsh-harmony-publish,由 AngChow 維護,社區目錄歸類爲 admin-security,目錄頁顯示星標 0,當前版本 0.2.1,許可證 MIT,只支持 macOS。

這是什麼

一個 DeepSeek Harness(DSH)插件:把 harmony-agc-publish Codex skill 的鴻蒙發佈流水線(簽名檢查 → 版本校驗 → devecocli 打包 → Bugly 符號表 → 上傳 AGC → 提審)以安全、可審計的方式暴露給 DSH Agent。

它不新建一套流程,而是把 skill 裏已經跑通的步驟映射成插件內的工具和腳本,再在外面套上憑據解析、環境隔離、脫敏和審批。插件附帶一個客戶端半身,在桌面端 / Web 端把 5 個工具渲染成發佈卡片,頁面上直接看到產品、發佈模式、七步進度和警告。

前置條件:目標 DSH 版本 >=0.2.0-rc.1 <0.3.0-0(來自 engines.dsh);平臺 macOS(AGC 上傳與提審僅限 darwin);構建依賴 devecocli。它與 xrxs-dsh-android-publish 共用同一套安全模型與工具形狀,便於兩端並行維護。

發佈模式與寫入面

三個 mode,寫入面逐級擴大:

mode 行爲 寫入面
buildOnly 簽名檢查 + 構建 + Bugly 符號表 僅本地 + Bugly
upload 上述 + 版本校驗 + 上傳 AGC 軟件包 加 AGC 草稿態
submit 上述 + app-submit 提審 加 AGC 線上審覈流程

默認 allowedModes 只有 buildOnly 和 upload,submit 需要顯式打開。這意味着即使模型拿到了啓動工具,沒有配置授權也不會走到提審。

五個工具與客戶端界面

插件註冊給模型的工具如下:

工具 用途
harmony_publish_doctor 體檢:Python/requests、Java、devecocli、工程結構、發佈證書與 Profile、Bugly jar、憑據配置狀態(只報狀態,永不報值)
harmony_publish_plan 生成確定性發佈計劃(校驗模式/工程/路徑/憑據,不執行)
harmony_publish_preflight 跑 pre_check.py(簽名狀態 + 在架版本對比),不構建不上傳
harmony_publish_start 啓動構建/上傳/提審後臺任務;upload 與 submit 都走審批卡片
harmony_publish_status 非消費式讀取任務狀態與脫敏輸出

status 工具讀的是子進程返回的 steps,可以把「預檢 → 簽名 → 版本號 → 構建 → Bugly 符號表 → 上傳 AGC → 提交審覈」七步的完成、失敗、跳過狀態還原出來。卡片數據走 output.presentationMeta 的結構化通道,客戶端讀 block.meta,不解析模型可見文本;舊會話裏沒有 meta 時回退展示原文本。審批卡片仍由宿主 userQuestions 渲染(plan-review),插件只負責標題與正文。

安裝

桌面版 DSH 推薦走插件管理器:把倉庫目錄,或 Releases 裏的 xrxs-dsh-harmony-publish-<version>.tgz,交給 DSH 的插件安裝入口即可。profile 的 package.json / cordis.patch.yml 由安裝動作維護,不要手寫。

需要自行構建時:

pnpm install
pnpm run build      # 產物在 lib/,不入庫
pnpm pack           # 生成 xrxs-dsh-harmony-publish-<version>.tgz

命令行方式直接按本地絕對路徑添加插件:

dsh plugin --profile <name> add /absolute/path/to/xrxs-dsh-harmony-publish
dsh --profile <name> --dump-config      # 檢查組合

有一點必須注意:@deepseek-ai/dsh-* 絕不能出現在本插件的 dependencies 裏,它們由宿主提供。一旦被複制進 profile 的 node_modules,進程內會出現兩份工具調度器 Symbol,該實例下所有工具調用都會失敗。

配置

plugin 的配置文件寫在 profile 覆蓋層,按 id 整行覆蓋(整對象替換,不是深合併)。下面是 README 裏的示例,其中的 projectRoot、bundleName、keystore 與 JAVA_HOME 路徑是作者本機的樣子,按自己工程替換:

- id: xrxs-harmony-publish
  name: xrxs-dsh-harmony-publish
  config:
    pythonExecutable: /opt/homebrew/opt/python@3.11/libexec/bin/python3
    profiles:
      xrxs-harmony:
        displayName: 薪人薪事 鴻蒙
        projectRoot: /Users/ang/workspace_codex/mobile_harmony
        productName: default
        bundleName: com.client.xrxs.app
        allowedModes: [buildOnly, upload, submit]
        allowSubmit: false
        symbolPolicy: optional
        requireManagedCredentialSource: true
        appArtifactGlob: "**/build/outputs/**/*-signed.app"
        credentialRefs:
          AGC_CLIENT_ID: HARMONY_PUBLISH_XRXS_AGC_CLIENT_ID
          AGC_CLIENT_SECRET: HARMONY_PUBLISH_XRXS_AGC_CLIENT_SECRET
          BUGLY_APP_ID: HARMONY_PUBLISH_XRXS_BUGLY_APP_ID
          BUGLY_APP_KEY: HARMONY_PUBLISH_XRXS_BUGLY_APP_KEY
        plainEnv:
          AGC_APP_ID: "109600000000000000"
          DEVECO_CLI: /opt/homebrew/bin/devecocli
          HARMONY_KEYSTORE_DIR: /Users/ang/develop/keystore/harmony
          HARMONY_RELEASE_PROFILE: /Users/ang/develop/keystore/harmony/發佈Profile/Release_Profile.p7b
          HARMONY_RELEASE_CERT: /Users/ang/develop/keystore/harmony/發佈證書/薪人薪事發布證書.cer
          JAVA_HOME: /Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home

幾個配置項的含義:

  • allowSubmit:提審總開關,默認 false,需要提審時才改成 true,改後工具會強制彈審批卡。
  • symbolPolicy:required = 符號表上傳失敗/缺失即中斷;optional = 失敗只警告;disabled = 完全跳過。默認 optional。
  • allowedModes:允許的發佈模式。
  • requireManagedCredentialSource:默認 true,即要求憑據來源爲託管庫 file。

允許寫進 plainEnv 的鍵只有這 8 個:AGC_APP_ID、DEVECO_CLI、DEVECO_HOME、HARMONY_KEYSTORE_DIR、HARMONY_RELEASE_PROFILE、HARMONY_RELEASE_CERT、BUGLY_JAR_PATH、JAVA_HOME。密鑰形變量不允許出現在這裏,只能通過 credentialRefs 指向 DSH 憑據庫:

version: 1
refs:
  HARMONY_PUBLISH_XRXS_AGC_CLIENT_ID: "..."
  HARMONY_PUBLISH_XRXS_AGC_CLIENT_SECRET: "..."
  HARMONY_PUBLISH_XRXS_BUGLY_APP_ID: "..."
  HARMONY_PUBLISH_XRXS_BUGLY_APP_KEY: "..."

默認託管庫路徑是 ~/.dsh/.credentials.yaml。也支持 ~/.dsh/.env 作爲只讀兜底層,但 requireManagedCredentialSource: true 時提審要求來源爲託管文件(file)。配完調用 harmony_publish_doctor,可以看到每個 ref 是否 configured,不會顯示值。

典型用法

README 給的調用順序是體檢 → 預檢 → 啓動 → 輪詢:

1、harmony_publish_doctor { profileId } —— 確認 Python/Java/devecocli/證書/憑據都到位。
2、harmony_publish_preflight { profileId } —— 確認簽名狀態與「本地版本 > 在架版本」,這一步不構建也不上傳。
3、harmony_publish_start { profileId, mode, remark } —— 審批後啓動後臺任務。
4、harmony_publish_status { jobId } —— 輪詢進度與脫敏日誌。

mode: submit 時用戶必須在審批卡片上點「確認提審」;拒絕的話不會有任何 AGC 寫操作。

老腳本(resources/scripts/ 下的 Python 腳本)也可以脫離插件當獨立 CLI 使用,此時 load_agc_env() / load_bugly_env() 仍會讀項目裏的 .agc_env / .bugly_env;插件驅動時插件側始終設置 HARMONY_PUBLISH_DISABLE_PROJECT_ENV=1,腳本遇該變量直接返回,明文憑據不可達。

腳本退出碼是固定的,可以直接用於判斷卡在哪一步:

腳本 0 1 2 3
pre_check.py 通過 存在阻塞問題 AGC 查詢失敗 —
check_version.py 本地 > 在架 版本未升級 AGC 查詢失敗 —
check_signing.py 已是發佈 / 已切換 無法安全切換 — dry-run 且需要切換
build_and_submit.py 全流程成功 某步失敗 submit 安全鎖未滿足 —
submit_review.py 提交成功 提交失敗 安全鎖未滿足 —

安全模型

幾個關鍵設計,寫插件配置前值得逐條看一遍。

1、憑據零暴露。AGC_CLIENT_ID / AGC_CLIENT_SECRET / BUGLY_APP_ID / BUGLY_APP_KEY 只在每次操作時經 DSH 憑據庫解析(credentialRefs → ref 名),只注入子進程環境,模型可見輸出、任務緩衝、審計日誌全部經過精確子串脫敏。憑據值永不出現在 argv 中。

2、模型不能傳任意旗標或憑據。環境鍵走白名單,secret 形只能走 credentialRefs,其餘走 plainEnv;--skip-*、--i-know-this-submits-to-production、HARMONY_CONFIRM_SUBMIT=YES 全部由 profile 策略與審批結果推導,不由模型直接指定。

3、三道閘門。提審需要 allowSubmit: true + 預檢查通過 + 用戶在審批卡片點選「確認提審」,任一缺失則什麼都不啓動。提審安全鎖爲 --i-know-this-submits-to-production 加 HARMONY_CONFIRM_SUBMIT=YES,與 skill 同構,變量名前綴改爲 HARMONY。

4、簽名切換 fail-closed。只在能精確定位目標 product 的 signingConfig 時改寫 build-profile.json5,無法安全定位就報錯交人工,storeFile(.p12)永不修改。

5、審計。<runtimeDir>/audit.ndjson 記錄 preflight / start / approval_denied / complete / failed / cancelled。

與 Codex skill 的差異

梳理一下,避免照搬 skill 的習慣:

  • 憑據從 DSH 憑據庫注入,插件模式下不讀 .agc_env / .bugly_env。
  • 簽名檢查拆成「只讀判定」(pre_check.py)與「可寫切換」(check_signing.py)兩步,pre_check.py 絕不改文件。
  • 雙簽名配置只改目標 product 的 signingConfig,多個 product 共用調試配置名時也安全。
  • Bugly jar 查找順序:BUGLY_JAR_PATH → resources/tools/ → ~/.dsh/harmony-publish/tools 緩存 → BUGLY_JAR_SEARCH_DIRS(冒號分隔,可指向 Codex skill 的 tools/)→ 下載(BUGLY_JAR_URL 可覆蓋)。官方下載鏈接會失效,建議本機放一份 jar 到緩存目錄。
  • symbolPolicy: required 時,「沒有任何符號表可上傳」也算失敗(fail-closed)。

目錄結構上,src/ 是宿主插件實現(工具註冊、憑據解析、脫敏、任務),resources/python/plugin_runner.py 是子進程脫敏包裝器,resources/scripts/ 是可獨立 CLI 運行的發佈腳本,locale/{en,zh}.json 是插件管理器的顯示元數據,測試在 tests/ 下用 vitest。

適用場景與注意

適合已經在用 DSH、想把鴻蒙發版交給 Agent 但不想讓它直接拿着明文憑據寫線上的人。也適合 Android 側在用 xrxs-dsh-android-publish、希望兩套平臺保持同一安全模型和工具形狀的團隊。

需要注意的地方:

  • 插件以當前 dsh 進程的權限運行,安裝前先讀源碼並確認許可證(MIT),別盲裝。
  • 環境只支持 macOS,構建依賴 devecocli,Java、Python/requests、keystore 路徑都要事先就位,用 harmony_publish_doctor 自檢。
  • 提審是本插件唯一動線上數據的操作,把 allowSubmit 保持 false 是常態,只有在確認要走提審時纔打開。
  • 升級宿主 DSH 版本後需要重新 pnpm build 生成 lib/client.js,否則客戶端卡片可能與新宿主不匹配。
  • 目錄頁顯示星標 0,屬於新倉庫,採用前建議自己跑一遍 vitest 和本地 buildOnly 流程。

結尾

這個插件的價值不在新增功能,而在給已有發佈腳本加了一層護欄:憑據進庫不進 argv,寫線上動作必須過審批,每一步都有審計;同時保留了 skill 原有的流程和退出碼語義。配置是一次性的,之後就可以用工具串起體檢、預檢、啓動、輪詢四步。

目錄頁:https://www.skillhub.cn/plugins/AngChow/xrxs-dsh-harmony-publish
GitHub:https://github.com/AngChow/xrxs-dsh-harmony-publish

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜