feat(harmonyos): prepare API 26 follow-ups (#40) #268
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
| 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. |