Repository navigation
feat: HarmonyOS support (auth, AGC signing, build, template) - #17
Merged
Merged
Conversation
added 3 commits
September 17, 2026 10:45
Adds a `harmonyos/` subtree to @oniroproject/core so the toolchain can build and sign HarmonyOS apps as well as OpenHarmony ones. A project is HarmonyOS only when a product in build-profile.json5 declares `runtimeOS: "HarmonyOS"`, as DevEco Studio writes. Every other project is OpenHarmony and takes the same code path as before, offline signing included. Project targeting `detectRuntimeOs` reads `runtimeOS` from the named product, else the first one. A missing or unreadable profile means OpenHarmony. SDK resolution The HarmonyOS SDK ships only inside DevEco Studio or the login-gated HarmonyOS command-line tools, so it is located rather than downloaded: `harmonyosSdkPath`, then DevEco Studio's default install location, then `cmdToolsPath` when those tools are the HarmonyOS edition. Both SDK flavours share one layout, so an autodetected candidate must also name itself HarmonyOS in sdk-pkg.json; otherwise the OpenHarmony command-line tools would be accepted and then fail deep inside hvigor. Account sign-in `createHarmonyOsSession` implements the browser sign-in: a loopback callback server with a constant-time secret check, the temp-token exchange, and the session token stored envelope-encrypted under `harmonyosAuthDir`. Accounts from every Huawei region work. Upstream hardcodes the Chinese-mainland hosts and refuses other accounts. Here sign-in starts on the CN page, which redirects to the account's own region; the callback's siteId then selects that region's login and AGC hosts. The host table and the `site` parameter (DE for siteId 7) are what DevEco Studio gets from Huawei's Global Routing Service. Real-name verification is not required. As in DevEco Studio, an account may sign once it has accepted the HUAWEI Developer Basic Service Agreement; `resolveAgcAuth` checks this and never accepts it on the user's behalf. Signing `harmonyOsAutoSign` mirrors DevEco Studio's automatic signing: keystore and CSR via hap-sign-tool, a debug certificate from AGC, registration of any connected devices, a debug provisioning profile naming all of the team's registered devices, then an encrypted signingConfig merged into build-profile.json5. No device needs to be attached when the team already has some registered. Certificates and profiles come from a small per-team quota, so existing material is reused unless it no longer matches the project, team, devices or requested ACL permissions. `shouldRegenerate` is that decision as a pure function, tested directly. Downloaded material is verified before it is written: the certificate chain is in date, the profile was issued for the leaf certificate (by X.509 fingerprint), and the keystore holds the certified key. node-forge parses only RSA certificates while hap-sign-tool generates ECC keys, so the keystore's certificate goes to Node's X.509 parser; tests use real hap-sign-tool keystores as fixtures. The AGC certificate is named oniro_debug_<team>.cer. Upstream shares DevEco Studio's auto_debug_<team>.cer, and regenerating replaces the certificate by name, so the two tools would revoke each other's material. Build and scaffold wiring runHvigorw passes the HarmonyOS SDK as DEVECO_SDK_HOME (not OHOS_BASE_SDK_HOME) and uses the project's hvigorw or the HarmonyOS install's. buildHap installs dependencies with that install's ohpm and points the missing-signature warning at `sign --harmonyos`. getHdcPath falls back to the HarmonyOS SDK's hdc when the OpenHarmony command-line tools are absent. createScaffold writes the `"<version>(<api>)"` SDK label a HarmonyOS template expects. hvigor builds only against the release compileSdkVersion names, so the installed SDK's own release from sdk-pkg.json is preferred over the built-in API table, with a warning when they differ. The new config keys get their ONIRO_HARMONYOS_* environment variables in the CLI's config adapter here, since it maps every ConfigKey exhaustively. The AGC endpoints are private and undocumented. Parts of this subtree are adapted from the MIT-licensed openharmony-sig/deveco-cli; each file names its upstream origin, and packages/core/src/harmonyos/NOTICE.md carries the file map, the deviations and the license text. Signed-off-by: Francesco Pham <francesco.pham1@h-partners.com>
Surfaces the core HarmonyOS support through the CLI.
oniro-app auth login|logout|status|team list
Browser sign-in to a Huawei developer account, needed only for HarmonyOS
signing. The login URL is printed as well as opened, so a headless host
can be signed in from another machine. `status` warns when the account
cannot sign yet, and `--json` reports the region and
developerAgreement.
oniro-app sign --harmonyos [--team-id] [--product] [--force]
Routes to the AppGallery Connect flow instead of the offline one, and
reports how many devices the issued profile names.
Plain `sign` on a HarmonyOS project now fails with the fix rather than
producing a HAP signed with the OpenHarmony development certificate.
That builds fine and then will not install, which is a much worse place
to find out.
oniro-app create --template HarmonyOSApp
Scaffolds an empty HarmonyOS ability. `--sdk` takes the API level of the
installed HarmonyOS SDK.
`build` needs no new flags: it reads the runtime from build-profile.json5.
Verified with an EU account and no device attached: sign-in, session refresh
and team listing succeed; `sign --harmonyos` has AGC issue a certificate and
a debug profile naming the team's 6 devices, hap-sign-tool verify-profile
accepts them, DevEco Studio's own certificate is left intact, and a rerun
reuses the material without writing to AGC.
OpenHarmony behaviour is unchanged: create, sign, sign --bootstrap and build
for the EmptyAbility and NativeCpp templates give the same exit codes, output
(bar hap-sign-tool timestamps) and generated project files as on main, and
both build signed HAPs.
Signed-off-by: Francesco Pham <francesco.pham1@h-partners.com>
…iden tests
A review pass over the HarmonyOS support.
Fixes
- undici 8 requires Node >= 22.19, but both packages declare Node >= 20
and build for node20. Moved to undici 7 (Node >= 20.18.1), and its own
fetch is used with its dispatcher, so the two never come from different
undici versions.
- A browser callback that arrived before `waitForCallback` was called was
dropped, and login then timed out after 10 minutes. `login` awaited the
browser launcher first, and xdg-open without a desktop environment, or
$BROWSER, exits only when the browser does. The callback server now
holds the callback from the start, and the launcher is detached and not
awaited.
- `sign --harmonyos` listed the team's devices in AGC before deciding
whether the existing material could be reused. Connected devices are now
read over hdc first, and AGC is called only when regenerating, as the
README already says; still before anything is deleted.
Simplifications
- Hand-rolled HTTP(S)_PROXY / NO_PROXY resolution and the per-proxy agent
cache are replaced by undici's EnvHttpProxyAgent.
- The token store drops its wrapped data key: the token is encrypted with
the key kept outside the auth directory. Every key was on the same disk,
so the second layer protected nothing the first did not.
Tests
- harmonyOsAutoSign end to end against an in-memory AGC with the real
fixture keystore: issuance, reuse without AGC calls, forced and implied
regeneration, replacing only oniro-app's certificate, team and product
overrides, and the no-device and verification failures.
- hap-sign-tool invocation through a stand-in java, the HTTP client against
a loopback server, buildHap/runHvigorw for HarmonyOS and OpenHarmony
projects with stand-in tools, getHdcPath's HarmonyOS fallback, AGC device
paging, session login/logout/state, and callback-server edge cases.
- CLI: auth status/logout/team list and sign --harmonyos while signed out.
- Token-store tests no longer write a key into the real home directory.
Signed-off-by: Francesco Pham <francesco.pham1@h-partners.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds HarmonyOS support next to OpenHarmony. A project is HarmonyOS only when a product in
build-profile.json5declaresruntimeOS: "HarmonyOS", which DevEco Studio writes. Every other project works exactly as before, and OpenHarmony signing still runs offline.oniro-app auth login|logout|status|team list: signs in to a Huawei developer account in the browser. The token is stored encrypted underONIRO_HARMONYOS_AUTH_DIR. Accounts from any Huawei region work; Huawei's own CLI accepts only CN accounts.oniro-app sign --harmonyos [--team-id] [--product] [--force]: AppGallery Connect issues a debug certificate and profile, the material is checked, and an encryptedsigningConfigis written intobuild-profile.json5. Material that is still valid gets reused. The certificate is namedoniro_debug_<team>.cer, so DevEco Studio's certificate is never revoked.oniro-app buildbuilds HarmonyOS projects against the HarmonyOS SDK (DEVECO_SDK_HOME) with that install's own hvigor and ohpm. The SDK is found in DevEco Studio's default location, in the HarmonyOS command-line tools, or atONIRO_HARMONYOS_SDK_PATH.oniro-app create --template HarmonyOSAppcreates a HarmonyOS project.Parts of
packages/core/src/harmonyos/are adapted from the MIT-licensedopenharmony-sig/deveco-cli.packages/core/src/harmonyos/NOTICE.mdlists each adapted file, what changed and the license text.Review pass (last commit)
undici@8needs Node ≥ 22.19, but the packages declare Node ≥ 20 and CI runs on Node 20. It now usesundici@7with its ownfetch.waitForCallbackwas called got dropped, and login timed out after 10 minutes. This happens whenever the browser launcher exits only when the browser closes (xdg-openwithout a desktop environment, or$BROWSER). The callback server now keeps the callback from the start, and login no longer waits for the launcher.EnvHttpProxyAgentreplaces the hand-writtenHTTP(S)_PROXY/NO_PROXYhandling. The token store no longer wraps a second key, since both keys sat on the same disk.Test plan
npm run typecheck,npm run build,npm test: 431 core tests pass (17 skipped) and 58 CLI tests passharmonyOsAutoSignend to end against an in-memory AGC with the real fixture keystore. Covers issuing, reuse without AGC calls, forced and implied regeneration, replacing only our own certificate, team and product overrides, and the no-device and verification failuresjava; the HTTP client against a loopback server;buildHap/runHvigorwfor HarmonyOS and OpenHarmony projects with stand-in tools; the HarmonyOS fallback ingetHdcPath; AGC device paging; session login, logout and stored state; callback-server edge casesauth status/logout/team listandsign --harmonyoswhile signed outhap-sign-tool verify-profileaccepted them, and a rerun reused the material. OpenHarmonycreate/sign/buildoutput matchesmain🤖 Generated with Claude Code