biucingcli 0.9.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. biucingcli/__init__.py +5 -0
  2. biucingcli/cli.py +849 -0
  3. biucingcli/template_data/android/template/.editorconfig +9 -0
  4. biucingcli/template_data/android/template/.gitignore +26 -0
  5. biucingcli/template_data/android/template/.mise.toml +3 -0
  6. biucingcli/template_data/android/template/Brewfile +6 -0
  7. biucingcli/template_data/android/template/Makefile +103 -0
  8. biucingcli/template_data/android/template/README.md +163 -0
  9. biucingcli/template_data/android/template/app/build.gradle.kts +178 -0
  10. biucingcli/template_data/android/template/app/proguard-rules.pro +1 -0
  11. biucingcli/template_data/android/template/app/src/androidTest/java/app/HomeRouteUiTest.kt +21 -0
  12. biucingcli/template_data/android/template/app/src/main/AndroidManifest.xml +18 -0
  13. biucingcli/template_data/android/template/app/src/main/java/app/MainActivity.kt +36 -0
  14. biucingcli/template_data/android/template/app/src/main/res/values/strings.xml +4 -0
  15. biucingcli/template_data/android/template/app/src/main/res/values/themes.xml +8 -0
  16. biucingcli/template_data/android/template/app/src/test/java/app/AppSmokeTest.kt +19 -0
  17. biucingcli/template_data/android/template/build.gradle.kts +27 -0
  18. biucingcli/template_data/android/template/core/designsystem/build.gradle.kts +33 -0
  19. biucingcli/template_data/android/template/core/designsystem/src/main/java/designsystem/Components.kt +75 -0
  20. biucingcli/template_data/android/template/core/designsystem/src/main/java/designsystem/DesignTokens.kt +23 -0
  21. biucingcli/template_data/android/template/core/designsystem/src/main/java/designsystem/Theme.kt +110 -0
  22. biucingcli/template_data/android/template/core/model/build.gradle.kts +26 -0
  23. biucingcli/template_data/android/template/core/model/src/main/java/model/Greeting.kt +6 -0
  24. biucingcli/template_data/android/template/core/model/src/test/java/model/GreetingTest.kt +16 -0
  25. biucingcli/template_data/android/template/core/network/build.gradle.kts +26 -0
  26. biucingcli/template_data/android/template/core/network/src/main/java/network/AppEnvironment.kt +17 -0
  27. biucingcli/template_data/android/template/core/testing/build.gradle.kts +27 -0
  28. biucingcli/template_data/android/template/core/testing/src/main/java/testing/FakeAppEnvironmentProvider.kt +13 -0
  29. biucingcli/template_data/android/template/docs/release-delivery.md +68 -0
  30. biucingcli/template_data/android/template/docs/release-signing.properties.example +20 -0
  31. biucingcli/template_data/android/template/fastlane/.env.example +22 -0
  32. biucingcli/template_data/android/template/fastlane/Appfile +1 -0
  33. biucingcli/template_data/android/template/fastlane/Fastfile +121 -0
  34. biucingcli/template_data/android/template/feature/home/build.gradle.kts +35 -0
  35. biucingcli/template_data/android/template/feature/home/src/main/java/home/HomeRoute.kt +38 -0
  36. biucingcli/template_data/android/template/feature/settings/build.gradle.kts +34 -0
  37. biucingcli/template_data/android/template/feature/settings/src/main/java/settings/SettingsRoute.kt +35 -0
  38. biucingcli/template_data/android/template/gradle/libs.versions.toml +35 -0
  39. biucingcli/template_data/android/template/gradle/verification-metadata.xml +3462 -0
  40. biucingcli/template_data/android/template/gradle/wrapper/gradle-wrapper.jar +0 -0
  41. biucingcli/template_data/android/template/gradle/wrapper/gradle-wrapper.jar.sha256 +1 -0
  42. biucingcli/template_data/android/template/gradle/wrapper/gradle-wrapper.properties +10 -0
  43. biucingcli/template_data/android/template/gradle.properties +4 -0
  44. biucingcli/template_data/android/template/gradlew +252 -0
  45. biucingcli/template_data/android/template/gradlew.bat +94 -0
  46. biucingcli/template_data/android/template/scripts/artifact-info +11 -0
  47. biucingcli/template_data/android/template/scripts/bootstrap +17 -0
  48. biucingcli/template_data/android/template/scripts/doctor +133 -0
  49. biucingcli/template_data/android/template/scripts/setup-android-sdk +23 -0
  50. biucingcli/template_data/android/template/scripts/sync-gradle-wrapper +19 -0
  51. biucingcli/template_data/android/template/scripts/verify-gradle-supply-chain +61 -0
  52. biucingcli/template_data/android/template/scripts/verify-release-artifact +104 -0
  53. biucingcli/template_data/android/template/settings.gradle.kts +25 -0
  54. biucingcli/template_data/android/template.json +146 -0
  55. biucingcli/template_data/apple/template/.gitignore +28 -0
  56. biucingcli/template_data/apple/template/.mise.toml +4 -0
  57. biucingcli/template_data/apple/template/.swiftformat +10 -0
  58. biucingcli/template_data/apple/template/.swiftlint.yml +33 -0
  59. biucingcli/template_data/apple/template/App/Config/ProjectDescriptionHelpers/Module.swift +6 -0
  60. biucingcli/template_data/apple/template/App/Config/XCConfig/Base.xcconfig +4 -0
  61. biucingcli/template_data/apple/template/App/Project.swift +66 -0
  62. biucingcli/template_data/apple/template/App/Targets/App/Resources/.gitkeep +1 -0
  63. biucingcli/template_data/apple/template/App/Targets/App/Sources/AppEntry.swift +9 -0
  64. biucingcli/template_data/apple/template/App/Targets/App/Sources/HomeView.swift +18 -0
  65. biucingcli/template_data/apple/template/App/Targets/App/Sources/HomeViewModel.swift +38 -0
  66. biucingcli/template_data/apple/template/App/Targets/AppTests/Sources/AppTests.swift +59 -0
  67. biucingcli/template_data/apple/template/Brewfile +8 -0
  68. biucingcli/template_data/apple/template/Makefile +128 -0
  69. biucingcli/template_data/apple/template/Packages/AppServices/Package.swift +20 -0
  70. biucingcli/template_data/apple/template/Packages/AppServices/Sources/AppServices/StarterMetadata.swift +52 -0
  71. biucingcli/template_data/apple/template/Packages/DesignSystem/Package.swift +20 -0
  72. biucingcli/template_data/apple/template/Packages/DesignSystem/Sources/DesignSystem/Theme.swift +8 -0
  73. biucingcli/template_data/apple/template/README.md +133 -0
  74. biucingcli/template_data/apple/template/Tuist.swift +8 -0
  75. biucingcli/template_data/apple/template/Workspace.swift +11 -0
  76. biucingcli/template_data/apple/template/docs/release-delivery.md +55 -0
  77. biucingcli/template_data/apple/template/fastlane/.env.example +20 -0
  78. biucingcli/template_data/apple/template/fastlane/Appfile +3 -0
  79. biucingcli/template_data/apple/template/fastlane/Fastfile +126 -0
  80. biucingcli/template_data/apple/template/fastlane/Matchfile +7 -0
  81. biucingcli/template_data/apple/template/scripts/bootstrap +9 -0
  82. biucingcli/template_data/apple/template/scripts/doctor +163 -0
  83. biucingcli/template_data/apple/template/scripts/setup-xcode +6 -0
  84. biucingcli/template_data/apple/template/scripts/test-destination +42 -0
  85. biucingcli/template_data/apple/template/scripts/verify-release-identity +88 -0
  86. biucingcli/template_data/apple/template.json +110 -0
  87. biucingcli/template_data/frontend/template/.dockerignore +8 -0
  88. biucingcli/template_data/frontend/template/.env.example +1 -0
  89. biucingcli/template_data/frontend/template/.gitignore +7 -0
  90. biucingcli/template_data/frontend/template/.npmrc +1 -0
  91. biucingcli/template_data/frontend/template/.prettierignore +2 -0
  92. biucingcli/template_data/frontend/template/.prettierrc.json +4 -0
  93. biucingcli/template_data/frontend/template/Dockerfile +25 -0
  94. biucingcli/template_data/frontend/template/Dockerfile.dev +35 -0
  95. biucingcli/template_data/frontend/template/Dockerfile.dev.full +40 -0
  96. biucingcli/template_data/frontend/template/Makefile +137 -0
  97. biucingcli/template_data/frontend/template/README.md +146 -0
  98. biucingcli/template_data/frontend/template/compose.dev.yaml +29 -0
  99. biucingcli/template_data/frontend/template/eslint.config.js +27 -0
  100. biucingcli/template_data/frontend/template/index.html +12 -0
  101. biucingcli/template_data/frontend/template/nginx.conf +11 -0
  102. biucingcli/template_data/frontend/template/package.json +50 -0
  103. biucingcli/template_data/frontend/template/playwright.production.config.ts +21 -0
  104. biucingcli/template_data/frontend/template/playwright.smoke.config.ts +19 -0
  105. biucingcli/template_data/frontend/template/pnpm-lock.yaml +4054 -0
  106. biucingcli/template_data/frontend/template/public/.gitkeep +1 -0
  107. biucingcli/template_data/frontend/template/scripts/browser-smoke-production +55 -0
  108. biucingcli/template_data/frontend/template/scripts/doctor +46 -0
  109. biucingcli/template_data/frontend/template/src/App.test.tsx +18 -0
  110. biucingcli/template_data/frontend/template/src/App.tsx +5 -0
  111. biucingcli/template_data/frontend/template/src/components/MetricCard.tsx +14 -0
  112. biucingcli/template_data/frontend/template/src/components/TaskPanel.tsx +32 -0
  113. biucingcli/template_data/frontend/template/src/config/env.ts +3 -0
  114. biucingcli/template_data/frontend/template/src/hooks/useProjectOverview.ts +24 -0
  115. biucingcli/template_data/frontend/template/src/index.css +208 -0
  116. biucingcli/template_data/frontend/template/src/main.tsx +11 -0
  117. biucingcli/template_data/frontend/template/src/pages/HomePage.tsx +60 -0
  118. biucingcli/template_data/frontend/template/src/router/AppRouter.tsx +14 -0
  119. biucingcli/template_data/frontend/template/src/services/api/client.ts +33 -0
  120. biucingcli/template_data/frontend/template/src/services/projectOverview.ts +39 -0
  121. biucingcli/template_data/frontend/template/src/test/setup.ts +1 -0
  122. biucingcli/template_data/frontend/template/src/types/projectOverview.ts +22 -0
  123. biucingcli/template_data/frontend/template/src/vite-env.d.ts +9 -0
  124. biucingcli/template_data/frontend/template/tests/browser-smoke.spec.ts +16 -0
  125. biucingcli/template_data/frontend/template/tests/production-browser-smoke.spec.ts +22 -0
  126. biucingcli/template_data/frontend/template/tsconfig.json +21 -0
  127. biucingcli/template_data/frontend/template/vite.config.ts +12 -0
  128. biucingcli/template_data/frontend/template.json +81 -0
  129. biucingcli/template_data/harmonyos/template/.gitignore +21 -0
  130. biucingcli/template_data/harmonyos/template/.mise.toml +2 -0
  131. biucingcli/template_data/harmonyos/template/AppScope/app.json5 +10 -0
  132. biucingcli/template_data/harmonyos/template/AppScope/resources/base/element/string.json +8 -0
  133. biucingcli/template_data/harmonyos/template/AppScope/resources/base/media/background.svg +3 -0
  134. biucingcli/template_data/harmonyos/template/AppScope/resources/base/media/foreground.svg +4 -0
  135. biucingcli/template_data/harmonyos/template/AppScope/resources/base/media/layered_image.json +6 -0
  136. biucingcli/template_data/harmonyos/template/Makefile +106 -0
  137. biucingcli/template_data/harmonyos/template/README.md +152 -0
  138. biucingcli/template_data/harmonyos/template/build-profile.json5 +36 -0
  139. biucingcli/template_data/harmonyos/template/code-linter.json5 +12 -0
  140. biucingcli/template_data/harmonyos/template/docs/release-signing.local.properties.example +14 -0
  141. biucingcli/template_data/harmonyos/template/entry/build-profile.json5 +9 -0
  142. biucingcli/template_data/harmonyos/template/entry/hvigorfile.ts +6 -0
  143. biucingcli/template_data/harmonyos/template/entry/oh-package.json5 +9 -0
  144. biucingcli/template_data/harmonyos/template/entry/src/main/ets/core/config/AppConfig.ets +10 -0
  145. biucingcli/template_data/harmonyos/template/entry/src/main/ets/core/designsystem/Tokens.ets +28 -0
  146. biucingcli/template_data/harmonyos/template/entry/src/main/ets/entryability/EntryAbility.ets +29 -0
  147. biucingcli/template_data/harmonyos/template/entry/src/main/ets/pages/Index.ets +47 -0
  148. biucingcli/template_data/harmonyos/template/entry/src/main/ets/pages/Settings.ets +96 -0
  149. biucingcli/template_data/harmonyos/template/entry/src/main/module.json5 +34 -0
  150. biucingcli/template_data/harmonyos/template/entry/src/main/resources/base/element/color.json +24 -0
  151. biucingcli/template_data/harmonyos/template/entry/src/main/resources/base/element/string.json +12 -0
  152. biucingcli/template_data/harmonyos/template/entry/src/main/resources/base/media/app_icon.svg +5 -0
  153. biucingcli/template_data/harmonyos/template/entry/src/main/resources/base/profile/main_pages.json +6 -0
  154. biucingcli/template_data/harmonyos/template/entry/src/test/List.test.ets +11 -0
  155. biucingcli/template_data/harmonyos/template/hvigor/hvigor-config.json5 +8 -0
  156. biucingcli/template_data/harmonyos/template/hvigorfile.ts +6 -0
  157. biucingcli/template_data/harmonyos/template/oh-package-lock.json5 +19 -0
  158. biucingcli/template_data/harmonyos/template/oh-package.json5 +13 -0
  159. biucingcli/template_data/harmonyos/template/scripts/artifact-info +31 -0
  160. biucingcli/template_data/harmonyos/template/scripts/bootstrap +38 -0
  161. biucingcli/template_data/harmonyos/template/scripts/doctor +147 -0
  162. biucingcli/template_data/harmonyos/template/scripts/lint +105 -0
  163. biucingcli/template_data/harmonyos/template/scripts/release-build +199 -0
  164. biucingcli/template_data/harmonyos/template/scripts/release-preflight +109 -0
  165. biucingcli/template_data/harmonyos/template/scripts/test +28 -0
  166. biucingcli/template_data/harmonyos/template/scripts/verify-release-artifact +173 -0
  167. biucingcli/template_data/harmonyos/template/scripts/verify-supply-chain +70 -0
  168. biucingcli/template_data/harmonyos/template.json +134 -0
  169. biucingcli/template_data/microservice/template/.air.toml +11 -0
  170. biucingcli/template_data/microservice/template/.dockerignore +5 -0
  171. biucingcli/template_data/microservice/template/.gitignore +4 -0
  172. biucingcli/template_data/microservice/template/.mise.toml +3 -0
  173. biucingcli/template_data/microservice/template/Brewfile +7 -0
  174. biucingcli/template_data/microservice/template/Dockerfile +44 -0
  175. biucingcli/template_data/microservice/template/Dockerfile.dev +50 -0
  176. biucingcli/template_data/microservice/template/Makefile +145 -0
  177. biucingcli/template_data/microservice/template/README.md +191 -0
  178. biucingcli/template_data/microservice/template/api/buf.gen.yaml +11 -0
  179. biucingcli/template_data/microservice/template/api/buf.yaml +11 -0
  180. biucingcli/template_data/microservice/template/api/proto/service/v1/service.proto +18 -0
  181. biucingcli/template_data/microservice/template/cmd/server/main.go +81 -0
  182. biucingcli/template_data/microservice/template/compose.dev.yaml +49 -0
  183. biucingcli/template_data/microservice/template/configs/config.yaml +18 -0
  184. biucingcli/template_data/microservice/template/deploy/compose.yaml +35 -0
  185. biucingcli/template_data/microservice/template/deploy/otel-collector.yaml +15 -0
  186. biucingcli/template_data/microservice/template/go.mod +53 -0
  187. biucingcli/template_data/microservice/template/go.sum +138 -0
  188. biucingcli/template_data/microservice/template/internal/config/config.go +112 -0
  189. biucingcli/template_data/microservice/template/internal/config/config_test.go +92 -0
  190. biucingcli/template_data/microservice/template/internal/handler/health.go +25 -0
  191. biucingcli/template_data/microservice/template/internal/handler/ping.go +25 -0
  192. biucingcli/template_data/microservice/template/internal/model/health.go +8 -0
  193. biucingcli/template_data/microservice/template/internal/model/ping.go +7 -0
  194. biucingcli/template_data/microservice/template/internal/repository/.gitkeep +1 -0
  195. biucingcli/template_data/microservice/template/internal/router/router.go +26 -0
  196. biucingcli/template_data/microservice/template/internal/runtime/server.go +116 -0
  197. biucingcli/template_data/microservice/template/internal/runtime/server_test.go +161 -0
  198. biucingcli/template_data/microservice/template/internal/service/health.go +26 -0
  199. biucingcli/template_data/microservice/template/internal/service/ping.go +23 -0
  200. biucingcli/template_data/microservice/template/internal/telemetry/telemetry.go +56 -0
  201. biucingcli/template_data/microservice/template/internal/transport/grpc.go +51 -0
  202. biucingcli/template_data/microservice/template/internal/transport/ping.go +28 -0
  203. biucingcli/template_data/microservice/template/scripts/bootstrap +29 -0
  204. biucingcli/template_data/microservice/template/scripts/doctor +115 -0
  205. biucingcli/template_data/microservice/template/tests/server_test.go +153 -0
  206. biucingcli/template_data/microservice/template.json +114 -0
  207. biucingcli/template_data/web-service/template/.air.toml +11 -0
  208. biucingcli/template_data/web-service/template/.dockerignore +5 -0
  209. biucingcli/template_data/web-service/template/.gitignore +5 -0
  210. biucingcli/template_data/web-service/template/.mise.toml +2 -0
  211. biucingcli/template_data/web-service/template/Brewfile +5 -0
  212. biucingcli/template_data/web-service/template/Dockerfile +41 -0
  213. biucingcli/template_data/web-service/template/Dockerfile.dev +45 -0
  214. biucingcli/template_data/web-service/template/Makefile +113 -0
  215. biucingcli/template_data/web-service/template/README.md +164 -0
  216. biucingcli/template_data/web-service/template/cmd/server/main.go +50 -0
  217. biucingcli/template_data/web-service/template/compose.dev.yaml +28 -0
  218. biucingcli/template_data/web-service/template/compose.yaml +14 -0
  219. biucingcli/template_data/web-service/template/configs/config.yaml +10 -0
  220. biucingcli/template_data/web-service/template/go.mod +36 -0
  221. biucingcli/template_data/web-service/template/go.sum +89 -0
  222. biucingcli/template_data/web-service/template/internal/config/config.go +84 -0
  223. biucingcli/template_data/web-service/template/internal/config/config_test.go +88 -0
  224. biucingcli/template_data/web-service/template/internal/handler/health.go +25 -0
  225. biucingcli/template_data/web-service/template/internal/handler/ping.go +25 -0
  226. biucingcli/template_data/web-service/template/internal/handler/user.go +40 -0
  227. biucingcli/template_data/web-service/template/internal/model/health.go +6 -0
  228. biucingcli/template_data/web-service/template/internal/model/ping.go +7 -0
  229. biucingcli/template_data/web-service/template/internal/model/user.go +7 -0
  230. biucingcli/template_data/web-service/template/internal/repository/.gitkeep +1 -0
  231. biucingcli/template_data/web-service/template/internal/repository/user.go +37 -0
  232. biucingcli/template_data/web-service/template/internal/router/router.go +28 -0
  233. biucingcli/template_data/web-service/template/internal/runtime/server.go +76 -0
  234. biucingcli/template_data/web-service/template/internal/runtime/server_test.go +139 -0
  235. biucingcli/template_data/web-service/template/internal/service/health.go +22 -0
  236. biucingcli/template_data/web-service/template/internal/service/ping.go +23 -0
  237. biucingcli/template_data/web-service/template/internal/service/user.go +27 -0
  238. biucingcli/template_data/web-service/template/scripts/bootstrap +23 -0
  239. biucingcli/template_data/web-service/template/scripts/doctor +83 -0
  240. biucingcli/template_data/web-service/template/tests/server_test.go +160 -0
  241. biucingcli/template_data/web-service/template.json +88 -0
  242. biucingcli/template_data/worker/template/.dockerignore +3 -0
  243. biucingcli/template_data/worker/template/.gitignore +2 -0
  244. biucingcli/template_data/worker/template/.mise.toml +2 -0
  245. biucingcli/template_data/worker/template/Brewfile +1 -0
  246. biucingcli/template_data/worker/template/Dockerfile +19 -0
  247. biucingcli/template_data/worker/template/Dockerfile.dev +9 -0
  248. biucingcli/template_data/worker/template/Makefile +105 -0
  249. biucingcli/template_data/worker/template/README.md +164 -0
  250. biucingcli/template_data/worker/template/cmd/worker/main.go +41 -0
  251. biucingcli/template_data/worker/template/compose.dev.yaml +29 -0
  252. biucingcli/template_data/worker/template/configs/config.json +11 -0
  253. biucingcli/template_data/worker/template/go.mod +3 -0
  254. biucingcli/template_data/worker/template/go.sum +1 -0
  255. biucingcli/template_data/worker/template/internal/config/config.go +108 -0
  256. biucingcli/template_data/worker/template/internal/config/config_test.go +86 -0
  257. biucingcli/template_data/worker/template/internal/runtime/runner.go +199 -0
  258. biucingcli/template_data/worker/template/internal/runtime/runner_test.go +215 -0
  259. biucingcli/template_data/worker/template/internal/task/heartbeat.go +19 -0
  260. biucingcli/template_data/worker/template/scripts/bootstrap +6 -0
  261. biucingcli/template_data/worker/template/scripts/doctor +41 -0
  262. biucingcli/template_data/worker/template/tests/worker_test.go +44 -0
  263. biucingcli/template_data/worker/template.json +100 -0
  264. biucingcli/templates.py +902 -0
  265. biucingcli-0.9.1.dist-info/METADATA +204 -0
  266. biucingcli-0.9.1.dist-info/RECORD +269 -0
  267. biucingcli-0.9.1.dist-info/WHEEL +5 -0
  268. biucingcli-0.9.1.dist-info/entry_points.txt +2 -0
  269. biucingcli-0.9.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,199 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ HVIGOR_BIN="${HVIGOR:-hvigorw}"
