diff --git a/.github/workflows/website-docs.yml b/.github/workflows/website-docs.yml
index a23dc8ea3b..5c87ebbaa1 100644
--- a/.github/workflows/website-docs.yml
+++ b/.github/workflows/website-docs.yml
@@ -57,6 +57,12 @@ permissions:
jobs:
build:
runs-on: ubuntu-latest
+ # Cap the whole job well below GitHub's 6h default. The site apps build
+ # their JavaScript bundles via the local ParparVM target plus a full
+ # reactor bootstrap, so a healthy run is well under an hour; anything past
+ # this is a hang (e.g. a JS build blocked on an external dependency) and
+ # should fail fast instead of holding a runner for hours.
+ timeout-minutes: 90
env:
CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN || secrets.CF_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID || secrets.CF_ACCOUNT_ID }}
@@ -136,6 +142,10 @@ jobs:
java-version: '25'
- name: Build website
+ # Bounds the heaviest step (javadocs + dev guide + three local ParparVM
+ # JavaScript builds). A healthy run finishes well within this; a hang
+ # here (e.g. a JS build blocked on an external dependency) fails fast.
+ timeout-minutes: 60
run: |
set -euo pipefail
scripts/website/build.sh
diff --git a/scripts/cn1playground/README.md b/scripts/cn1playground/README.md
index 152eb69d36..16ed2b860e 100644
--- a/scripts/cn1playground/README.md
+++ b/scripts/cn1playground/README.md
@@ -189,9 +189,16 @@ Changes made in the property editor are immediately reflected in the preview. Th
## JavaScript Port Tracking
-The current `javascript` module still represents the legacy JavaScript build
-path. While the new ParparVM-backed JavaScript port is being integrated, you
-can compare bundle size against a ParparVM artifact with:
+The `javascript` module now builds through the ParparVM-backed JavaScript port
+by default: `build.sh javascript` (and `build.bat javascript`) pass
+`-Dcodename1.buildTarget=local-javascript`, which routes through the local
+ParparVM bytecode → JavaScript translator instead of the cloud `javascript`
+build target. The website pipeline picks the same target up via the module's
+`codename1.defaultBuildTarget` property. The cloud `javascript` target remains
+available as a fallback by overriding `-Dcodename1.buildTarget=javascript`.
+
+To compare the ParparVM bundle size against a reference (e.g. a cloud-built
+artifact), use:
```bash
PLAYGROUND_PARPARVM_BUNDLE=/path/to/parparvm/dist ./build.sh javascript_compare
@@ -199,9 +206,7 @@ PLAYGROUND_PARPARVM_BUNDLE=/path/to/parparvm/dist ./build.sh javascript_compare
This uses
[`compare-javascript-bundles.sh`](/Users/shai/dev/cn1/scripts/cn1playground/tools/compare-javascript-bundles.sh)
-to report total and JavaScript payload sizes. The long-term goal is to replace
-the legacy `javascript` module build itself with the ParparVM-backed port once
-the runtime and browser harness are complete.
+to report total and JavaScript payload sizes.
## BeanShell Interpreter Tradeoffs
diff --git a/scripts/cn1playground/build.bat b/scripts/cn1playground/build.bat
index fc60f9b54d..50564a0156 100644
--- a/scripts/cn1playground/build.bat
+++ b/scripts/cn1playground/build.bat
@@ -40,7 +40,7 @@ goto :EOF
goto :EOF
:javascript
-!MVNW! package -DskipTests -Dcodename1.platform^=javascript -Dcodename1.buildTarget^=javascript -U -e
+!MVNW! package -DskipTests -Dcodename1.platform^=javascript -Dcodename1.buildTarget^=local-javascript -U -e
goto :EOF
:android
diff --git a/scripts/cn1playground/build.sh b/scripts/cn1playground/build.sh
index 883e7ac3a0..02ef1bfc60 100644
--- a/scripts/cn1playground/build.sh
+++ b/scripts/cn1playground/build.sh
@@ -28,10 +28,13 @@ function linux_device {
}
function javascript {
- "$MVNW" "package" "-DskipTests" "-Dcodename1.platform=javascript" "-Dcodename1.buildTarget=javascript" "-U" "-e"
+ "$MVNW" "package" "-DskipTests" "-Dcodename1.platform=javascript" "-Dcodename1.buildTarget=local-javascript" "-U" "-e"
}
function javascript_compare {
- "javascript"
+ # Build the legacy cloud JavaScript bundle explicitly: the default `javascript`
+ # function now targets local-javascript (ParparVM), so override back to the
+ # cloud `javascript` target to keep this a cloud-vs-ParparVM comparison.
+ "$MVNW" "package" "-DskipTests" "-Dcodename1.platform=javascript" "-Dcodename1.buildTarget=javascript" "-U" "-e"
local legacy_zip=""
legacy_zip="$(ls -1 javascript/target/result.zip javascript/target/cn1playground-javascript-*.zip 2>/dev/null | head -n1 || true)"
if [ -z "$legacy_zip" ] || [ ! -f "$legacy_zip" ]; then
diff --git a/scripts/cn1playground/common/codenameone_settings.properties b/scripts/cn1playground/common/codenameone_settings.properties
index 454539b07f..6f757fb1ac 100644
--- a/scripts/cn1playground/common/codenameone_settings.properties
+++ b/scripts/cn1playground/common/codenameone_settings.properties
@@ -12,6 +12,11 @@ codename1.arg.ios.themeMode=modern
codename1.arg.and.themeMode=modern
codename1.arg.java.version=17
codename1.arg.javascript.inject_proxy=false
+# Local ParparVM JavaScript build (codename1.buildTarget=local-javascript) is
+# gated to Enterprise-tier accounts in the released plugin. The website build
+# logs in via set_cn1_user_token; declare the tier so the released plugin's
+# license gate is satisfied. Newer plugins also accept the login directly.
+codename1.arg.javascript.userLevel=Enterprise
codename1.cssTheme=true
codename1.displayName=CN1Playground
codename1.icon=icon.png
diff --git a/scripts/cn1playground/javascript/pom.xml b/scripts/cn1playground/javascript/pom.xml
index ab622cd9a2..0dc3b1f399 100644
--- a/scripts/cn1playground/javascript/pom.xml
+++ b/scripts/cn1playground/javascript/pom.xml
@@ -18,7 +18,7 @@
1.8
javascript
javascript
- javascript
+ local-javascript
diff --git a/scripts/skindesigner/build.bat b/scripts/skindesigner/build.bat
index fc60f9b54d..50564a0156 100644
--- a/scripts/skindesigner/build.bat
+++ b/scripts/skindesigner/build.bat
@@ -40,7 +40,7 @@ goto :EOF
goto :EOF
:javascript
-!MVNW! package -DskipTests -Dcodename1.platform^=javascript -Dcodename1.buildTarget^=javascript -U -e
+!MVNW! package -DskipTests -Dcodename1.platform^=javascript -Dcodename1.buildTarget^=local-javascript -U -e
goto :EOF
:android
diff --git a/scripts/skindesigner/build.sh b/scripts/skindesigner/build.sh
index 8736620e6f..d8fa09168e 100644
--- a/scripts/skindesigner/build.sh
+++ b/scripts/skindesigner/build.sh
@@ -28,7 +28,7 @@ function linux_device {
}
function javascript {
- "$MVNW" "package" "-DskipTests" "-Dcodename1.platform=javascript" "-Dcodename1.buildTarget=javascript" "-U" "-e"
+ "$MVNW" "package" "-DskipTests" "-Dcodename1.platform=javascript" "-Dcodename1.buildTarget=local-javascript" "-U" "-e"
}
function android {
diff --git a/scripts/skindesigner/common/codenameone_settings.properties b/scripts/skindesigner/common/codenameone_settings.properties
index a344a9f269..110e120d25 100644
--- a/scripts/skindesigner/common/codenameone_settings.properties
+++ b/scripts/skindesigner/common/codenameone_settings.properties
@@ -5,6 +5,11 @@ codename1.arg.ios.newStorageLocation=true
codename1.arg.ios.NSPhotoLibraryUsageDescription=Some functionality of the application requires access to your photo library
codename1.arg.java.version=17
codename1.arg.javascript.inject_proxy=false
+# Local ParparVM JavaScript build (codename1.buildTarget=local-javascript) is
+# gated to Enterprise-tier accounts in the released plugin. The website build
+# logs in via set_cn1_user_token; declare the tier so the released plugin's
+# license gate is satisfied. Newer plugins also accept the login directly.
+codename1.arg.javascript.userLevel=Enterprise
codename1.cssTheme=true
codename1.displayName=SkinDesigner
codename1.icon=icon.png
diff --git a/scripts/skindesigner/javascript/pom.xml b/scripts/skindesigner/javascript/pom.xml
index 4367d34502..d16dd2afa8 100644
--- a/scripts/skindesigner/javascript/pom.xml
+++ b/scripts/skindesigner/javascript/pom.xml
@@ -18,7 +18,7 @@
1.8
javascript
javascript
- javascript
+ local-javascript
diff --git a/scripts/skindesigner/pom.xml b/scripts/skindesigner/pom.xml
index dc8ca8d1a7..899a989736 100644
--- a/scripts/skindesigner/pom.xml
+++ b/scripts/skindesigner/pom.xml
@@ -109,6 +109,25 @@
+
+
+ cn1-local-workspace
+
+
+ cn1.localWorkspace
+ true
+
+
+
+ 8.0-SNAPSHOT
+ 8.0-SNAPSHOT
+
+
javascript
diff --git a/scripts/website/build.sh b/scripts/website/build.sh
index 156f3d31f5..684f41e635 100755
--- a/scripts/website/build.sh
+++ b/scripts/website/build.sh
@@ -717,10 +717,30 @@ build_playground_for_site() {
mkdir -p "${output_dir}"
unzip -q -o "${result_zip}" -d "${output_dir}"
+ # The cloud result.zip is flat (index.html at the root), but the local
+ # ParparVM build (codename1.buildTarget=local-javascript) wraps the bundle in
+ # a single top-level directory (e.g. CN1Playground-js/). Flatten that wrapper
+ # so the served layout is identical regardless of which builder produced it.
+ if [ ! -f "${output_dir}/index.html" ]; then
+ local inner_dir
+ inner_dir="$(find "${output_dir}" -mindepth 1 -maxdepth 1 -type d | head -n1 || true)"
+ if [ -n "${inner_dir}" ] && [ -f "${inner_dir}/index.html" ]; then
+ ( cd "${inner_dir}" && tar cf - . ) | ( cd "${output_dir}" && tar xf - )
+ rm -rf "${inner_dir}"
+ fi
+ fi
+
if [ ! -f "${output_dir}/index.html" ]; then
echo "Playground website bundle is missing index.html after extraction." >&2
exit 1
fi
+
+ # The Playground page (layouts/_default/playground.html) shows the app icon
+ # from /playground-app/icon.png. The cloud bundle shipped one; the local
+ # ParparVM bundle does not, so copy the project icon in when it is absent.
+ if [ ! -f "${output_dir}/icon.png" ] && [ -f "${REPO_ROOT}/scripts/cn1playground/common/icon.png" ]; then
+ cp "${REPO_ROOT}/scripts/cn1playground/common/icon.png" "${output_dir}/icon.png"
+ fi
}
@@ -784,6 +804,19 @@ build_skindesigner_for_site() {
mkdir -p "${output_dir}"
unzip -q -o "${result_zip}" -d "${output_dir}"
+ # The cloud result.zip is flat (index.html at the root), but the local
+ # ParparVM build (codename1.buildTarget=local-javascript) wraps the bundle in
+ # a single top-level directory (e.g. SkinDesigner-js/). Flatten that wrapper
+ # so the served layout is identical regardless of which builder produced it.
+ if [ ! -f "${output_dir}/index.html" ]; then
+ local inner_dir
+ inner_dir="$(find "${output_dir}" -mindepth 1 -maxdepth 1 -type d | head -n1 || true)"
+ if [ -n "${inner_dir}" ] && [ -f "${inner_dir}/index.html" ]; then
+ ( cd "${inner_dir}" && tar cf - . ) | ( cd "${output_dir}" && tar xf - )
+ rm -rf "${inner_dir}"
+ fi
+ fi
+
if [ ! -f "${output_dir}/index.html" ]; then
echo "Skin Designer website bundle is missing index.html after extraction." >&2
exit 1