极狐GitLab鸿蒙开发场景DevOps解决方案
参考资料
- 获取命令行工具-Command Line Tools - 华为HarmonyOS开发者 (huawei.com)
- 搭建流水线-Command Line Tools - 华为HarmonyOS开发者 (huawei.com)
- 应用/服务签名-DevEco Studio - 华为HarmonyOS开发者 (huawei.com)
修订记录
日期 内容 2024.08.21 创建文档 重要说明
- 该项目基于极狐GitLab专业版进行设置和演示
- 该项目地址 https://presales-demo.jihulab.com/mycompany/harmony/harmony-demo
- 该文档基于于HarmonyOS NEXT Developer Beta5,最低仅支持OpenHarmony API 9的项目,由于Harmony项目也在高速演进和迭代,其他HarmonyOS版本仅供参考。
1. 环境依赖
- 服务端
- 已安装极狐GitLab专业版, 如未安装,可参考《极狐GitLab私有化部署指南》安装部署。
- 一台8C、32G、500G及以上配置的Linux服务器,x86架构,建议Ubuntu操作系统,用于执行Harmony项目的流水线,并根据项目大小与并发任务适当增加配置。
- 开发机
- 有Harmony项目,至少是OpenHarmony API 9版本,不支持更低版本。
- 已安装git客户端。
2. 环境配置
注意:以下操作均在GitLab Runner所在服务器进行。
2.1 安装GitLab Runner
-
参考文档安装GitLab Runner,以Ubuntu为例:
# 添加极狐GitLab仓库 curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash # 安装GitLab Runner sudo apt-get install gitlab-runner -
打开极狐GitLab,在全局(需GitLab管理员)或在指定的群组或项目中创建Runner。

-
输入Runner标签,如
harmony,创建Runner。
-
根据页面提示,在GitLab Runner中执行命令:
- 第一步直接按回车。
- 第二步输入
shell。

-
在GitLab页面查看Runner状态。

