Skip to content

JSON mapping: codecs, creators, generics, arrays and null semantics #6294

JSON mapping: codecs, creators, generics, arrays and null semantics

JSON mapping: codecs, creators, generics, arrays and null semantics #6294

# 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:
schedule:
- cron: '55 1 * * *'
pull_request:
paths:
# The application these jobs build compiles a Unity project, from an
# archive that unity-gallery-prebuilt.yml makes out of these.
- 'scripts/unity-compat-samples/gallery/**'
- 'maven/cil-translator/**'
- 'maven/unity-compat/**'
- 'maven/build-engine/src/main/java/com/codename1/maven/Unity*'
- 'maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/*Unity*'
- 'scripts/unity-gallery-prebuilt.sh'
- '.github/workflows/unity-gallery-prebuilt.yml'
- '.github/actions/unity-gallery-prebuilt/**'
- '.github/workflows/windows-cross-build-run.yml'
- 'vm/**'
- 'Ports/WindowsPort/**'
- 'maven/windows/**'
- 'scripts/windows/**'
- 'scripts/hellocodenameone/**'
# This job's first step runs through both CI shell helpers, so a change to either has
# to be exercised here rather than merged untested -- the same reason every other
# consumer lists them.
- 'scripts/ci/apt-get-install.sh'
- 'scripts/ci/apt-get-update.sh'
- 'scripts/ci/retry.sh'
- '!vm/**/README.md'
- '!vm/**/readme.md'
- '!vm/**/docs/**'
push:
branches: [ master, main ]
paths:
# The application these jobs build compiles a Unity project, from an
# archive that unity-gallery-prebuilt.yml makes out of these.
- 'scripts/unity-compat-samples/gallery/**'
- 'maven/cil-translator/**'
- 'maven/unity-compat/**'
- 'maven/build-engine/src/main/java/com/codename1/maven/Unity*'
- 'maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/*Unity*'
- 'scripts/unity-gallery-prebuilt.sh'
- '.github/workflows/unity-gallery-prebuilt.yml'
- '.github/actions/unity-gallery-prebuilt/**'
- '.github/workflows/windows-cross-build-run.yml'
- 'vm/**'
- 'Ports/WindowsPort/**'
- 'maven/windows/**'
- 'scripts/ci/apt-get-install.sh'
- 'scripts/ci/apt-get-update.sh'
- 'scripts/ci/retry.sh'
concurrency:
# Only the latest revision needs validation. PR numbers keep forks isolated;
# event names keep a manual/scheduled run from cancelling a push or PR run.
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
env:
# A method the translator culled as unreachable is still emitted as a stub,
# because dispatch tables name it. With this on, the stub aborts with the
# method's name instead of returning 0, so a wrong cull fails the suite that
# reached it rather than shipping a silent null. Ours to enforce, like
# CN1_NATIVE_VERIFY: customer builds keep the plain stub. See
# BytecodeMethod.appendMethodC. Not in the size or perf benchmarks, whose
# binaries should be the ones customers get.
CN1_CULL_TRAP: '1'
jobs:
# The application has a Unity project in it. One Linux job compiles it and
# hands the result to the jobs below as an artifact; none of them installs
# the .NET SDK or builds the Unity modules.
unity-gallery:
uses: ./.github/workflows/unity-gallery-prebuilt.yml
cross-build:
needs: unity-gallery
name: cross-build suite exe (Linux, x64 + WebView2)
runs-on: ubuntu-24.04
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
# Capped well inside the job's 60 minutes. The inner bounds give a stalled mirror a
# second chance; this one guarantees that however they compound, the step cannot eat
# the budget the build itself needs -- which is what happened twice on 2026-08-19,
# each time surfacing as "Artifact not found" in a different job.
timeout-minutes: 20
run: |
set -e
# No explicit index refresh here: apt-get-install.sh does one itself, and doing it
# twice doubles the time a stalling mirror can take before anything is installed.
# No xvfb: nothing in this job opens a window. The sample build's css
# goal compiles theme.css headless, and the PE this job produces is
# run by the Windows jobs downstream, not here.
# Every network call here is bounded and retried. On 2026-08-19 this step sat in
# its first line for a full hour and was cancelled having installed nothing, which
# then failed the screenshot-comment job downstream for a missing artifact. That is
# the same hang apt-get-install.sh was written for -- a hung mirror should cost one
# attempt, not the job -- and this workflow had never adopted it.
bash scripts/ci/apt-get-install.sh cmake ninja-build unzip
# apt.llvm.org is a single host with no mirror, and llvm.sh both adds its repo and
# installs from it, so it is the likeliest thing in this step to stall forever.
RETRY_ATTEMPTS=3 bash scripts/ci/retry.sh \
wget -q --timeout=30 --tries=3 -O llvm.sh https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
# Two attempts of ten minutes, not three of fifteen: the point of a bound is to
# leave the job enough budget to do its actual work afterwards, and 3x900s is
# three quarters of the runner's hour.
RETRY_ATTEMPTS=2 bash scripts/ci/retry.sh timeout 600 sudo ./llvm.sh 19
bash scripts/ci/apt-get-install.sh 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)
env:
# A build-only step: it compiles and then asserts two class files
# exist, so there is no test for a blanket retry to launder. Narrowed
# to resolution failures anyway, on the same principle the steps below
# apply -- this died on `Connection reset` pulling maven-plugin-api
# from Central, which is the canonical set's business and not this
# branch's.
RETRY_ONLY_MATCHING: transient
run: |
cd maven
JAVA_HOME="$JDK_8_HOME" bash ../scripts/ci/retry.sh \
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
# After everything that fills the local Maven repository and before the
# application is built; this job has no .NET SDK (see the action).
- name: Unpack the Unity gallery prebuilt
uses: ./.github/actions/unity-gallery-prebuilt
# 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"
mkdir -p "$HOME/.codenameone"
[ -f "$HOME/.codenameone/guibuilder.jar" ] || : > "$HOME/.codenameone/guibuilder.jar"
RETRY_ONLY_MATCHING=transient bash scripts/ci/retry.sh \
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
# Narrowed to resolution failures, because this step RUNS A TEST. The wrapper
# retries every nonzero exit unless it is told what to look for, so a cross-build or
# translation failure that came and went would have passed on attempt two and taken
# the gate green with it -- laundering exactly the kind of intermittent product bug
# this job exists to catch. The unit test workflow narrows it for the same reason.
RETRY_ONLY_MATCHING: transient
run: |
cd vm
# Through the retry wrapper: this resolves plugins from Maven Central and the runner
# edge intermittently resets the connection mid-download, which Maven treats as a
# permanent resolution failure -- this run died on a truncated plexus-utils with nothing
# compiled yet. A real failure fails the same way on every attempt.
JAVA_HOME="$JDK_8_HOME" bash ../scripts/ci/retry.sh mvn -B -pl tests -am test \
'-Dtest=CleanTargetIntegrationTest#crossBuildsHelloSuiteExe' \
'-Dsurefire.failIfNoSpecifiedTests=false'
test -f "$CN1_CROSS_EXE_OUT"
ls -l "$CN1_CROSS_EXE_OUT"
# The CI test server (scripts/hellocodenameone/backend) the suite streams its
# screenshots to and drives its networking tests against, as a runnable copy
# the Windows job runs with plain java: that job has a JDK and no Maven
# repository with the backend in it. Built here, where the plugin and the
# backend runtime are a Maven install away.
- name: Build the test server
env:
JAVA17_HOME: ${{ env.JDK_17_HOME }}
RETRY_ONLY_MATCHING: transient
run: |
bash scripts/ci/retry.sh scripts/hellocodenameone/backend/server.sh dist "$GITHUB_WORKSPACE/artifacts/cn1ss-server"
test -f "$GITHUB_WORKSPACE/artifacts/cn1ss-server/classes/META-INF/cn1-backend-main"
- 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
artifacts/cn1ss-server/**
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 runs the test server the cross-build
# job built (CN1SS_SERVER_DIST), 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
CN1SS_SERVER_DIST: ${{ github.workspace }}\artifacts\cn1ss-server
CN1_PERFORMANCE_BINARY_OUT: ${{ github.workspace }}\artifacts\windows-port\raw\benchmark-app.exe
CN1_REQUIRE_PERFORMANCE: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}
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: ${{ !cancelled() }}
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
# !cancelled(), for the same reason as linux-build-run.yml: without it GitHub
# skips this job whenever run-on-windows fails, so the run that most needs
# reporting uploads raw evidence but no port-status artifact. The nightly
# sweep then falls back to an older run, and while that one is still inside
# the freshness window the public table keeps showing it -- the current
# Windows failure masked by a stale pass. The workflow still goes red because
# run-on-windows itself failed.
if: >-
!cancelled() &&
(github.event_name == 'pull_request' || github.event_name == 'push' ||
github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
runs-on: ubuntu-24.04
permissions:
# write, because this job publishes the normalized report to the
# port-status-data branch itself (see the publish step below).
contents: write
# write, to dispatch website-docs.yml -- the Port Status page is static,
# so a published report is invisible until Hugo rebuilds.
actions: write
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
# A run that died before its first PNG still persists app-output.log,
# and that log is what normalization reads to produce the fail /
# not-run counts. Bailing out here left the failed capture with no
# port-status artifact at all, so the nightly sweep fell back to an
# older report and the table kept showing it. Carry on with an empty
# entry list when there is a log; only a run with neither has nothing
# to say. (Same handling as linux-build-run.yml.)
if [ ! -f "$ART/raw-x64/app-output.log" ]; then
echo "No screenshots and no app log; nothing to normalize."
exit 0
fi
echo "No screenshots were produced; normalizing from the app log so the failure reaches the table."
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
export CN1SS_PORT_ID=windows-x64
export CN1SS_SUITE_LOG="$ART/raw-x64/app-output.log"
export CN1SS_BINARY_PATH="$ART/raw-x64/benchmark-app.exe"
if [ "${{ github.event_name }}" != "pull_request" ]; then export CN1SS_SKIP_COMMENT=1; fi
# Assertion-only failures count here as they do on every other producer.
# A test like CryptoApiTest can fail while the suite still emits its
# completion marker and every screenshot matches, and without this the
# step exited zero: the workflow stayed green and published a report
# containing failed tests. Linux, Android, JavaScript, iOS and Mac all
# set this; Windows was the one producer that did not.
export CN1SS_FAIL_ON_TEST_PROBLEMS=1
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[@]+"${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
- name: Upload Windows port status
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: port-status-windows-x64
path: artifacts/windows-port/port-status-windows-x64.json
if-no-files-found: warn
retention-days: 14
# Publish from here rather than waiting for port-status-publish.yml.
# That workflow reacts to a workflow_run "completed" event, and GitHub has
# never delivered one for this workflow: ports/windows-x64.json had never
# existed on the data branch, so the public table served the checked-in
# fallback for the Windows x64 column. The report is already on disk in
# this job, so publish it directly and depend on no event.
#
# if: ${{ !cancelled() }} for the same reason the job itself runs on failure -- a
# report recording real failures is the one the table most needs.
- name: Publish the Windows report to the data branch
if: >-
!cancelled() && github.ref == 'refs/heads/master' &&
(github.event_name == 'push' || github.event_name == 'schedule' ||
github.event_name == 'workflow_dispatch')
env:
GH_TOKEN: ${{ github.token }}
PORT_STATUS_PUBLISH: '1'
run: |
set -euo pipefail
report=artifacts/windows-port/port-status-windows-x64.json
if [ ! -f "$report" ]; then
echo "No normalized Windows report to publish." >&2
exit 1
fi
./scripts/hellocodenameone/conformance/publish_port_status.sh "$report"
# Publishing to the data branch is only half the job. The Port Status
# page is STATIC -- Hugo reads the reports at build time -- and
# website-docs.yml is triggered by pushes to master, not by the data
# branch, so a report published here would sit unseen until the next
# daily rebuild. That is the same stale window this whole change
# exists to close. port-status-publish.yml dispatches the rebuild for
# the producers it handles; do the same for the ones that publish
# themselves. In the same step as the publish, so it runs only when
# the publish actually succeeded.
gh workflow run website-docs.yml --ref master -f deploy_production=true