Fix JavaScript glass tab lens rendering #840
Workflow file for this run
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
| # Real-life Windows build pipeline: CROSS-COMPILE the native Windows port's full | |
| # hellocodenameone screenshot-suite .exe on a *Linux* runner (clang-cl + lld-link | |
| # + llvm-rc against an xwin-laid-out Windows SDK, with the WebView2 SDK fetched so | |
| # the BrowserComponent peer is linked), then RUN that exact Linux-built binary on | |
| # a real Windows runner and capture the screenshot suite over the cn1ss WebSocket. | |
| # | |
| # This mirrors how a Codename One app is actually shipped for Windows -- compiled | |
| # on a (Linux) build host, executed on the user's Windows machine -- which neither | |
| # of the other two Windows workflows does on its own: windows-cross-compile.yml | |
| # builds on Linux but only *links* (never runs), and parparvm-tests-windows.yml | |
| # builds *natively on Windows* and runs. Here the binary that renders on Windows | |
| # is the one cross-compiled on Linux, browser included. | |
| # | |
| # Three jobs, artifact-chained within the run: | |
| # cross-build (ubuntu) -> uploads WinHelloMain.exe (Linux-cross-compiled, x64) | |
| # run-on-windows (x64) -> downloads + runs it, captures the suite PNGs | |
| # compare-comment (ubuntu)-> diffs the PNGs vs the in-repo baseline, posts the PR | |
| name: Windows cross-build + run (Linux build -> Windows run) | |
| on: | |
| # Manual dispatch: this PR's changed-file count exceeds GitHub's paths-filter | |
| # diff limit, so pull_request triggers stopped firing -- dispatch with | |
| # gh workflow run <file> --ref <branch> | |
| workflow_dispatch: | |
| pull_request: | |
| paths: | |
| - '.github/workflows/windows-cross-build-run.yml' | |
| - 'vm/**' | |
| - 'Ports/WindowsPort/**' | |
| - 'maven/windows/**' | |
| - 'scripts/windows/**' | |
| - 'scripts/hellocodenameone/**' | |
| - '!vm/**/README.md' | |
| - '!vm/**/readme.md' | |
| - '!vm/**/docs/**' | |
| push: | |
| branches: [ master, main ] | |
| paths: | |
| - '.github/workflows/windows-cross-build-run.yml' | |
| - 'vm/**' | |
| - 'Ports/WindowsPort/**' | |
| - 'maven/windows/**' | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} | |
| cancel-in-progress: true | |
| jobs: | |
| cross-build: | |
| name: cross-build suite exe (Linux, x64 + WebView2) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v6 | |
| # The native BrowserComponent peer (cn1_windows_browser.cpp) is C++ that | |
| # uses the MSVC STL via the xwin headers; the MSVC STL gates on a recent | |
| # clang (older clang-cl trips STL1000 "Unexpected compiler version"), so | |
| # pin LLVM 19 for the cross-build rather than the distro default. | |
| - name: Install LLVM 19 + CMake/Ninja | |
| run: | | |
| set -e | |
| bash scripts/ci/apt-get-update.sh | |
| # xvfb: the CN1 CSS compiler (codenameone-maven-plugin css goal) renders | |
| # via CEF/AWT and throws HeadlessException without a display, so the | |
| # hellocodenameone-common build below runs under a virtual X server. | |
| sudo apt-get install -y cmake ninja-build unzip xvfb | |
| wget -q https://apt.llvm.org/llvm.sh | |
| chmod +x llvm.sh | |
| sudo ./llvm.sh 19 | |
| sudo apt-get install -y clang-19 lld-19 llvm-19 | |
| echo "/usr/lib/llvm-19/bin" >> "$GITHUB_PATH" | |
| /usr/lib/llvm-19/bin/clang-cl --version | |
| /usr/lib/llvm-19/bin/lld-link --version 2>&1 | head -1 || true | |
| /usr/lib/llvm-19/bin/llvm-rc --version 2>&1 | head -1 || true | |
| # JDK matrix the translator harness auto-discovers (JDK_*_HOME). JDK 8 is | |
| # restored last so it is the active JAVA_HOME (it builds codename1-core and | |
| # is what CompilerHelper translates with). JDK 17 builds the sample app. | |
| - name: Set up JDK 8 | |
| uses: actions/setup-java@v5 | |
| with: { distribution: 'temurin', java-version: '8' } | |
| - run: echo "JDK_8_HOME=$JAVA_HOME" >> $GITHUB_ENV | |
| - name: Set up JDK 11 | |
| uses: actions/setup-java@v5 | |
| with: { distribution: 'temurin', java-version: '11' } | |
| - run: echo "JDK_11_HOME=$JAVA_HOME" >> $GITHUB_ENV | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v5 | |
| with: { distribution: 'temurin', java-version: '17' } | |
| - run: echo "JDK_17_HOME=$JAVA_HOME" >> $GITHUB_ENV | |
| - name: Restore JDK 8 as the active JDK | |
| uses: actions/setup-java@v5 | |
| with: { distribution: 'temurin', java-version: '8' } | |
| - name: Install xwin + lay out the Windows SDK (x64) | |
| env: | |
| # `cargo install xwin` and `xwin splat` flake on transient crates.io / | |
| # download errors ("curl [16] HTTP2 framing layer", "[55] OpenSSL | |
| # SSL_read unexpected eof"). Disable HTTP/2 multiplexing (forces | |
| # HTTP/1.1, which avoids the framing errors) and let cargo retry. | |
| CARGO_NET_RETRY: "10" | |
| CARGO_HTTP_MULTIPLEXING: "false" | |
| run: | | |
| set -e | |
| # Retry the whole install/splat a few times for non-cargo download | |
| # hiccups (the xwin SDK fetch from Microsoft). | |
| n=0 | |
| until [ "$n" -ge 3 ]; do | |
| cargo install xwin --version 0.9.0 --locked \ | |
| && xwin --accept-license --arch x86_64 splat --output "$RUNNER_TEMP/xwin-sdk" \ | |
| && break | |
| n=$((n+1)) | |
| echo "xwin install/splat attempt $n failed; retrying after backoff..." | |
| rm -rf "$RUNNER_TEMP/xwin-sdk" | |
| sleep $((n*15)) | |
| done | |
| test -d "$RUNNER_TEMP/xwin-sdk/crt/include" | |
| test -f "$RUNNER_TEMP/xwin-sdk/sdk/include/um/d2d1.h" | |
| # Fetch the WebView2 NuGet SDK on Linux (portable bash counterpart of the | |
| # Windows fetch script). It is a plain zip of headers + the x64/arm64 static | |
| # loader libs, so the cross-build links the BrowserComponent peer exactly | |
| # like the Windows runners do. Non-fatal: if the download fails the browser | |
| # natives compile as stubs (WEBVIEW2_SDK_DIR stays unset) and the suite runs | |
| # without the BrowserComponent tile rather than failing the whole pipeline. | |
| - name: Fetch WebView2 SDK (Linux) | |
| continue-on-error: true | |
| run: | | |
| set -e | |
| LINE="$(bash scripts/windows/fetch-webview2-sdk.sh "$RUNNER_TEMP/webview2sdk" | tail -1)" | |
| echo "Resolved: $LINE" | |
| case "$LINE" in | |
| WEBVIEW2_SDK_DIR=*) echo "$LINE" >> "$GITHUB_ENV" ;; | |
| *) echo "WebView2 fetch did not yield a dir; browser will be stubbed" ;; | |
| esac | |
| # Build codename1-core + the Windows port, the codenameone maven plugin | |
| # (runs transcode-svg / css / annotation processing during the sample build) | |
| # and cn1-ads-mock (a sample dependency) -- the same inputs the native | |
| # Windows screenshot job installs. JDK 8: core is source/target 1.5. | |
| - name: Build core + Windows port + CN1 maven plugin (JDK 8) | |
| run: | | |
| cd maven | |
| JAVA_HOME="$JDK_8_HOME" mvn -B -pl windows,codenameone-maven-plugin,cn1-ads-mock -am \ | |
| -DskipTests '-Dmaven.javadoc.skip=true' '-Plocal-dev-javase' install | |
| test -f core/target/classes/com/codename1/ui/Form.class | |
| test -f windows/target/classes/com/codename1/impl/windows/WindowsImplementation.class | |
| # Build the hellocodenameone screenshot app into common/target/classes (the | |
| # suite the cross-build translates). Plain Maven build of the sample on JDK | |
| # 17 -- exactly what a fresh initializr project does; the plugin runs | |
| # transcode-svg/css/annotation processing. Kotlin 1.6.0 compiles on JDK 17. | |
| # Seed an empty guibuilder.jar marker to skip the codenameone install | |
| # bootstrap's network step (artifacts are already in the local repo). | |
| - name: Build hellocodenameone-common (Maven, JDK 17) | |
| env: | |
| JDK_17_HOME: ${{ env.JDK_17_HOME }} | |
| run: | | |
| set -e | |
| export JAVA_HOME="$JDK_17_HOME" | |
| # Headful virtual display for the CSS compiler's CEF/AWT rendering. | |
| Xvfb :99 -screen 0 1600x1200x24 >/tmp/xvfb.log 2>&1 & | |
| export DISPLAY=:99 | |
| sleep 2 | |
| mkdir -p "$HOME/.codenameone" | |
| [ -f "$HOME/.codenameone/guibuilder.jar" ] || : > "$HOME/.codenameone/guibuilder.jar" | |
| mvn -B -f scripts/hellocodenameone/pom.xml -pl common -am install -DskipTests '-Dmaven.javadoc.skip=true' | |
| test -f scripts/hellocodenameone/common/target/classes/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunner.class | |
| test -f scripts/hellocodenameone/common/target/classes/com/codename1/generated/svg/SVGRegistry.class | |
| # Translate the full suite and cross-compile it to a Windows x64 PE with | |
| # clang-cl + xwin. WEBVIEW2_SDK_DIR (exported above when the fetch worked) | |
| # flows into the generated CMake and links the BrowserComponent peer. The | |
| # exe is written to CN1_CROSS_EXE_OUT for the upload below. | |
| - name: Cross-build the full suite exe (clang-cl + xwin + WebView2) | |
| env: | |
| CN1_XWIN_SYSROOT: ${{ runner.temp }}/xwin-sdk | |
| CN1_CLANG_CL: clang-cl | |
| CN1_LLVM_RC: llvm-rc | |
| CN1_CROSS_EXE_OUT: ${{ github.workspace }}/artifacts/WinHelloMain.exe | |
| run: | | |
| cd vm | |
| JAVA_HOME="$JDK_8_HOME" mvn -B -pl tests -am test \ | |
| '-Dtest=CleanTargetIntegrationTest#crossBuildsHelloSuiteExe' \ | |
| '-Dsurefire.failIfNoSpecifiedTests=false' | |
| test -f "$CN1_CROSS_EXE_OUT" | |
| ls -l "$CN1_CROSS_EXE_OUT" | |
| - name: Upload cross-built suite exe | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: windows-cross-suite-exe | |
| # The .exe plus its separate .pdb symbol companion (for crash symbolication). | |
| path: | | |
| artifacts/WinHelloMain.exe | |
| artifacts/WinHelloMain.pdb | |
| if-no-files-found: error | |
| retention-days: 1 | |
| run-on-windows: | |
| name: run cross-built exe + capture (Windows x64) | |
| needs: cross-build | |
| runs-on: windows-latest | |
| timeout-minutes: 60 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v4 | |
| # Only a JDK is needed here: with CN1_PREBUILT_EXE set the capture test | |
| # neither translates nor builds -- it just compiles the Java cn1ss server, | |
| # launches the prebuilt exe and collects the PNGs it streams. No MSVC / | |
| # Ninja / clang. windows-latest ships the WebView2 Evergreen runtime the | |
| # BrowserComponent peer loads at activation. | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v5 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '17' | |
| cache: 'maven' | |
| - name: Download cross-built suite exe | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: windows-cross-suite-exe | |
| path: artifacts | |
| - name: Verify the downloaded exe | |
| shell: pwsh | |
| run: | | |
| $exe = "artifacts/WinHelloMain.exe" | |
| if (!(Test-Path $exe)) { Write-Error "cross-built exe missing: $exe"; exit 1 } | |
| Write-Host "Cross-built exe: $((Get-Item $exe).Length) bytes" | |
| # Run the Linux-cross-compiled exe and capture the screenshot suite over the | |
| # cn1ss WebSocket. CN1_PREBUILT_EXE makes the capture test run this exact | |
| # binary instead of building one. ~112 PNGs land in CN1_SHOT_OUTPUT_DIR. | |
| - name: Run cross-built suite + capture screenshots | |
| working-directory: vm | |
| shell: pwsh | |
| env: | |
| CN1_PREBUILT_EXE: ${{ github.workspace }}\artifacts\WinHelloMain.exe | |
| CN1_SHOT_OUTPUT_DIR: ${{ github.workspace }}\artifacts\windows-port\raw | |
| run: | | |
| mvn -B clean package -pl JavaAPI -am -DskipTests | |
| mvn -B test -pl tests -am '-Dtest=CleanTargetIntegrationTest#capturesHelloSuiteOverWebSocket' '-Dsurefire.failIfNoSpecifiedTests=false' | |
| - name: Upload screenshot artifact (cross-compiled, x64) | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: windows-cross-screenshot-raw | |
| path: artifacts/windows-port/raw | |
| if-no-files-found: warn | |
| retention-days: 14 | |
| # Diffs the screenshots produced by the Linux-cross-compiled binary against the | |
| # in-repo baseline (scripts/windows/screenshots) and posts them to the PR, with | |
| # a marker distinct from the native-Windows screenshot comment so both coexist. | |
| compare-comment: | |
| name: cross-compiled screenshot-comment | |
| needs: run-on-windows | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.CN1SS_GH_TOKEN }} | |
| GH_TOKEN: ${{ secrets.CN1SS_GH_TOKEN }} | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v4 | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v5 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '17' | |
| - name: Download cross-compiled screenshot artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: windows-cross-screenshot-raw | |
| path: artifacts/windows-port/raw-x64 | |
| - name: Post screenshots to PR | |
| shell: bash | |
| env: | |
| CN1SS_COMMENT_MARKER: '<!-- CN1SS_WINDOWS_CROSS_COMPILED_COMMENT -->' | |
| CN1SS_COMMENT_LOG_PREFIX: '[windows-cross-compiled]' | |
| CN1SS_PREVIEW_SUBDIR: 'windows-cross' | |
| CN1SS_SUCCESS_MESSAGE: 'Native Windows port, REAL shipping pipeline: the hellocodenameone screenshot suite rendered by a binary CROSS-COMPILED on Linux (clang-cl + xwin, WebView2 linked) and RUN on a Windows x64 runner. Compared against the in-repo baseline in scripts/windows/screenshots.' | |
| run: | | |
| set -e | |
| ART="artifacts/windows-port" | |
| entries=() | |
| if [ -d "$ART/raw-x64" ]; then | |
| for f in "$ART"/raw-x64/*.png; do | |
| [ -f "$f" ] || continue | |
| name=$(basename "$f" .png) | |
| entries+=("$name=$f") | |
| done | |
| fi | |
| if [ ${#entries[@]} -eq 0 ]; then | |
| echo "No screenshots were produced; skipping PR comment." | |
| exit 0 | |
| fi | |
| echo "Posting ${#entries[@]} screenshot(s)" | |
| mkdir -p "$ART/previews" | |
| # Lift the SIMD benchmark tally (captured next to the PNGs) to the dir | |
| # cn1ss scans for --extra-stats, so it renders in the comment. | |
| cp -f "$ART"/raw-x64/windows-benchmark-stats.txt "$ART/" 2>/dev/null || true | |
| source scripts/lib/cn1ss.sh | |
| cn1ss_setup "$JAVA_HOME/bin/java" "$(pwd)/scripts/common/java" | |
| # Gate for real: differing or missing screenshots FAIL the job (the | |
| # comparison previously only posted diffs to the PR and exited green, | |
| # which let 100+ render changes land unreviewed). | |
| export CN1SS_FAIL_ON_MISMATCH=1 | |
| REF_DIR="$(pwd)/scripts/windows/screenshots" | |
| # Gate like the Linux port: fail on any mismatch/error or a new | |
| # screenshot with no committed golden. Previously this job only | |
| # posted the comparison as a PR comment, so stale goldens sailed | |
| # through green CI. | |
| export CN1SS_FAIL_ON_MISMATCH=1 | |
| export CN1SS_ALLOWED_MISSING=0 | |
| set +e | |
| cn1ss_process_and_report \ | |
| "Native Windows port (cross-compiled)" \ | |
| "$ART/compare.json" "$ART/summary.txt" "$ART/comment.md" \ | |
| "$REF_DIR" "$ART/previews" "$ART" \ | |
| "${entries[@]}" | |
| gate_rc=$? | |
| set -e | |
| fail=0 | |
| if [ "$gate_rc" -ne 0 ]; then | |
| echo "[windows-cross] FATAL: screenshot gate failed (rc=$gate_rc)"; fail=1 | |
| fi | |
| if [ -f "$ART/summary.txt" ] && grep -q "^missing_expected|" "$ART/summary.txt"; then | |
| me="$(grep -c "^missing_expected|" "$ART/summary.txt" || echo 0)" | |
| echo "[windows-cross] FATAL: $me screenshot(s) streamed with no stored golden (missing_expected) -- add them to $REF_DIR."; fail=1 | |
| fi | |
| if [ "$fail" -ne 0 ]; then echo "Windows cross screenshot gate failed."; exit 1; fi |