初始化项目
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# CI 构建与签名流水线(1.3.11)
|
||||
|
||||
本目录把「命令行构建 → 签名 → 产物归档」固化为可复用脚本与流水线说明。
|
||||
|
||||
## 前置环境
|
||||
|
||||
| 项 | 要求 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| JDK | 17(`JAVA_HOME`) | hvigor 依赖 |
|
||||
| Node | 22.19+ / 24 | hvigor 与 ohpm |
|
||||
| 命令行工具 | `command-line-tools`(hvigorw / ohpm / sdk) | 与 DevEco Studio 版本一致 |
|
||||
| SDK | `DEVECO_SDK_HOME` 指向 SDK 根目录 | 当前 API 24(6.1.1.125) |
|
||||
| 签名材料 | `.p12`、`.cer`、`.p7b` | 由 AGC 申请,只注入 CI 密钥库 |
|
||||
|
||||
## 流水线阶段
|
||||
|
||||
```
|
||||
① 检出代码
|
||||
② ohpm install --all(锁定 lockfile)
|
||||
③ 静态检查:ArkTS 编译 + code-linter(hvigorw 内置)
|
||||
④ 构建:ci/build-hap.ps1 -BuildMode debug|release
|
||||
⑤ 签名:注入签名配置(见 signing.template.json5),hvigorw 重新打包签名
|
||||
⑥ 归档:HAP/APP、mapping、符号表,保留最近 N 次
|
||||
⑦ 分发:上传 AGC(发布通道 / 测试通道)
|
||||
```
|
||||
|
||||
## 本地用法
|
||||
|
||||
```powershell
|
||||
# 只打印命令,不构建
|
||||
powershell -ExecutionPolicy Bypass -File ci\build-hap.ps1 -DryRun
|
||||
|
||||
# 调试构建
|
||||
powershell -ExecutionPolicy Bypass -File ci\build-hap.ps1 -BuildMode debug
|
||||
|
||||
# 发布构建(需先配置 signingConfigs)
|
||||
powershell -ExecutionPolicy Bypass -File ci\build-hap.ps1 -BuildMode release
|
||||
```
|
||||
|
||||
产物定位:`entry\build\<product>\outputs\<product>\*.hap`。
|
||||
|
||||
## 签名配置
|
||||
|
||||
1. 复制 `signing.template.json5` 的 `signingConfigs` 到 `build-profile.json5` 的 `app` 节点;
|
||||
2. 证书与密码通过环境变量/密钥库注入,**不得提交到仓库**;
|
||||
3. 未配置签名时构建仍可成功,但产物为 `*-unsigned.hap`,无法真机安装。
|
||||
|
||||
## 已知问题
|
||||
|
||||
| 现象 | 原因 | 处理 |
|
||||
| --- | --- | --- |
|
||||
| `EPERM: operation not permitted, symlink ...` | hvigor 需要在工作区外创建工具链接;受限沙箱会拒绝 | CI 运行在完整权限环境;本地不要在受限沙箱执行 |
|
||||
| `No signingConfigs profile is configured` | 未配置签名 | 按上节注入签名配置 |
|
||||
| `version ... does not comply with SemVer` | oh-package 版本主版本号为 0 | 模块版本使用 1.x.y |
|
||||
|
||||
## 版本与产物保留
|
||||
|
||||
- `versionCode` 单调递增,`versionName` 语义化;
|
||||
- 每个发布版本归档:HAP、mapping、混淆符号表、构建日志;
|
||||
- 保留策略:最近 10 个版本 + 所有里程碑版本。
|
||||
@@ -0,0 +1,65 @@
|
||||
<#
|
||||
build-hap.ps1 - 命令行构建 HAP(CI 与本地通用)
|
||||
|
||||
用法:
|
||||
powershell -ExecutionPolicy Bypass -File ci\build-hap.ps1 [-BuildMode debug|release] [-Product default] [-SdkHome <SDK 路径>] [-DryRun]
|
||||
|
||||
说明:
|
||||
- 只封装 hvigorw 调用与产物定位,签名由 CI 的独立步骤完成(见 ci/README.md);
|
||||
- -DryRun 只打印将要执行的命令,不触发构建(用于自检与流水线 dry-run)。
|
||||
#>
|
||||
param(
|
||||
[ValidateSet('debug', 'release')][string]$BuildMode = 'debug',
|
||||
[string]$Product = 'default',
|
||||
[string]$SdkHome = 'D:\env\huawei\command-line-tools\sdk',
|
||||
[switch]$DryRun
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$projectRoot = Split-Path -Parent $PSScriptRoot
|
||||
if (-not (Test-Path (Join-Path $projectRoot 'hvigorfile.ts'))) {
|
||||
throw "未找到工程根目录(缺少 hvigorfile.ts): $projectRoot"
|
||||
}
|
||||
if (-not (Test-Path $SdkHome)) {
|
||||
throw "SDK 路径不存在: $SdkHome"
|
||||
}
|
||||
|
||||
$env:DEVECO_SDK_HOME = $SdkHome
|
||||
|
||||
$hvArgs = @(
|
||||
'assembleHap',
|
||||
'--mode', 'module',
|
||||
'-p', "product=$Product",
|
||||
'-p', "buildMode=$BuildMode",
|
||||
'--no-daemon'
|
||||
)
|
||||
|
||||
if ($DryRun) {
|
||||
Write-Output ("PROJECT: " + $projectRoot)
|
||||
Write-Output ("SDK: " + $SdkHome)
|
||||
Write-Output ("DRYRUN: hvigorw " + ($hvArgs -join ' '))
|
||||
return
|
||||
}
|
||||
|
||||
Push-Location $projectRoot
|
||||
try {
|
||||
& hvigorw @hvArgs
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "hvigorw 构建失败,退出码 $LASTEXITCODE"
|
||||
}
|
||||
}
|
||||
finally {
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
$outDir = Join-Path $projectRoot ("entry\build\" + $Product + "\outputs\" + $Product)
|
||||
$hap = Get-ChildItem $outDir -Filter '*.hap' -ErrorAction SilentlyContinue |
|
||||
Sort-Object LastWriteTime -Descending |
|
||||
Select-Object -First 1
|
||||
if ($null -eq $hap) {
|
||||
throw "未找到 HAP 产物: $outDir"
|
||||
}
|
||||
|
||||
Write-Output ("ARTIFACT: " + $hap.FullName)
|
||||
Write-Output ("SIZE: " + $hap.Length)
|
||||
@@ -0,0 +1,21 @@
|
||||
// 签名配置模板(不要直接提交真实证书与密码)
|
||||
//
|
||||
// 用法:把 signingConfigs 合并进 build-profile.json5 的 app 节点,并把占位路径换成
|
||||
// CI 密钥目录或本地证书路径。证书、私钥与密码不得进入版本库。
|
||||
{
|
||||
"signingConfigs": [
|
||||
{
|
||||
"name": "default",
|
||||
"type": "HarmonyOS",
|
||||
"material": {
|
||||
"storeFile": "<CI_SECRET_DIR>/kuge-release.p12",
|
||||
"storePassword": "<ENV:KUGE_STORE_PASSWORD>",
|
||||
"keyAlias": "kuge",
|
||||
"keyPassword": "<ENV:KUGE_KEY_PASSWORD>",
|
||||
"certpath": "<CI_SECRET_DIR>/kuge-release.cer",
|
||||
"profile": "<CI_SECRET_DIR>/kuge-release.p7b",
|
||||
"signAlg": "SHA256withECDSA"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user