Introduction¶
A HarmonyOS release typically involves a chain of error-prone steps: signing checks, version verification, release packaging, Bugly symbol table upload, AppGallery Connect (AGC) upload, and finally submission for review. Delegating this flow directly to the DSH Agent carries obvious risks—it needs to read certificates and keys and write to the online AGC (uploading packages, submitting). If parameters are misconfigured by the model, the cost is high.
The existing practice is to write these steps into scripts or Codex skills (harmony-agc-publish), placing credentials in .agc_env / .bugly_env within the project. The model gets indiscriminate execution permissions. This plugin adds a layer between the two: following the skill’s pipeline but collecting credentials in the DSH credential database, reclaiming all online write actions for manual approval, and recording every change as an audit log.
Below is an introduction to angchow/xrxs-dsh-harmony-publish, maintained by AngChow. It is categorized as admin-security in the community directory, displays 0 stars on the directory page, is currently at version 0.2.1, uses the MIT license, and only supports macOS.
What is this¶
A DeepSeek Harness (DSH) plugin: exposing the HarmonyOS release pipeline (signing check → version verification → devecocli packaging → Bugly symbol table → upload AGC → submit review) from the harmony-agc-publish Codex skill to the DSH Agent in a secure, auditable way.
It does not create a new flow but maps the already validated steps in the skill into tools and scripts within the plugin, wrapping them with credential parsing, environment isolation, redaction, and approval. The plugin comes with a client-side UI, rendering the 5 tools as release cards on the desktop/Web, showing the product, release mode, 7-step progress, and warnings directly on the page.
Prerequisites: Target DSH version >=0.2.0-rc.1 <0.3.0-0 (from engines.dsh); Platform macOS (AGC upload and submission are darwin-only); Build dependency devecocli. It shares the same security model and tool shape as xrxs-dsh-android-publish, facilitating parallel maintenance for both platforms.
Release Modes and Write Surface¶
Three modes, expanding the write surface incrementally:
| mode | Behavior | Write Surface |
|---|---|---|
buildOnly |
Signing check + Build + Bugly symbol table | Local + Bugly only |
upload |
Above + Version check + Upload AGC package | Local + Bugly + AGC Draft state |
submit |
Above + app-submit submission |
Local + Bugly + AGC Online Review Process |
The default allowedModes are only buildOnly and upload; submit needs to be explicitly enabled. This means even if the model gets the tool started, it won’t reach submission without configured authorization.
Five Tools and Client Interface¶
The tools registered for the model are as follows:
| Tool | Purpose |
|---|---|
harmony_publish_doctor |
Health Check: Python/requests, Java, devecocli, project structure, release certificates and Profile, Bugly jar, credential configuration status (reports status only, never reports values) |
harmony_publish_plan |
Generate deterministic release plan (validates mode/project/path/credentials, does not execute) |
harmony_publish_preflight |
Run pre_check.py (signing status + on-shelf version comparison), no build or upload |
harmony_publish_start |
Start background tasks for build/upload/submit; upload and submit both go through approval cards |
harmony_publish_status |
Non-consumptive read of task status and redacted output |
The status tool reads the steps returned by the subprocess, restoring the completion, failure, or skip status of the 7 steps: “Preflight → Signing → Version → Build → Bugly Symbol Table → Upload AGC → Submit Review”. Card data travels via the structured channel of output.presentationMeta. The client reads block.meta instead of parsing model-visible text; it falls back to displaying the original text if meta is missing in old sessions. Approval cards are still rendered by the host userQuestions (plan-review); the plugin is only responsible for the title and body.
Installation¶
For the desktop DSH, it is recommended to use the Plugin Manager: hand over the repository directory, or xrxs-dsh-harmony-publish-<version>.tgz from Releases, to the DSH plugin installation entry. The profile’s package.json / cordis.patch.yml are maintained by the installation action, do not write them manually.
When building manually:
pnpm install
pnpm run build # artifacts in lib/, not committed
pnpm pack # generates xrxs-dsh-harmony-publish-<version>.tgz
For the CLI method, add the plugin directly by local absolute path:
dsh plugin --profile <name> add /absolute/path/to/xrxs-dsh-harmony-publish
dsh --profile <name> --dump-config # check configuration
One thing must be noted: @deepseek-ai/dsh-* must never appear in this plugin’s dependencies; they are provided by the host. Once copied into the profile’s node_modules, two instances of the tool scheduler Symbol will appear in the process, causing all tool calls in that instance to fail.
Configuration¶
The plugin’s configuration file is written in the profile overlay, covering by id (whole object replacement, not deep merge). Below is an example from the README, where projectRoot, bundleName, keystore, and JAVA_HOME paths are the author’s local setup, replace according to your project:
- 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
Meanings of a few configuration items:
allowSubmit: Master switch for submission, defaultfalse, change totrueonly when submission is needed. After changing, the tool will force a popup approval card.symbolPolicy:required= interrupt on symbol table upload failure/missing;optional= warn only on failure;disabled= skip entirely. Defaultoptional.allowedModes: Allowed release modes.requireManagedCredentialSource: Defaulttrue, meaning credentials must come from the managed libraryfile.
Only these 8 keys are allowed in plainEnv: AGC_APP_ID, DEVECO_CLI, DEVECO_HOME, HARMONY_KEYSTORE_DIR, HARMONY_RELEASE_PROFILE, HARMONY_RELEASE_CERT, BUGLY_JAR_PATH, JAVA_HOME. Credential-like variables cannot appear here and must be pointed to via credentialRefs to the DSH credential database:
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: "..."
The default managed library path is ~/.dsh/.credentials.yaml. It also supports ~/.dsh/.env as a read-only fallback, but when requireManagedCredentialSource: true, submission requires the source to be a managed file (file). Call harmony_publish_doctor after configuration to see if each ref is configured (values are not displayed).
Typical Usage¶
The calling order given in the README is: doctor → preflight → start → poll:
harmony_publish_doctor { profileId }— Confirm Python/Java/devecocli/certificates/credentials are in place.harmony_publish_preflight { profileId }— Confirm signing status and “local version > on-shelf version”, this step does not build or upload.harmony_publish_start { profileId, mode, remark }— Start background tasks after approval.harmony_publish_status { jobId }— Poll progress and redacted logs.
When mode: submit, the user must click “Confirm Submission” on the approval card; if rejected, no AGC write operations will occur.
Old scripts (Python scripts under resources/scripts/) can also be used independently as a CLI. In this case, load_agc_env() / load_bugly_env() will still read .agc_env / .bugly_env in the project; when driven by the plugin, the plugin side always sets HARMONY_PUBLISH_DISABLE_PROJECT_ENV=1, causing the script to return directly upon encountering this variable, making clear credentials unreachable.
Script exit codes are fixed and can be used directly to determine which step failed:
| Script | 0 | 1 | 2 | 3 |
|---|---|---|---|---|
pre_check.py |
Pass | Blocking issue exists | AGC query failed | — |
check_version.py |
Local > On-shelf | Version not upgraded | AGC query failed | — |
check_signing.py |
Already released / Switched | Cannot switch safely | — | dry-run and requires switch |
build_and_submit.py |
Full flow success | Step failed | Submit safety lock not satisfied | — |
submit_review.py |
Submission success | Submission failed | Safety lock not satisfied | — |
Security Model¶
Several key designs worth reviewing one by one before writing plugin configuration.
-
Zero credential exposure.
AGC_CLIENT_ID/AGC_CLIENT_SECRET/BUGLY_APP_ID/BUGLY_APP_KEYare only resolved from the DSH credential database (credentialRefs→ ref name) on every operation, injected only into the subprocess environment. Model-visible output, task buffers, and audit logs are all precisely redacted via substring masking. Credential values never appear in argv. -
Model cannot pass arbitrary flags or credentials. Environment keys use a whitelist; secret-like keys can only go through
credentialRefs; others go throughplainEnv;--skip-*,--i-know-this-submits-to-production,HARMONY_CONFIRM_SUBMIT=YESare all derived from profile policy and approval results, not directly specified by the model. -
Three gates. Submission requires
allowSubmit: true+ pre-check pass + user clicking “Confirm Submission” on the approval card. If any is missing, nothing starts. The submission safety lock is--i-know-this-submits-to-production+HARMONY_CONFIRM_SUBMIT=YES, isomorphic to the skill, with the variable prefix changed toHARMONY. -
Signing switch fail-closed. Only rewrite
build-profile.json5when the target product’ssigningConfigcan be precisely located. If it cannot be safely located, report error and hand to manual.storeFile(.p12) is never modified. -
Audit.
<runtimeDir>/audit.ndjsonrecordspreflight/start/approval_denied/complete/failed/cancelled.
Differences from Codex skill¶
To summarize, avoid blindly copying skill habits:
- Credentials are injected from the DSH database; the plugin mode does not read
.agc_env/.bugly_env. - Signing check is split into “read-only determination” (
pre_check.py) and “writable switch” (check_signing.py),pre_check.pynever modifies files. - Dual signing config only changes the target product’s
signingConfig, safe even when multiple products share a debug config name. - Bugly jar search order:
BUGLY_JAR_PATH→resources/tools/→~/.dsh/harmony-publish/toolscache →BUGLY_JAR_SEARCH_DIRS(colon-separated, can point to Codex skill’stools/) → download (can override withBUGLY_JAR_URL). Official download links may expire; it is recommended to keep a local jar in the cache directory. - When
symbolPolicy: required, “no symbol table available to upload” counts as a failure (fail-closed).
In terms of directory structure, src/ is the host plugin implementation (tool registration, credential parsing, redaction, tasks), resources/python/plugin_runner.py is the subprocess redaction wrapper, resources/scripts/ are the release scripts that can run independently as CLI, locale/{en,zh}.json is the plugin manager’s display metadata, and tests are under tests/ using vitest.
Scenarios and Notes¶
Suitable for those already using DSH who want to hand HarmonyOS releases to an Agent but don’t want it to directly hold clear credentials to write online. Also suitable for Android teams using xrxs-dsh-android-publish who want both platforms to maintain the same security model and tool shape.
Points to note:
- The plugin runs with the permissions of the current dsh process. Read the source code and confirm the license (MIT) before installing, don’t install blindly.
- Environment only supports macOS, build dependency
devecocli, Java, Python/requests, and keystore paths must be in place beforehand, useharmony_publish_doctorto self-check. - Submission is the only operation this plugin performs on online data. Keeping
allowSubmitasfalseis the norm, only enable it when confirming you want to submit. - After upgrading the host DSH version, you need to re-run
pnpm buildto generatelib/client.js, otherwise the client card might not match the new host. - The directory page shows 0 stars, it is a new repository; it is recommended to run
vitestand the localbuildOnlyflow yourself before adopting.
Conclusion¶
The value of this plugin is not in new features, but in adding a layer of guardrails to existing release scripts: credentials go into the database, not argv; online write actions must pass approval; every step is audited; while retaining the original flow and exit code semantics of the skill. Configuration is one-time; afterwards, the 4 steps (doctor, preflight, start, poll) can be connected with tools.
Directory Page: https://www.skillhub.cn/plugins/AngChow/xrxs-dsh-harmony-publish
GitHub: https://github.com/AngChow/xrxs-dsh-harmony-publish