-
修改
/etc/gitlab-runner/config.toml中的concurrent=5,表示可以并发的任务数,可根据实际情况和资源配置修改。
2.2 安装环境依赖
- 参考Harmony官方文档,分别安装并配置JDK、命令行工具、hdc、hvigor、npm、ohpm、libGL1,以下是Ubuntu操作系统下的简化命令,具体以官方为准:
# 安装JDK17 wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.tar.gz mkdir /opt tar -xvf jdk-17_linux-x64_bin.tar.gz -C /opt/ export JAVA_HOME=/opt/jdk-17.0.12 export PATH=$PATH:$JAVA_HOME/bin java -version # 安装command line ## 访问 https://developer.huawei.com/consumer/cn/download/,下载 Command Line Tools For HarmonyOS for Linux,并上传到Runner所在服务器 unzip -d /opt/ commandline-tools-linux-x64-5.0.3.700.zip chmod -R 777 /opt/command-line-tools # 配置hdc环境变量 export HDC_HOME=/opt/command-line-tools/sdk/HarmonyOS-NEXT-DB5/openharmony/toolchains export PATH=$PATH:$HDC_HOME # 配置hvigor环境变量 export PATH=/opt/command-line-tools/bin:$PATH # 配置npm镜像仓库 apt install npm npm config set registry=https://repo.huaweicloud.com/repository/npm/ npm config set @ohos:registry=https://repo.harmonyos.com/npm/ # 安装ohpm export PATH=/opt/command-line-tools/bin:$PATH ohpm config set registry https://ohpm.openharmony.cn/ohpm/ ohpm config set strict_ssl false # 安装libGL1 apt install libgl1-mesa-dev
3. 项目配置
3.1 初始化项目
-
在极狐GitLab中创建空白项目,如
harmony demo,取消勾选“使用自述文件初始化仓库”。
-
根据
harmony demo的提示,在开发机本地初始化已存在的Harmony项目,将本地代码上传到GitLab。
3.2 申请HAP签名
从NEXT Developer Beta3版本开始,所有的HAP、APP文件需开启签名,否则将导致构建出的包无法安装到设备上。
-
如果仅开发环境进行调试,DevEco提供了自动签名。
-
如果要发布应用,或在流水线中自动构建、打包,需参考以下步骤获取相关证书:
-
在当前项目
harmony demo“设置——CI/CD——变量”中创建环境变量,类型为**“变量” ,取消勾选“保护变量”:**- keyPwd: 申请
.p12文件时的password - keyAlias: 申请
.csr文件时的keyAlias - keystorePwd:申请
.csr文件时的password,正常与keyPwd一致
- keyPwd: 申请
-
在当前项目
harmony demo“设置——CI/CD——Secure files”中上传以下文件:- 密钥
.p12文件。注意请将文件直接改名为.p12,再上传。 - 证书
.cer文件。注意请将文件直接改名为.cer,再上传。 - Profile
.p7b文件。注意请将文件直接改名为.p7b,再上传。
- 密钥
3.3 流水线配置
在当前项目harmony demo创建流水线,内容如下,需修改:
PRODUCT_NAME:对应项目build-profile.json5中的products的nameOUTPUT_PATH:构建文件的输出路径,APP和HAP的输出路径不一样UNSIGNED_FILE:未签名的文件路径SIGNED_FILE:签名的文件路径before_script中的环境变量需与2.2章节配置的环境变量一致- 根据实际情况修改
build-job的构建命令,如构建Hap或构建Hsp# 仅在Tag为harmony的Runner中执行 default: tags: - harmony variables: # 对应 build-profile.json5 中的products的name PRODUCT_NAME: default # 输出路径 OUTPUT_PATH: build/outputs/$PRODUCT_NAME # 未签名文件名 UNSIGNED_FILE: $CI_PROJECT_NAME-$PRODUCT_NAME-unsigned.app # 已签名文件名 SIGNED_FILE: $CI_PROJECT_NAME-$PRODUCT_NAME-signed.app # 添加环境变量 before_script: - export JAVA_HOME=/opt/jdk-17.0.12 - export HDC_HOME=/opt/command-line-tools/sdk/HarmonyOS-NEXT-DB5/openharmony/toolchains - export HCT_HOME=/opt/command-line-tools/bin - export PATH=$PATH:$JAVA_HOME/bin:$HDC_HOME:$HCT_HOME stages: - build - test - upload # hvigorw编译打包 build-job: stage: build script: # 安装依赖 - ohpm install # 构建Hsp, 生成产物:${PROJECT_PATH}/{moduleName}/build/{productName}/outputs/{targetName}/(xxx.har | xxx.hsp) # - hvigorw assembleHsp --mode module -p module=library@default -p product=default --no-daemon # 构建Har, 生成产物:${PROJECT_PATH}/{moduleName}/build/{productName}/outputs/{targetName}/outputs/xxx.har # - hvigorw assembleHar --mode module -p module=library1@default -p product=default --no-daemon # 构建Hap, 生成产物:${PROJECT_PATH}/{moduleName}/build/{productName}/outputs/{targetName}/xxx.hap # - hvigorw assembleHap --mode module -p product=$PRODUCT_NAME -p buildMode=debug --no-daemon # 构建App, 生成产物: ${PROJECT_PATH}/build/outputs/{productName}/xxx.app - hvigorw assembleApp --mode project -p product=$PRODUCT_NAME -p buildMode=debug --no-daemon # 下载security file - curl --silent "https://gitlab.com/gitlab-org/incubation-engineering/mobile-devops/download-secure-files/-/raw/main/installer" | bash # 签名 - java -jar $HDC_HOME/lib/hap-sign-tool.jar sign-app -keyAlias "$keyAlias" -signAlg "SHA256withECDSA" -mode "localSign" -appCertFile ".secure_files/.cer" -profileFile ".secure_files/.p7b" -inFile "$OUTPUT_PATH/$UNSIGNED_FILE" -keystoreFile ".secure_files/.p12" -outFile "$OUTPUT_PATH/$SIGNED_FILE" -keyPwd "$keyPwd" -keystorePwd "$keystorePwd" -signCode "1" # 创建review环境 environment: name: review/$CI_COMMIT_REF_SLUG url: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/jobs/artifacts/$CI_COMMIT_REF_NAME/download?job=build-job # 上传签名后的文件 artifacts: paths: - $OUTPUT_PATH/$SIGNED_FILE # codelinter静态扫描 lint-test-job: stage: test script: - codelinter -o codelinter.txt - | #!/bin/bash input_file="codelinter.txt" output_file="gl-code-quality-report.json" # 初始化变量 declare -a issues current_path="" # 生成UUID的函数 generate_uuid() { uuidgen } # 转义description中的特殊字符:双引号、正反斜杠 escape_special_chars() { echo "$1" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\//\\\//g' } # 读取文件逐行处理 while IFS= read -r line do # 去除行尾的回车符 line=$(echo "$line" | tr -d '\r') # 判断是否为path if [[ $line =~ ^/ ]]; then # 去掉路径中的括号部分,并去除末尾的换行符 current_path=$(echo "$line" | sed 's/(.*)//' | tr -d '\n') # 去掉开头的"$CI_PROJECT_DIR/"字符串,只取相对路径 current_path=$(echo "$current_path" | sed "s|^$CI_PROJECT_DIR/||") elif [[ $line =~ ^[0-9]+:[0-9]+ ]]; then # 提取行号,错误类型,描述,和规则名称 line_info=$(echo "$line" | awk '{print $1}') severity="minor" # 固定为 minor description=$(echo "$line" | awk '{$1=$2=""; print $0}' | awk '{$NF=""; print $0}' | tr -d '\n') check_name=$(echo "$line" | awk '{print $NF}' | tr -d '\n') fingerprint=$(generate_uuid) begin_line=$(echo "$line_info" | cut -d: -f1) end_line=$(echo "$line_info" | cut -d: -f2) # 去掉description和check_name中的多余空格 description=$(echo "$description" | sed 's/^[ \t]*//;s/[ \t]*$//') check_name=$(echo "$check_name" | sed 's/^[ \t]*//;s/[ \t]*$//') # 转义description中的特殊字符 description=$(escape_special_chars "$description") # 创建JSON对象并添加到数组中 issue=$(printf '{ "engine_name": "codelinter", "fingerprint": "%s", "type": "issue", "check_name": "%s", "description": "%s", "severity": "%s", "location": { "path": "%s", "lines": { "begin": %d, "end": %d } } }' "$fingerprint" "$check_name" "$description" "$severity" "$current_path" "$begin_line" "$end_line") issues+=("$issue") fi done < "$input_file" # 将数组内容格式化为JSON数组并写入输出文件 printf "[\n%s\n]\n" "$(IFS=','; echo "${issues[*]}")" > "$output_file" artifacts: reports: codequality: gl-code-quality-report.json # 上传到制品库 upload-job: stage: upload image: alpine/curl rules: # 如果是从tag触发,即生产版本,则执行上传到制品库任务 - if: '$CI_COMMIT_TAG =~ /^v?\d+\.\d+\.\d+$/' script: # 上传到软件包库 - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file $OUTPUT_PATH/$SIGNED_FILE "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/release/$CI_COMMIT_TAG/$SIGNED_FILE"'
3.4 分支策略
建议使用GitLab Workflow,可参考文档《快速开始极狐GitLab工作流——分支策略》。
3.5 保护分支:防止越权提交
参考文档《快速开始极狐GitLab工作流——保护分支》配置。

