servo/.github/workflows/ohos.yml
Narfinger 2353c0089f
OHOS CI: Allow run.json to be overwritten in upload action. (#37083)
The CI does multiple build runs so we need to handle it being
overwritten.

Multiple different build of OHOS servoshell would fight for who is first
to upload run.json and the other would error out.
Now we allow both to succeed by overwrite the run.json

Testing: Testrun:
4268974880

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
2025-05-23 02:17:41 +00:00

263 lines
12 KiB
YAML

name: OpenHarmony
on:
workflow_call:
inputs:
profile:
required: false
default: "release"
type: string
upload:
required: false
default: false
type: boolean
github-release-id:
required: false
type: string
bencher:
required: false
default: false
type: boolean
workflow_dispatch:
inputs:
profile:
required: false
default: "release"
type: choice
description: "Cargo build profile"
options: [ "release", "debug", "production"]
bencher:
required: false
default: false
type: boolean
env:
RUST_BACKTRACE: 1
SHELL: /bin/bash
CARGO_INCREMENTAL: 0
BENCHER_PROJECT: ${{ vars.BENCHER_PROJECT || 'servo' }}
jobs:
build:
name: OpenHarmony Build
runs-on: ubuntu-22.04
strategy:
matrix:
target: ['aarch64-unknown-linux-ohos', 'x86_64-unknown-linux-ohos']
outputs:
signed: ${{ steps.signing_config.outputs.signed }}
steps:
- uses: actions/checkout@v4
if: github.event_name != 'pull_request_target'
with:
fetch-depth: 2
# This is necessary to checkout the pull request if this run was triggered via a
# `pull_request_target` event.
- uses: actions/checkout@v4
if: github.event_name == 'pull_request_target'
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 2
- name: Install crown
run: cargo install --path support/crown
- name: Setup Python
uses: ./.github/actions/setup-python
- name: Bootstrap dependencies
run: sudo apt update && ./mach bootstrap --skip-lints
- name: Setup OpenHarmony SDK
id: setup_sdk
uses: openharmony-rs/setup-ohos-sdk@v0.1
with:
version: "5.0.0"
fixup-path: true
- name: Install node for hvigor
uses: actions/setup-node@v4
with:
node-version: 18
- name: Install hvigor modules
run: |
mkdir ~/hvigor-installation
cd ~/hvigor-installation
echo "@ohos:registry=https://repo.harmonyos.com/npm/" > .npmrc
npm install "@ohos/hvigor@5" "@ohos/hvigor-ohos-plugin@5"
echo "HVIGOR_PATH=$PWD" >> $GITHUB_ENV
- name: "Setup HAP signing config"
id: signing_config
env:
SIGNING_MATERIAL: ${{ secrets.SERVO_OHOS_SIGNING_MATERIAL }}
if: ${{ inputs.upload || env.SIGNING_MATERIAL != '' }} # Allows the build to pass on forks.
run: |
cd ~
echo "${SIGNING_MATERIAL}" | base64 -d > servo-ohos-material.zip
unzip servo-ohos-material.zip
echo "SERVO_OHOS_SIGNING_CONFIG=${PWD}/servo-ohos-material/signing-configs.json" >> $GITHUB_ENV
echo "signed=true" >> "$GITHUB_OUTPUT"
- name: Build (arch ${{ matrix.target }} profile ${{ inputs.profile }})
env:
OHOS_SDK_NATIVE: ${{ steps.setup_sdk.outputs.ohos_sdk_native }}
OHOS_BASE_SDK_HOME: ${{ steps.setup_sdk.outputs.ohos-base-sdk-home }}
run: |
./mach build --locked --target ${{ matrix.target }} --${{ inputs.profile }}
cp -r target/cargo-timings target/cargo-timings-ohos-${{ matrix.target }}
- name: Archive build timing
uses: actions/upload-artifact@v4
with:
name: cargo-timings-ohos-${{ matrix.target }}-${{ inputs.profile }}
# Using a wildcard here ensures that the archive includes the path.
path: target/cargo-timings-*
- name: Upload nightly
if: ${{ inputs.upload && contains(matrix.target, 'aarch64') }}
run: |
./mach upload-nightly ohos \
--secret-from-environment \
--github-release-id ${{ inputs.github-release-id }}
env:
S3_UPLOAD_CREDENTIALS: ${{ secrets.S3_UPLOAD_CREDENTIALS }}
NIGHTLY_REPO_TOKEN: ${{ secrets.NIGHTLY_REPO_TOKEN }}
NIGHTLY_REPO: ${{ github.repository_owner }}/servo-nightly-builds
- name: Generate artifact attestation for HAP
if: ${{ inputs.upload }}
uses: actions/attest-build-provenance@v1
with:
subject-path: target/openharmony/${{ matrix.target }}/${{ inputs.profile }}/entry/build/default/outputs/default/servoshell-default-signed.hap
- name: Upload signed HAP artifact
if: ${{ env.SERVO_OHOS_SIGNING_CONFIG != '' }} # Build output has different name if not signed.
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.profile }}-binary-ohos-${{ matrix.target }}
path: target/openharmony/${{ matrix.target }}/${{ inputs.profile }}/entry/build/default/outputs/default/servoshell-default-signed.hap
- name: Upload unsigned HAP artifact
if: ${{ env.SERVO_OHOS_SIGNING_CONFIG == '' }} # Build output has different name if not signed.
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.profile }}-binary-ohos-${{ matrix.target }}
path: target/openharmony/${{ matrix.target }}/${{ inputs.profile }}/entry/build/default/outputs/default/servoshell-default-unsigned.hap
bencher:
needs: ["build"]
strategy:
matrix:
target: ['aarch64-unknown-linux-ohos', 'x86_64-unknown-linux-ohos']
if: ${{ inputs.bencher && inputs.profile != 'debug' && github.event_name != 'workflow_dispatch' && github.event_name != 'merge_group' }}
uses: ./.github/workflows/bencher.yml
with:
target: ohos-${{ matrix.target }}
profile: ${{ inputs.profile }}
compressed-file-path: ${{ inputs.profile }}-binary-ohos-${{ matrix.target }}/servoshell-default-${{ needs.build.outputs.signed && 'signed' || 'unsigned' }}.hap
binary-path: libs/${{ matrix.target == 'aarch64-unknown-linux-ohos' && 'arm64-v8a' || matrix.target == 'x86_64-unknown-linux-ohos' && 'x86_64' }}/libservoshell.so
file-size: true
speedometer: false
dromaeo: false
secrets: inherit
# Note: We could potentially also merge this build job with the above one,
# if we figure out how to make hvigor build for harmonyos without the HOS commandline-tools installed.
build-harmonyos-aarch64:
name: HarmonyOS Build (aarch64)
continue-on-error: true
runs-on: hos-builder
if: github.repository == 'servo/servo'
steps:
- if: ${{ github.event_name != 'pull_request_target' }}
run: git fetch --depth=1 origin $GITHUB_SHA
- if: ${{ github.event_name == 'pull_request_target' }}
run: git fetch --depth=1 origin ${{ github.event.pull_request.head.sha }}
- run: |
git switch --detach
git reset --hard FETCH_HEAD
- name: Build for aarch64 HarmonyOS
run: |
./mach build --locked --target aarch64-unknown-linux-ohos --profile=${{ inputs.profile }} --flavor=harmonyos --no-default-features --features tracing,tracing-hitrace
- name: Upload supprt/hitrace-bencher/runs.json
uses: actions/upload-artifact@v4
with:
name: runs.json
path: support/hitrace-bencher/runs.json
overwrite: true
- uses: actions/upload-artifact@v4
with:
# Upload the **unsigned** artifact - We don't have the signing materials in pull request workflows
name: servoshell-hos-${{ inputs.profile }}.hap
path: target/openharmony/aarch64-unknown-linux-ohos/${{ inputs.profile }}/entry/build/harmonyos/outputs/default/servoshell-default-unsigned.hap
test-harmonyos-aarch64:
name: Test HarmonyOS aarch64
# Don't block servos Merge queue on this job failing.
# Since we just added this, there might be some hidden issues,
# so in the beginning we will just do a best effort approach but ignore errors.
continue-on-error: true
runs-on: hos-runner
if: github.repository == 'servo/servo'
needs: build-harmonyos-aarch64
steps:
- uses: actions/download-artifact@v4
with:
# Name of the artifact to download.
# If unspecified, all artifacts for the run are downloaded.
name: servoshell-hos-${{ inputs.profile }}.hap
- name: Test hdc device
# First we ensure a device is actually connected and working.
run: hdc list targets && hdc shell echo hello world
- name: Sign the hap
run: |
ls -la
/usr/bin/sign-hos.sh servoshell-default-unsigned.hap servoshell-hos-signed.hap
- name: Install
run: |
# Uninstall first. hdc is not very reliable in terms of exiting with an error, so we uninstall first
# to make sure we don't use a previous version if installation failed for some reason.
hdc uninstall org.servo.servo
hdc install -r servoshell-hos-signed.hap
- name: Test loading servo.org
env:
TRACE_BUFFER_SZ_KB: "524288" # 512 MB
run: |
mkdir test_output
hdc shell aa force-stop org.servo.servo
# Hitrace allows us to save application and system traces, which is useful to analyze performance.
# The main reason however, is that we can use the application traces to determine if servo
# successfully reaches certain locations in the code, in particular if a page is successfully loaded.
hdc shell hitrace -b "${TRACE_BUFFER_SZ_KB}" app graphic ohos freq idle memory --trace_begin
# We start servo, tell it to load a website (servo.org). JIT is not allowed on HarmonyOS 5.
hdc shell aa start -a EntryAbility -b org.servo.servo -U https://servo.org --ps=--pref js_disable_jit=true
servo_pid=$(hdc shell pidof org.servo.servo)
# We don't really know how long servo needs to load a webpage, so we just wait 10s.
sleep 10
# We dump the trace in ftrace format to disk
hdc shell hitrace -b "${TRACE_BUFFER_SZ_KB}" --trace_finish -o /data/local/tmp/ohtrace.txt
hdc shell snapshot_display -f /data/local/tmp/servo.jpeg
hdc file recv /data/local/tmp/servo.jpeg test_output/servo_hos_screenshot.jpeg
hdc file recv /data/local/tmp/ohtrace.txt test_output/servo.ftrace
# To limit the logsize we only save logs from servo.
hdc shell hilog --exit -D 0xE0C3 > test_output/servo.log
# todo: Also benchmark some other websites....
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
path: test_output
name: hos-${{ inputs.profile }}-test-output
- name: Check success
run: |
# would be empty if servo crashed.
servo_pid=$(hdc shell pidof org.servo.servo)
[[ $servo_pid =~ ^[0-9]+$ ]] || { echo "It looks like servo crashed!" ; exit 1; }
# If the grep fails, then the trace output for the "page loaded" prompt is missing
grep 'org\.servo\.servo-.* tracing_mark_write.*PageLoadEndedPrompt' test_output/servo.ftrace
- name: Getting runs file
uses: actions/download-artifact@v4
with:
# Name of the artifact to download.
# If unspecified, all artifacts for the run are downloaded.
name: runs.json
- name: "Run benchmark"
run: hitrace-bench -r runs.json
- name: Getting bencher
uses: bencherdev/bencher@main
- name: Getting model name
run: |
echo "MODEL_NAME=$(hdc bugreport | head -n 20 | grep MarketName | awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}' -)" >> $GITHUB_ENV
- name: Uploading to bencher.dev
run: |
bencher run --adapter json --file bench.json --project '${{ env.BENCHER_PROJECT }}' --token '${{ secrets.BENCHER_API_TOKEN }}' --github-actions '${{ secrets.GITHUB_TOKEN }}' --testbed="$MODEL_NAME"