5
+ MODULE_NAME="{{HARMONY_MODULE_NAME}}"
6
+ BUILD_PROFILE="build-profile.json5"
7
+ BACKUP_DIR=".biucing/release"
8
+ BACKUP_PROFILE="${BACKUP_DIR}/build-profile.json5.backup"
9
+ GENERATED_PROFILE="${BACKUP_DIR}/build-profile.json5.generated"
10
+ RESTORE_PROFILE="${BACKUP_DIR}/build-profile.json5.restore"
11
+ BUILD_MARKER="${BACKUP_DIR}/release-build.started"
12
+
13
+ if [[ ! -f "local.properties" ]]; then
14
+ cat >&2 <<'EOF'
15
+ local.properties is missing.
16
+
17
+ Copy docs/release-signing.local.properties.example to local.properties and fill in
18
+ your HarmonyOS signing material before running make release.
19
+ EOF
20
+ exit 1
21
+ fi
22
+
23
+ ./scripts/verify-supply-chain
24
+ ./scripts/release-preflight
25
+
26
+ if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1 || \
27
+ ! git ls-files --error-unmatch "$BUILD_PROFILE" >/dev/null 2>&1; then
28
+ echo "$BUILD_PROFILE must be tracked in a Git repository before a signed release." >&2
29
+ exit 1
30
+ fi
31
+
32
+ if ! git diff --quiet -- "$BUILD_PROFILE" || ! git diff --cached --quiet -- "$BUILD_PROFILE"; then
33
+ echo "$BUILD_PROFILE has staged or unstaged changes." >&2
34
+ echo "Commit or stash those changes before running a signed release." >&2
35
+ exit 1
36
+ fi
37
+
38
+ if ORIGINAL_MODE="$(stat -f '%Lp' "$BUILD_PROFILE" 2>/dev/null)"; then
39
+ :
40
+ else
41
+ ORIGINAL_MODE="$(stat -c '%a' "$BUILD_PROFILE")"
42
+ fi
43
+
44
+ umask 077
45
+ mkdir -p "$BACKUP_DIR"
46
+ cp -p "$BUILD_PROFILE" "$BACKUP_PROFILE"
47
+ chmod 600 "$BACKUP_PROFILE"
48
+
49
+ restore_build_profile() {
50
+ local original_status=$?
51
+ local restore_status=0
52
+
53
+ trap - EXIT HUP INT TERM
54
+ rm -f "$GENERATED_PROFILE" "$RESTORE_PROFILE" "$BUILD_MARKER"
55
+
56
+ if [[ -f "$BACKUP_PROFILE" ]]; then
57
+ if cp -p "$BACKUP_PROFILE" "$RESTORE_PROFILE" && \
58
+ mv -f "$RESTORE_PROFILE" "$BUILD_PROFILE" && chmod "$ORIGINAL_MODE" "$BUILD_PROFILE"; then
59
+ if cmp -s "$BACKUP_PROFILE" "$BUILD_PROFILE"; then
60
+ rm -f "$BACKUP_PROFILE"
61
+ rmdir "$BACKUP_DIR" 2>/dev/null || true
62
+ else
63
+ echo "Failed to verify restoration of $BUILD_PROFILE; backup retained at $BACKUP_PROFILE." >&2
64
+ restore_status=1
65
+ fi
66
+ else
67
+ echo "Failed to restore $BUILD_PROFILE; backup retained at $BACKUP_PROFILE." >&2
68
+ restore_status=1
69
+ fi
70
+ fi
71
+
72
+ if [[ "$restore_status" -ne 0 ]]; then
73
+ exit "$restore_status"
74
+ fi
75
+ exit "$original_status"
76
+ }
77
+ trap restore_build_profile EXIT
78
+ trap 'exit 129' HUP
79
+ trap 'exit 130' INT
80
+ trap 'exit 143' TERM
81
+
82
+ BUILD_PROFILE_PATH="$BUILD_PROFILE" GENERATED_PROFILE_PATH="$GENERATED_PROFILE" node <<'NODE'
83
+ const fs = require('fs');
84
+ const path = require('path');
85
+
86
+ const localPropertiesPath = 'local.properties';
87
+ const buildProfilePath = process.env.BUILD_PROFILE_PATH;
88
+ const generatedProfilePath = process.env.GENERATED_PROFILE_PATH;
89
+ const requiredKeys = [
90
+ 'biucing.harmony.signing.certpath',
91
+ 'biucing.harmony.signing.profile',
92
+ 'biucing.harmony.signing.storeFile',
93
+ 'biucing.harmony.signing.storePassword',
94
+ 'biucing.harmony.signing.keyAlias',
95
+ 'biucing.harmony.signing.keyPassword'
96
+ ];
97
+
98
+ function parseProperties(raw) {
99
+ const values = {};
100
+ for (const line of raw.split(/\r?\n/)) {
101
+ const trimmed = line.trim();
102
+ if (!trimmed || trimmed.startsWith('#')) {
103
+ continue;
104
+ }
105
+ const separator = trimmed.indexOf('=');
106
+ if (separator < 0) {
107
+ continue;
108
+ }
109
+ const key = trimmed.slice(0, separator).trim();
110
+ const value = trimmed.slice(separator + 1).trim();
111
+ values[key] = value;
112
+ }
113
+ return values;
114
+ }
115
+
116
+ const properties = parseProperties(fs.readFileSync(localPropertiesPath, 'utf8'));
117
+ const missing = requiredKeys.filter((key) => !properties[key]);
118
+ if (missing.length > 0) {
119
+ console.error(`Missing signing key(s) in ${localPropertiesPath}:`);
120
+ for (const key of missing) {
121
+ console.error(` - ${key}`);
122
+ }
123
+ process.exit(1);
124
+ }
125
+
126
+ for (const key of [
127
+ 'biucing.harmony.signing.certpath',
128
+ 'biucing.harmony.signing.profile',
129
+ 'biucing.harmony.signing.storeFile'
130
+ ]) {
131
+ const value = properties[key];
132
+ const resolved = path.isAbsolute(value) ? value : path.resolve(value);
133
+ if (!fs.existsSync(resolved)) {
134
+ console.error(`Signing file for ${key} does not exist: ${value}`);
135
+ process.exit(1);
136
+ }
137
+ }
138
+
139
+ const buildProfile = JSON.parse(fs.readFileSync(buildProfilePath, 'utf8'));
140
+ const material = {
141
+ certpath: properties['biucing.harmony.signing.certpath'],
142
+ profile: properties['biucing.harmony.signing.profile'],
143
+ storeFile: properties['biucing.harmony.signing.storeFile'],
144
+ storePassword: properties['biucing.harmony.signing.storePassword'],
145
+ keyAlias: properties['biucing.harmony.signing.keyAlias'],
146
+ keyPassword: properties['biucing.harmony.signing.keyPassword'],
147
+ signAlg: properties['biucing.harmony.signing.signAlg'] || 'SHA256withECDSA'
148
+ };
149
+
150
+ buildProfile.app.signingConfigs = [
151
+ {
152
+ name: 'release',
153
+ type: 'HarmonyOS',
154
+ material
155
+ }
156
+ ];
157
+ for (const product of buildProfile.app.products || []) {
158
+ product.signingConfig = 'release';
159
+ }
160
+
161
+ fs.writeFileSync(generatedProfilePath, `${JSON.stringify(buildProfile, null, 2)}\n`, { mode: 0o600 });
162
+ console.log('Injected release signing config from local.properties.');
163
+ NODE
164
+
165
+ mv -f "$GENERATED_PROFILE" "$BUILD_PROFILE"
166
+
167
+ touch "$BUILD_MARKER"
168
+ "$HVIGOR_BIN" assembleHap --mode module -p "module=${MODULE_NAME}" -p buildMode=release
169
+ release_artifact="$(MODULE_BUILD_ROOT="${MODULE_NAME}/build" BUILD_MARKER_PATH="$BUILD_MARKER" node <<'NODE'
170
+ const fs = require('fs');
171
+ const path = require('path');
172
+ const markerTime = fs.statSync(process.env.BUILD_MARKER_PATH).mtimeMs;
173
+ const candidates = [];
174
+
175
+ function visit(directory) {
176
+ if (!fs.existsSync(directory)) return;
177
+ for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
178
+ const candidate = path.join(directory, entry.name);
179
+ if (entry.isDirectory()) {
180
+ visit(candidate);
181
+ } else if (entry.isFile() && candidate.endsWith('.hap')) {
182
+ const modified = fs.statSync(candidate).mtimeMs;
183
+ if (modified > markerTime) candidates.push({ candidate, modified });
184
+ }
185
+ }
186
+ }
187
+
188
+ visit(process.env.MODULE_BUILD_ROOT);
189
+ candidates.sort((left, right) => right.modified - left.modified);
190
+ if (candidates.length > 0) process.stdout.write(candidates[0].candidate);
191
+ NODE
192
+ )"
193
+ if [[ -z "$release_artifact" ]]; then
194
+ echo "Release build did not produce a new HAP artifact." >&2
195
+ exit 1
196
+ fi
197
+ ./scripts/verify-release-artifact "$release_artifact"
198
+
199
+ echo "Release build finished. Restoring build-profile.json5."
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ echo "HarmonyOS release signing preflight"
5
+
6
+ node <<'NODE'
7
+ const fs = require('fs');
8
+
9
+ const buildProfilePath = 'build-profile.json5';
10
+ let buildProfile;
11
+ try {
12
+ buildProfile = JSON.parse(fs.readFileSync(buildProfilePath, 'utf8'));
13
+ } catch (_error) {
14
+ console.error(`${buildProfilePath} is missing or is not valid JSON.`);
15
+ process.exit(1);
16
+ }
17
+
18
+ const signingConfigs = buildProfile?.app?.signingConfigs;
19
+ const containsPasswordField = (value) => {
20
+ if (Array.isArray(value)) {
21
+ return value.some(containsPasswordField);
22
+ }
23
+ if (!value || typeof value !== 'object') {
24
+ return false;
25
+ }
26
+
27
+ return Object.entries(value).some(([key, child]) => {
28
+ if ((key === 'storePassword' || key === 'keyPassword') && String(child || '').length > 0) {
29
+ return true;
30
+ }
31
+ return containsPasswordField(child);
32
+ });
33
+ };
34
+
35
+ if (!Array.isArray(signingConfigs) || signingConfigs.length > 0 || containsPasswordField(buildProfile)) {
36
+ console.error(`${buildProfilePath} contains signing material.`);
37
+ console.error('Restore the committed unsigned build profile before running a release.');
38
+ process.exit(1);
39
+ }
40
+ NODE
41
+
42
+ if [[ ! -f "local.properties" ]]; then
43
+ cat >&2 <<'EOF'
44
+ local.properties is missing.
45
+
46
+ Copy docs/release-signing.local.properties.example to local.properties and fill in
47
+ your HarmonyOS signing material before running make release.
48
+ EOF
49
+ exit 1
50
+ fi
51
+
52
+ node <<'NODE'
53
+ const fs = require('fs');
54
+ const path = require('path');
55
+
56
+ const localPropertiesPath = 'local.properties';
57
+ const requiredKeys = [
58
+ 'biucing.harmony.signing.certpath',
59
+ 'biucing.harmony.signing.profile',
60
+ 'biucing.harmony.signing.storeFile',
61
+ 'biucing.harmony.signing.storePassword',
62
+ 'biucing.harmony.signing.keyAlias',
63
+ 'biucing.harmony.signing.keyPassword'
64
+ ];
65
+ const fileKeys = [
66
+ 'biucing.harmony.signing.certpath',
67
+ 'biucing.harmony.signing.profile',
68
+ 'biucing.harmony.signing.storeFile'
69
+ ];
70
+
71
+ function parseProperties(raw) {
72
+ const values = {};
73
+ for (const line of raw.split(/\r?\n/)) {
74
+ const trimmed = line.trim();
75
+ if (!trimmed || trimmed.startsWith('#')) {
76
+ continue;
77
+ }
78
+ const separator = trimmed.indexOf('=');
79
+ if (separator < 0) {
80
+ continue;
81
+ }
82
+ const key = trimmed.slice(0, separator).trim();
83
+ const value = trimmed.slice(separator + 1).trim();
84
+ values[key] = value;
85
+ }
86
+ return values;
87
+ }
88
+
89
+ const properties = parseProperties(fs.readFileSync(localPropertiesPath, 'utf8'));
90
+ const missing = requiredKeys.filter((key) => !properties[key]);
91
+ if (missing.length > 0) {
92
+ console.error(`Missing signing key(s) in ${localPropertiesPath}:`);
93
+ for (const key of missing) {
94
+ console.error(` - ${key}`);
95
+ }
96
+ process.exit(1);
97
+ }
98
+
99
+ for (const key of fileKeys) {
100
+ const value = properties[key];
101
+ const resolved = path.isAbsolute(value) ? value : path.resolve(value);
102
+ if (!fs.existsSync(resolved)) {
103
+ console.error(`Signing file for ${key} does not exist: ${value}`);
104
+ process.exit(1);
105
+ }
106
+ }
107
+
108
+ console.log('Release signing material is present and file paths resolve.');
109
+ NODE
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ HVIGOR_BIN="${HVIGOR:-hvigorw}"
5
+ MODULE_NAME="{{HARMONY_MODULE_NAME}}"
6
+
7
+ echo "Running HarmonyOS ArkTS unit tests with hvigor..."
8
+
9
+ if [[ ! -f "entry/src/test/List.test.ets" ]]; then
10
+ cat >&2 <<'EOF'
11
+ entry/src/test/List.test.ets is missing.
12
+
13
+ Keep at least one Hypium test suite in the generated project before treating
14
+ the project as release-ready.
15
+ EOF
16
+ exit 1
17
+ fi
18
+
19
+ if [[ ! -d "oh_modules/@ohos/hypium" && ! -d "entry/oh_modules/@ohos/hypium" ]]; then
20
+ cat >&2 <<'EOF'
21
+ @ohos/hypium is not installed.
22
+
23
+ Run make bootstrap before make test so ohpm can install test dependencies.
24
+ EOF
25
+ exit 1
26
+ fi
27
+
28
+ "$HVIGOR_BIN" test --mode module -p "module=${MODULE_NAME}"
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ EXPECTED_BUNDLE_NAME="{{BUNDLE_NAME}}"
5
+ properties_path="local.properties"
6
+ keytool_bin="${KEYTOOL:-keytool}"
7
+
8
+ property_value() {
9
+ local key="$1"
10
+ awk -F= -v expected="$key" '
11
+ $0 !~ /^[[:space:]]*#/ && $1 ~ "^[[:space:]]*" expected "[[:space:]]*$" {
12
+ sub(/^[^=]*=/, ""); sub(/^[[:space:]]+/, ""); sub(/[[:space:]]+$/, ""); print; exit
13
+ }
14
+ ' "$properties_path"
15
+ }
16
+
17
+ fingerprint_from_certificate() {
18
+ LC_ALL=C "$keytool_bin" -printcert -file "$1" 2>/dev/null \
19
+ | sed -nE 's/.*SHA-?256:[[:space:]]*([0-9A-Fa-f:]+).*/\1/p' \
20
+ | head -n 1 \
21
+ | tr '[:lower:]' '[:upper:]' \
22
+ | tr -d ':[:space:]'
23
+ }
24
+
25
+ find_sign_tool() {
26
+ if [[ -n "${HAP_SIGN_TOOL:-}" ]]; then
27
+ printf '%s' "$HAP_SIGN_TOOL"
28
+ return
29
+ fi
30
+ local sdk_root="${DEVECO_SDK_HOME:-${HOS_SDK_HOME:-${OHOS_SDK_HOME:-}}}"
31
+ local candidate
32
+ for candidate in \
33
+ "$sdk_root/default/openharmony/toolchains/lib/hap-sign-tool.jar" \
34
+ "/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/lib/hap-sign-tool.jar"; do
35
+ if [[ -f "$candidate" ]]; then
36
+ printf '%s' "$candidate"
37
+ return
38
+ fi
39
+ done
40
+ }
41
+
42
+ artifact_path="${1:-}"
43
+ if [[ -z "$artifact_path" ]]; then
44
+ artifact_path="$(find "{{HARMONY_MODULE_NAME}}/build" -type f -name '*.hap' -print 2>/dev/null | sort | tail -n 1)"
45
+ fi
46
+
47
+ echo "HarmonyOS release artifact signature verification"
48
+
49
+ if [[ -z "$artifact_path" || ! -s "$artifact_path" ]]; then
50
+ echo "Signed HAP artifact is missing or empty." >&2
51
+ exit 1
52
+ fi
53
+ if ! unzip -tqq "$artifact_path"; then
54
+ echo "HAP archive validation failed: $artifact_path" >&2
55
+ exit 1
56
+ fi
57
+ if [[ ! -f "$properties_path" ]]; then
58
+ echo "$properties_path is required to verify the expected signer and profile." >&2
59
+ exit 1
60
+ fi
61
+ if ! command -v "$keytool_bin" >/dev/null 2>&1 && [[ ! -x "$keytool_bin" ]]; then
62
+ echo "keytool is required to compare signing certificate fingerprints." >&2
63
+ exit 1
64
+ fi
65
+
66
+ cert_path="$(property_value biucing.harmony.signing.certpath)"
67
+ profile_path="$(property_value biucing.harmony.signing.profile)"
68
+ for variable_name in cert_path profile_path; do
69
+ value="${!variable_name:-}"
70
+ if [[ -z "$value" ]]; then
71
+ echo "Missing signing property for $variable_name." >&2
72
+ exit 1
73
+ fi
74
+ if [[ "$value" != /* ]]; then
75
+ printf -v "$variable_name" '%s' "$PWD/$value"
76
+ fi
77
+ if [[ ! -f "${!variable_name}" ]]; then
78
+ echo "Configured signing input does not exist: ${!variable_name}" >&2
79
+ exit 1
80
+ fi
81
+ done
82
+
83
+ sign_tool="$(find_sign_tool)"
84
+ if [[ -z "$sign_tool" || ( ! -f "$sign_tool" && ! -x "$sign_tool" ) ]]; then
85
+ echo "hap-sign-tool is unavailable. Set HAP_SIGN_TOOL or DEVECO_SDK_HOME." >&2
86
+ exit 1
87
+ fi
88
+
89
+ verification_dir="$(mktemp -d "${TMPDIR:-/tmp}/biucing-hap-verify.XXXXXX")"
90
+ chmod 700 "$verification_dir"
91
+ out_certchain="$verification_dir/certificate-chain.cer"
92
+ out_profile="$verification_dir/profile.p7b"
93
+ profile_result="$verification_dir/profile-verification.json"
94
+ cleanup() {
95
+ rm -f "$out_certchain" "$out_profile" "$profile_result"
96
+ rmdir "$verification_dir" 2>/dev/null || true
97
+ }
98
+ trap cleanup EXIT HUP INT TERM
99
+
100
+ if [[ "$sign_tool" == *.jar ]]; then
101
+ java -jar "$sign_tool" verify-app \
102
+ -inFile "$artifact_path" \
103
+ -outCertChain "$out_certchain" \
104
+ -outProfile "$out_profile" \
105
+ -inForm zip >/dev/null
106
+ else
107
+ "$sign_tool" verify-app \
108
+ -inFile "$artifact_path" \
109
+ -outCertChain "$out_certchain" \
110
+ -outProfile "$out_profile" \
111
+ -inForm zip >/dev/null
112
+ fi
113
+
114
+ if [[ ! -s "$out_certchain" || ! -s "$out_profile" ]]; then
115
+ echo "hap-sign-tool did not export a signer certificate chain and profile." >&2
116
+ exit 1
117
+ fi
118
+
119
+ expected_fingerprint="$(fingerprint_from_certificate "$cert_path")"
120
+ actual_fingerprint="$(fingerprint_from_certificate "$out_certchain")"
121
+ if [[ -z "$expected_fingerprint" || -z "$actual_fingerprint" ]]; then
122
+ echo "Unable to read the configured or embedded signer certificate fingerprint." >&2
123
+ exit 1
124
+ fi
125
+ if [[ "$actual_fingerprint" != "$expected_fingerprint" ]]; then
126
+ echo "HAP signer certificate does not match the configured release certificate." >&2
127
+ echo "expected: $expected_fingerprint" >&2
128
+ echo "actual: $actual_fingerprint" >&2
129
+ exit 1
130
+ fi
131
+ if ! cmp -s "$profile_path" "$out_profile"; then
132
+ echo "HAP embedded signing profile does not match the configured release profile." >&2
133
+ exit 1
134
+ fi
135
+
136
+ if [[ "$sign_tool" == *.jar ]]; then
137
+ java -jar "$sign_tool" verify-profile -inFile "$out_profile" -outFile "$profile_result" >/dev/null
138
+ else
139
+ "$sign_tool" verify-profile -inFile "$out_profile" -outFile "$profile_result" >/dev/null
140
+ fi
141
+ if [[ ! -s "$profile_result" ]]; then
142
+ echo "hap-sign-tool did not produce a verified profile result." >&2
143
+ exit 1
144
+ fi
145
+ EXPECTED_BUNDLE_NAME="$EXPECTED_BUNDLE_NAME" PROFILE_RESULT="$profile_result" node <<'NODE'
146
+ const fs = require('fs');
147
+ const result = JSON.parse(fs.readFileSync(process.env.PROFILE_RESULT, 'utf8'));
148
+ const found = [];
149
+ function visit(value) {
150
+ if (Array.isArray(value)) {
151
+ value.forEach(visit);
152
+ } else if (typeof value === 'string' && value.trim().startsWith('{')) {
153
+ try { visit(JSON.parse(value)); } catch (_error) { /* not an embedded JSON object */ }
154
+ } else if (value && typeof value === 'object') {
155
+ for (const [key, child] of Object.entries(value)) {
156
+ if (key.toLowerCase().replace(/[-_.]/g, '') === 'bundlename') {
157
+ found.push(String(child));
158
+ }
159
+ visit(child);
160
+ }
161
+ }
162
+ }
163
+ visit(result);
164
+ if (!found.includes(process.env.EXPECTED_BUNDLE_NAME)) {
165
+ console.error('Verified HAP profile bundle identity does not match the template release bundle.');
166
+ console.error(`expected: ${process.env.EXPECTED_BUNDLE_NAME}`);
167
+ console.error(`actual: ${found.length > 0 ? found.join(', ') : '<missing>'}`);
168
+ process.exit(1);
169
+ }
170
+ NODE
171
+
172
+ echo "HAP signature is valid; signer and embedded profile match local release inputs."
173
+ echo "Bundle: $EXPECTED_BUNDLE_NAME"
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ echo "HarmonyOS ohpm supply-chain verification"
5
+
6
+ node <<'NODE'
7
+ const fs = require('fs');
8
+
9
+ const manifestPath = 'oh-package.json5';
10
+ const lockPath = 'oh-package-lock.json5';
11
+ const allowedRegistryPrefix = 'https://ohpm.openharmony.cn/ohpm/';
12
+ const failures = [];
13
+
14
+ function load(path) {
15
+ try {
16
+ return JSON.parse(fs.readFileSync(path, 'utf8'));
17
+ } catch (_error) {
18
+ failures.push(`${path} is missing or is not valid JSON.`);
19
+ return {};
20
+ }
21
+ }
22
+
23
+ const manifest = load(manifestPath);
24
+ const lock = load(lockPath);
25
+ const declared = { ...(manifest.dependencies || {}), ...(manifest.devDependencies || {}) };
26
+ const specifiers = lock.specifiers || {};
27
+ const packages = lock.packages || {};
28
+
29
+ if (lock.lockfileVersion !== 3) {
30
+ failures.push(`${lockPath} must use lockfileVersion 3.`);
31
+ }
32
+ if (lock?.meta?.stableOrder !== true) {
33
+ failures.push(`${lockPath} must enable meta.stableOrder.`);
34
+ }
35
+
36
+ for (const [name, version] of Object.entries(declared)) {
37
+ if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(String(version))) {
38
+ failures.push(`${name} must use an exact version; found ${version}.`);
39
+ continue;
40
+ }
41
+ const key = `${name}@${version}`;
42
+ if (specifiers[key] !== key) {
43
+ failures.push(`${key} is not pinned by lockfile specifiers.`);
44
+ }
45
+ if (!packages[key]) {
46
+ failures.push(`${key} is missing from lockfile packages.`);
47
+ }
48
+ }
49
+
50
+ for (const [key, pkg] of Object.entries(packages)) {
51
+ if (!/^sha512-[A-Za-z0-9+/]+={0,2}$/.test(String(pkg.integrity || ''))) {
52
+ failures.push(`${key} is missing a valid sha512 integrity value.`);
53
+ }
54
+ if (!String(pkg.resolved || '').startsWith(allowedRegistryPrefix)) {
55
+ failures.push(`${key} resolves outside the approved ohpm registry.`);
56
+ }
57
+ if (pkg.registryType !== 'ohpm') {
58
+ failures.push(`${key} must use registryType ohpm.`);
59
+ }
60
+ }
61
+
62
+ if (failures.length > 0) {
63
+ for (const failure of failures) {
64
+ console.error(`[fail] ${failure}`);
65
+ }
66
+ process.exit(1);
67
+ }
68
+
69
+ console.log(`Pinned ${Object.keys(packages).length} package(s) with registry and integrity checks.`);
70
+ NODE