3.6 推送规则:规范提交信息
参考文档《快速开始极狐GitLab工作流——分支命名规则》、《快速开始极狐GitLab工作流——代码推送规则》配置。


3.7 代码评审:提高代码质量
参考文档《快速开始极狐GitLab工作流——代码评审》配置“合并请求批准”和“代码所有者CodeOwner”。
若未经过审核人审批,则无法合并代码。

3.8 代码扫描:Code Linter
Harmony官方提供了静态扫描工具Code Linter,已在3.3流水线配置中进行了集成,用户可根据Harmony官方文档修改项目中的code-linter.json5文件,自定义规则或使用不同的规则集。
注意,由于当前Harmony的Code Linter对于Error、Warn区分的不是很好,也没有优先级的定义,所以在GitLab中,所有的质量问题均显示为“次要”,后续等Harmony完善后可再做调整。
扫描后的结果可在以下位置查询:
-
流水线:显示流水线运行分支的全量报告。

-
合并请求:显示合并请求源分支相较于目标分支的差异报告。

3.9 制品管理
在3.3流水线配置中,已将编译构建并签名后的软件包上传到GitLab,可在以下位置获取:
-
合并请求:如从
feature/my-new-feat合并到main分支,流水线会基于feature/my-new-feat分支进行打包。开发、测试人员可点击合并请求中的“查看最新应用”下载feature/my-new-feat分支的软件包。一般用于测试,并可将测试结果作为评审意见参与代码评审,提高产品、研发、测试协同效率。
-
软件包库:如测试完成,准备正式发版,可基于
main分支创建release分支,再基于release分支打上标签Tag。对于从Tag触发的流水线,会将软件包上传到GitLab软件包库,作为正式发版的制品。
