Skip to content

feat(harmonyos): prepare API 26 follow-ups (#40) #268

feat(harmonyos): prepare API 26 follow-ups (#40)

feat(harmonyos): prepare API 26 follow-ups (#40) #268

Workflow file for this run

name: Build HarmonyOS
on:
push:
branches: [ master, main ]
tags: [ 'v*' ]
pull_request:
branches: [ master, main ]
workflow_dispatch:
inputs:
build_type:
description: 'Build type'
required: false
default: 'debug'
type: choice
options:
- debug
- release
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
NODE_OPTIONS: '--max_old_space_size=8192'
SDK_VERSION: '6.1-Release'
CI_TARGET_API_VERSION: '24'
CMDLINE_TOOLS_VERSION: '5.1.0.840'
CACHE_VERSION: 'v10'
jobs:
build:
name: Build (${{ github.event.inputs.build_type || 'debug' }})
runs-on: ubuntu-latest
timeout-minutes: 90
steps:
# ── 基础环境 ──
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
- name: Setup Node.js 18
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Setup Java 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
- name: Get version info
id: version
run: |
if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
VERSION="${GITHUB_REF#refs/tags/v}"
else
VERSION="$(git describe --tags --always --dirty 2>/dev/null || echo "dev-${GITHUB_SHA:0:7}")"
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Version: $VERSION"
- name: Determine build mode
id: build-mode
run: |
if [[ "${{ github.event.inputs.build_type }}" == "release" ]] || [[ "$GITHUB_REF" == refs/tags/v* ]]; then
echo "mode=release" >> "$GITHUB_OUTPUT"
else
echo "mode=debug" >> "$GITHUB_OUTPUT"
fi
- name: Check signing config
id: signing
run: |
if [[ -n "${{ secrets.SIGNING_CERT }}" ]] && [[ -n "${{ secrets.SIGNING_PROFILE }}" ]] && [[ -n "${{ secrets.SIGNING_KEYSTORE }}" ]]; then
echo "available=true" >> "$GITHUB_OUTPUT"
else
echo "available=false" >> "$GITHUB_OUTPUT"
fi
# ── 磁盘空间 ──
- name: Free disk space
run: |
sudo rm -rf /usr/share/dotnet /opt/ghc /usr/local/share/boost \
"$AGENT_TOOLSDIRECTORY" /opt/hostedtoolcache/CodeQL
df -h /
# ── SDK 下载 & 缓存 ──
- name: Cache OHOS SDK & tools
id: cache-sdk
uses: actions/cache@v4
with:
path: |
~/ohos-sdk
~/cmdline-tools
key: ohos-${{ env.SDK_VERSION }}-tools-${{ env.CMDLINE_TOOLS_VERSION }}-${{ env.CACHE_VERSION }}
- name: Download OHOS SDK
if: steps.cache-sdk.outputs.cache-hit != 'true'
run: |
set -euo pipefail
SDK_URL="https://repo.huaweicloud.com/harmonyos/os/${{ env.SDK_VERSION }}/ohos-sdk-windows_linux-public.tar.gz"
mkdir -p ~/ohos-sdk && cd ~/ohos-sdk
curl -L --retry 3 --retry-delay 10 -o sdk.tar.gz "$SDK_URL" --progress-bar --fail
tar -xzf sdk.tar.gz && rm sdk.tar.gz
if [ -d "linux" ]; then
for zip in linux/*.zip; do
[ -f "$zip" ] && unzip -q -o "$zip" -d .
done
rm -rf linux windows
fi
- name: Download command-line-tools
if: steps.cache-sdk.outputs.cache-hit != 'true'
run: |
set -euo pipefail
TOOLS_VER="${{ env.CMDLINE_TOOLS_VERSION }}"
TOOLS_PREFIX="${TOOLS_VER%.*}"
TOOLS_URL="https://repo.huaweicloud.com/harmonyos/ohpm/${TOOLS_PREFIX}/commandline-tools-linux-x64-${TOOLS_VER}.zip"
cd ~
curl -L --retry 3 --retry-delay 10 -o cmdline-tools.zip "$TOOLS_URL" --progress-bar --fail
unzip -q cmdline-tools.zip
[ -d "command-line-tools" ] && mv command-line-tools ~/cmdline-tools
rm -f cmdline-tools.zip
chmod -R +x ~/cmdline-tools/ohpm/bin/ 2>/dev/null || true
# ── SDK 结构修正 & 补丁 ──
- name: Normalize SDK layout
run: |
chmod +x ci/normalize-sdk.sh
OUTPUT=$(ci/normalize-sdk.sh ~/ohos-sdk)
echo "$OUTPUT"
API_VER=$(echo "$OUTPUT" | grep "SDK_API_VERSION=" | cut -d= -f2)
TARGET_SDK_VERSION=$(echo "$OUTPUT" | grep "HOS_TARGET_SDK_VERSION=" | cut -d= -f2)
echo "SDK_API_VERSION=$API_VER" >> "$GITHUB_ENV"
echo "TARGET_SDK_VERSION=$TARGET_SDK_VERSION" >> "$GITHUB_ENV"
echo "Target SDK version: $TARGET_SDK_VERSION"
- name: Setup environment
run: |
SDK_HOME=~/ohos-sdk
NATIVE_DIR="$(find "$SDK_HOME" -maxdepth 3 -name "native" -type d | head -1)"
TOOLCHAINS_DIR="$(find "$SDK_HOME" -maxdepth 3 -name "toolchains" -type d | head -1)"
[ -n "$TOOLCHAINS_DIR" ] && echo "$TOOLCHAINS_DIR" >> "$GITHUB_PATH"
[ -n "$NATIVE_DIR" ] && echo "${NATIVE_DIR}/build-tools/cmake/bin" >> "$GITHUB_PATH"
echo "$HOME/cmdline-tools/ohpm/bin" >> "$GITHUB_PATH"
echo "$HOME/cmdline-tools/hvigor/bin" >> "$GITHUB_PATH"
{
echo "OHOS_SDK_HOME=$SDK_HOME"
echo "HOS_SDK_HOME=$SDK_HOME"
echo "OHOS_BASE_SDK_HOME=$SDK_HOME"
echo "DEVECO_SDK_HOME=$SDK_HOME"
} >> "$GITHUB_ENV"
# ── build-profile.json5 ──
- name: Create build profile (unsigned)
if: steps.signing.outputs.available != 'true'
run: |
cat > build-profile.json5 << EOF
{
"app": {
"signingConfigs": [],
"products": [
{
"name": "default",
"compatibleSdkVersion": "5.0.0(12)",
"compileSdkVersion": "${TARGET_SDK_VERSION}",
"targetSdkVersion": "${TARGET_SDK_VERSION}",
"runtimeOS": "HarmonyOS",
"buildOption": {
"strictMode": {
"caseSensitiveCheck": true,
"useNormalizedOHMUrl": true
}
}
}
],
"buildModeSet": [
{ "name": "debug" },
{ "name": "release" }
]
},
"modules": [
{
"name": "entry",
"srcPath": "./entry",
"targets": [{ "name": "default", "applyToProducts": ["default"] }]
},
{
"name": "nativelib",
"srcPath": "./nativelib",
"targets": [{ "name": "default", "applyToProducts": ["default"] }]
}
]
}
EOF
- name: Create build profile (signed)
if: steps.signing.outputs.available == 'true'
run: |
mkdir -p .signing
echo "${{ secrets.SIGNING_CERT }}" | base64 -d > .signing/cert.cer
echo "${{ secrets.SIGNING_PROFILE }}" | base64 -d > .signing/profile.p7b
echo "${{ secrets.SIGNING_KEYSTORE }}" | base64 -d > .signing/keystore.p12
CERT_PATH="$(pwd)/.signing/cert.cer"
PROFILE_PATH="$(pwd)/.signing/profile.p7b"
KEYSTORE_PATH="$(pwd)/.signing/keystore.p12"
KEY_ALIAS="${{ secrets.SIGNING_KEY_ALIAS }}"
KEY_PASSWORD="${{ secrets.SIGNING_KEY_PASSWORD }}"
STORE_PASSWORD="${{ secrets.SIGNING_STORE_PASSWORD }}"
cat > build-profile.json5 << PROFILE_EOF
{
"app": {
"signingConfigs": [
{
"name": "default",
"type": "HarmonyOS",
"material": {
"certpath": "${CERT_PATH}",
"keyAlias": "${KEY_ALIAS}",
"keyPassword": "${KEY_PASSWORD}",
"profile": "${PROFILE_PATH}",
"signAlg": "SHA256withECDSA",
"storeFile": "${KEYSTORE_PATH}",
"storePassword": "${STORE_PASSWORD}"
}
}
],
"products": [
{
"name": "default",
"signingConfig": "default",
"compatibleSdkVersion": "5.0.0(12)",
"compileSdkVersion": "${TARGET_SDK_VERSION}",
"targetSdkVersion": "${TARGET_SDK_VERSION}",
"runtimeOS": "HarmonyOS",
"buildOption": {
"strictMode": {
"caseSensitiveCheck": true,
"useNormalizedOHMUrl": true
}
}
}
],
"buildModeSet": [
{ "name": "debug" },
{ "name": "release" }
]
},
"modules": [
{
"name": "entry",
"srcPath": "./entry",
"targets": [{ "name": "default", "applyToProducts": ["default"] }]
},
{
"name": "nativelib",
"srcPath": "./nativelib",
"targets": [{ "name": "default", "applyToProducts": ["default"] }]
}
]
}
PROFILE_EOF
# ── 依赖安装 ──
- name: Cache ohpm packages
uses: actions/cache@v4
with:
path: |
oh_modules
entry/oh_modules
nativelib/oh_modules
~/.ohpm
key: ohpm-${{ hashFiles('**/oh-package.json5') }}
restore-keys: ohpm-
- name: Setup hvigor
run: |
set -euo pipefail
CMDTOOLS_HVIGOR="$HOME/cmdline-tools/hvigor"
echo "@ohos:registry=https://repo.huaweicloud.com/repository/npm/" > ~/.npmrc
mkdir -p "$CMDTOOLS_HVIGOR/node_modules/@ohos"
ln -sf "$CMDTOOLS_HVIGOR/hvigor" "$CMDTOOLS_HVIGOR/node_modules/@ohos/hvigor"
ln -sf "$CMDTOOLS_HVIGOR/hvigor-ohos-plugin" "$CMDTOOLS_HVIGOR/node_modules/@ohos/hvigor-ohos-plugin"
mkdir -p "$CMDTOOLS_HVIGOR/hvigor/node_modules/@ohos"
ln -sf "$CMDTOOLS_HVIGOR/hvigor" "$CMDTOOLS_HVIGOR/hvigor/node_modules/@ohos/hvigor"
mkdir -p "$CMDTOOLS_HVIGOR/hvigor-ohos-plugin/node_modules/@ohos"
ln -sf "$CMDTOOLS_HVIGOR/hvigor" "$CMDTOOLS_HVIGOR/hvigor-ohos-plugin/node_modules/@ohos/hvigor"
for dir in . hvigor entry nativelib; do
mkdir -p "$dir/node_modules/@ohos"
ln -sf "$CMDTOOLS_HVIGOR/hvigor" "$dir/node_modules/@ohos/hvigor"
ln -sf "$CMDTOOLS_HVIGOR/hvigor-ohos-plugin" "$dir/node_modules/@ohos/hvigor-ohos-plugin"
done
- name: Install ohpm dependencies
run: |
ohpm config set registry https://ohpm.openharmony.cn/ohpm/
ohpm config set strict_ssl false
ohpm install --all
# ── SDK 补丁 ──
- name: Patch SDK
run: |
chmod +x ci/patch-sdk.sh
ci/patch-sdk.sh ~/ohos-sdk
# ── 构建 ──
- name: Build Native HAR
run: |
set -o pipefail
BUILD_MODE="${{ steps.build-mode.outputs.mode }}"
export NODE_HOME="$(dirname "$(dirname "$(which node)")")"
export JAVA_HOME="${JAVA_HOME_17_X64}"
export LD_LIBRARY_PATH="${HOME}/ohos-sdk/toolchains/lib:${HOME}/ohos-sdk/previewer/common/bin:${LD_LIBRARY_PATH:-}"
node hvigorw.js assembleHar \
--mode module \
-p module=nativelib@default \
-p product=default \
-p buildMode="${BUILD_MODE}" \
--no-daemon \
--stacktrace \
2>&1 | tee build-har.log
- name: Build App
run: |
set -o pipefail
BUILD_MODE="${{ steps.build-mode.outputs.mode }}"
export NODE_HOME="$(dirname "$(dirname "$(which node)")")"
export JAVA_HOME="${JAVA_HOME_17_X64}"
export LD_LIBRARY_PATH="${HOME}/ohos-sdk/toolchains/lib:${HOME}/ohos-sdk/previewer/common/bin:${LD_LIBRARY_PATH:-}"
node hvigorw.js assembleApp \
--mode project \
-p product=default \
-p buildMode="${BUILD_MODE}" \
--no-daemon \
--stacktrace \
2>&1 | tee build-hap.log
# ── 清理 & 上传 ──
- name: Cleanup signing files
if: always()
run: rm -rf .signing/
- name: Upload build logs on failure
uses: actions/upload-artifact@v4
if: failure()
with:
name: build-logs-${{ github.run_id }}
path: |
build-har.log
build-hap.log
retention-days: 7
- name: Upload build artifacts
uses: actions/upload-artifact@v4
if: success()
with:
name: harmonyos-${{ steps.build-mode.outputs.mode }}-${{ github.run_id }}
path: |
entry/build/default/outputs/**/*.hap
nativelib/build/default/outputs/**/*.har
if-no-files-found: warn
retention-days: 7
# Signed release artifacts are produced when signing secrets are configured.