Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -300,20 +300,6 @@ jobs:
- name: Build Android Port
run: ant -noinput -buildfile Ports/Android/build.xml jar

- name: Run Java SE device-runner tests
env:
ARTIFACTS_DIR: ${{ github.workspace }}/artifacts/desktop-device-runner
run: ./scripts/run-javase-device-tests.sh

- name: Upload Java SE device-runner artifacts
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: javase-device-runner
path: artifacts/desktop-device-runner
if-no-files-found: warn
retention-days: 14

- name: Packaging Everything
run: zip -j result.zip CodenameOne/javadocs.zip CodenameOne/dist/CodenameOne.jar CodenameOne/updatedLibs.zip Ports/JavaSE/dist/JavaSE.jar build/CodenameOneDist/CodenameOne/demos/CodenameOne_SRC.zip

Expand Down
17 changes: 16 additions & 1 deletion .github/workflows/scripts-ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,29 @@ jobs:
gem install cocoapods xcodeproj --no-document --user-install
pod --version

- name: Compute setup-workspace hash
id: setup_hash
run: |
set -euo pipefail
echo "hash=$(shasum -a 256 scripts/setup-workspace.sh | awk '{print $1}')" >> "$GITHUB_OUTPUT"

- name: Restore cn1-binaries cache
uses: actions/cache@v4
with:
path: ../cn1-binaries
key: cn1-binaries-${{ runner.os }}-${{ hashFiles('scripts/setup-workspace.sh') }}
key: cn1-binaries-${{ runner.os }}-${{ steps.setup_hash.outputs.hash }}
restore-keys: |
cn1-binaries-${{ runner.os }}-

# Temporary disabled due to github issue: https://github.com/actions/runner/issues/4134
# - name: Restore cn1-binaries cache
# uses: actions/cache@v4
# with:
# path: ../cn1-binaries
# key: cn1-binaries-${{ runner.os }}-${{ hashFiles('scripts/setup-workspace.sh') }}
# restore-keys: |
# cn1-binaries-${{ runner.os }}-

- name: Setup workspace
run: ./scripts/setup-workspace.sh -q -DskipTests
# per-step timeout
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.codename1.ui;

import com.codename1.junit.FormTest;
import com.codename1.junit.UITestBase;
import com.codename1.ui.list.DefaultListModel;
import com.codename1.ui.list.ListModel;
Expand All @@ -23,7 +24,7 @@ void initModel() {
suggestionModel = new DefaultListModel<String>(new String[]{"alpha", "beta", "gamma"});
}

@Test
@FormTest
void constructorAppliesCustomFilterAndProvidesEditorAccess() throws Exception {
final List<String> filtered = new ArrayList<String>();
AutoCompleteTextComponent.AutoCompleteFilter filter = new AutoCompleteTextComponent.AutoCompleteFilter() {
Expand All @@ -44,7 +45,7 @@ public boolean filter(String text) {
assertSame(field, component.getEditor(), "getEditor should return the AutoCompleteTextField instance");
}

@Test
@FormTest
void focusAnimationFollowsThemeAndManualOverrides() {
Hashtable theme = new Hashtable();
theme.put("@textComponentAnimBool", "true");
Expand All @@ -60,7 +61,7 @@ void focusAnimationFollowsThemeAndManualOverrides() {
assertTrue(component.isFocusAnimation(), "Explicit true should override theme");
}

@Test
@FormTest
void fluentSettersUpdateUnderlyingField() {
AutoCompleteTextComponent component = new AutoCompleteTextComponent(suggestionModel, AcceptAllFilter.INSTANCE);
Image hintIcon = Image.createImage(2, 2);
Expand All @@ -84,7 +85,7 @@ void fluentSettersUpdateUnderlyingField() {
assertSame(hintIcon, field.getHintIcon());
}

@Test
@FormTest
void propertyMetadataAndValuesReflectFieldState() {
AutoCompleteTextComponent component = new AutoCompleteTextComponent(suggestionModel, AcceptAllFilter.INSTANCE);
component
Expand Down
186 changes: 7 additions & 179 deletions scripts/build-android-app.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ set -euo pipefail

ba_log() { echo "[build-android-app] $1"; }

REPO_ROOT="$(pwd)"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
cd "$REPO_ROOT"

TMPDIR="${TMPDIR:-/tmp}"; TMPDIR="${TMPDIR%/}"
DOWNLOAD_DIR="${TMPDIR%/}/codenameone-tools"
ENV_DIR="$DOWNLOAD_DIR/tools"
EXTRA_MVN_ARGS=("$@")

ENV_FILE="$ENV_DIR/env.sh"
ba_log "Loading workspace environment from $ENV_FILE"
Expand Down Expand Up @@ -74,191 +73,21 @@ fi
export ANDROID_SDK_ROOT ANDROID_HOME="$ANDROID_SDK_ROOT"
ba_log "Using Android SDK at $ANDROID_SDK_ROOT"

CN1_VERSION=$(awk -F'[<>]' '/<version>/{print $3; exit}' maven/pom.xml)
ba_log "Detected Codename One version $CN1_VERSION"

WORK_DIR="$TMPDIR/cn1-hello-android"
rm -rf "$WORK_DIR"; mkdir -p "$WORK_DIR"

GROUP_ID="com.codenameone.examples"
ARTIFACT_ID="hello-codenameone"
PACKAGE_NAME="com.codenameone.examples.hellocodenameone"
MAIN_NAME="HelloCodenameOne"

SOURCE_PROJECT="$REPO_ROOT/Samples/SampleProjectTemplate"
if [ ! -d "$SOURCE_PROJECT" ]; then
ba_log "Source project template not found at $SOURCE_PROJECT" >&2
exit 1
fi
ba_log "Using source project template at $SOURCE_PROJECT"

LOCAL_MAVEN_REPO="${LOCAL_MAVEN_REPO:-$HOME/.m2/repository}"
ba_log "Using local Maven repository at $LOCAL_MAVEN_REPO"
mkdir -p "$LOCAL_MAVEN_REPO"
MAVEN_CMD=(
"$MAVEN_HOME/bin/mvn" -B -ntp
-Dmaven.repo.local="$LOCAL_MAVEN_REPO"
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
)

# --- Generate app skeleton ---
ba_log "Generating Codename One application skeleton via codenameone-maven-plugin"
(
cd "$WORK_DIR"
xvfb-run -a "${MAVEN_CMD[@]}" -q \
com.codenameone:codenameone-maven-plugin:7.0.204:generate-app-project \
-DgroupId="$GROUP_ID" \
-DartifactId="$ARTIFACT_ID" \
-Dversion=1.0-SNAPSHOT \
-DsourceProject="$SOURCE_PROJECT" \
-Dcn1Version="7.0.204" \
"${EXTRA_MVN_ARGS[@]}"
)

APP_DIR="$WORK_DIR/$ARTIFACT_ID"

# --- Namespace-aware CN1 normalization (xmlstarlet) ---
ROOT_POM="$APP_DIR/pom.xml"
NS="mvn=http://maven.apache.org/POM/4.0.0"

if ! command -v xmlstarlet >/dev/null 2>&1; then
sudo apt-get update -y && sudo apt-get install -y xmlstarlet
fi

# Helper to run xmlstarlet with Maven namespace
x() { xmlstarlet ed -L -N "$NS" "$@"; }
q() { xmlstarlet sel -N "$NS" "$@"; }

# 1) Ensure <properties><codenameone.version> exists/updated (root pom)
if [ "$(q -t -v 'count(/mvn:project/mvn:properties)' "$ROOT_POM" 2>/dev/null || echo 0)" = "0" ]; then
x -s "/mvn:project" -t elem -n properties -v "" "$ROOT_POM"
fi
if [ "$(q -t -v 'count(/mvn:project/mvn:properties/mvn:codenameone.version)' "$ROOT_POM" 2>/dev/null || echo 0)" = "0" ]; then
x -s "/mvn:project/mvn:properties" -t elem -n codenameone.version -v "$CN1_VERSION" "$ROOT_POM"
else
x -u "/mvn:project/mvn:properties/mvn:codenameone.version" -v "$CN1_VERSION" "$ROOT_POM"
fi

# 2) Parent must be a LITERAL version (no property allowed)
while IFS= read -r -d '' P; do
x -u "/mvn:project[mvn:parent/mvn:groupId='com.codenameone' and mvn:parent/mvn:artifactId='codenameone-maven-parent']/mvn:parent/mvn:version" -v "$CN1_VERSION" "$P" || true
done < <(find "$APP_DIR" -type f -name pom.xml -print0)

# 3) Point com.codenameone deps/plugins to ${codenameone.version}
while IFS= read -r -d '' P; do
# Dependencies
x -u "/mvn:project//mvn:dependencies/mvn:dependency[starts-with(mvn:groupId,'com.codenameone')]/mvn:version" -v '${codenameone.version}' "$P" 2>/dev/null || true
# Plugins (regular)
x -u "/mvn:project//mvn:build/mvn:plugins/mvn:plugin[starts-with(mvn:groupId,'com.codenameone')]/mvn:version" -v '${codenameone.version}' "$P" 2>/dev/null || true
# Plugins (pluginManagement)
x -u "/mvn:project//mvn:build/mvn:pluginManagement/mvn:plugins/mvn:plugin[starts-with(mvn:groupId,'com.codenameone')]/mvn:version" -v '${codenameone.version}' "$P" 2>/dev/null || true
done < <(find "$APP_DIR" -type f -name pom.xml -print0)

# 4) Ensure common Maven plugins have a version (Maven requires it even if parent not yet resolved)
declare -A PIN=(
[org.apache.maven.plugins:maven-compiler-plugin]=3.11.0
[org.apache.maven.plugins:maven-resources-plugin]=3.3.1
[org.apache.maven.plugins:maven-surefire-plugin]=3.2.5
[org.apache.maven.plugins:maven-failsafe-plugin]=3.2.5
[org.apache.maven.plugins:maven-jar-plugin]=3.3.0
[org.apache.maven.plugins:maven-clean-plugin]=3.3.2
[org.apache.maven.plugins:maven-deploy-plugin]=3.1.2
[org.apache.maven.plugins:maven-install-plugin]=3.1.2
[org.apache.maven.plugins:maven-assembly-plugin]=3.6.0
[org.apache.maven.plugins:maven-site-plugin]=4.0.0-M15
[com.codenameone:codenameone-maven-plugin]='${codenameone.version}'
)

add_version_if_missing() {
local pom="$1" g="$2" a="$3" v="$4"
# build/plugins
if [ "$(q -t -v "count(/mvn:project/mvn:build/mvn:plugins/mvn:plugin[mvn:groupId='$g' and mvn:artifactId='$a']/mvn:version)" "$pom" 2>/dev/null || echo 0)" = "0" ] &&
[ "$(q -t -v "count(/mvn:project/mvn:build/mvn:plugins/mvn:plugin[mvn:groupId='$g' and mvn:artifactId='$a'])" "$pom" 2>/dev/null || echo 0)" != "0" ]; then
x -s "/mvn:project/mvn:build/mvn:plugins/mvn:plugin[mvn:groupId='$g' and mvn:artifactId='$a']" -t elem -n version -v "$v" "$pom" || true
fi
# pluginManagement/plugins
if [ "$(q -t -v "count(/mvn:project/mvn:build/mvn:pluginManagement/mvn:plugins/mvn:plugin[mvn:groupId='$g' and mvn:artifactId='$a']/mvn:version)" "$pom" 2>/dev/null || echo 0)" = "0" ] &&
[ "$(q -t -v "count(/mvn:project/mvn:build/mvn:pluginManagement/mvn:plugins/mvn:plugin[mvn:groupId='$g' and mvn:artifactId='$a'])" "$pom" 2>/dev/null || echo 0)" != "0" ]; then
x -s "/mvn:project/mvn:build/mvn:pluginManagement/mvn:plugins/mvn:plugin[mvn:groupId='$g' and mvn:artifactId='$a']" -t elem -n version -v "$v" "$pom" || true
fi
}

while IFS= read -r -d '' P; do
for ga in "${!PIN[@]}"; do
add_version_if_missing "$P" "${ga%%:*}" "${ga##*:}" "${PIN[$ga]}"
done
done < <(find "$APP_DIR" -type f -name pom.xml -print0)

# 5) Build with the property set so any lingering refs resolve to the local snapshot
EXTRA_MVN_ARGS+=("-Dcodenameone.version=${CN1_VERSION}")

# (Optional) quick non-fatal checks
xmlstarlet sel -N "$NS" -t -v "/mvn:project/mvn:properties/mvn:codenameone.version" -n "$ROOT_POM" || true
xmlstarlet sel -N "$NS" -t -c "/mvn:project/mvn:build/mvn:plugins" -n "$ROOT_POM" | head -n 60 || true


APP_DIR="scripts/hellocodenameone"

[ -d "$APP_DIR" ] || { ba_log "Failed to create Codename One application project" >&2; exit 1; }
[ -f "$APP_DIR/build.sh" ] && chmod +x "$APP_DIR/build.sh"

SETTINGS_FILE="$APP_DIR/common/codenameone_settings.properties"
echo "codename1.arg.android.useAndroidX=true" >> "$SETTINGS_FILE"
[ -f "$SETTINGS_FILE" ] || { ba_log "codenameone_settings.properties not found at $SETTINGS_FILE" >&2; exit 1; }

set_prop() {
local key="$1" value="$2"
if grep -q "^${key}=" "$SETTINGS_FILE"; then
if sed --version >/dev/null 2>&1; then
sed -i -E "s|^${key}=.*$|${key}=${value}|" "$SETTINGS_FILE"
else
sed -i '' -E "s|^${key}=.*$|${key}=${value}|" "$SETTINGS_FILE"
fi
else
printf '\n%s=%s\n' "$key" "$value" >> "$SETTINGS_FILE"
fi
}

# --- Install Codename One application sources ---
PACKAGE_PATH="${PACKAGE_NAME//.//}"
JAVA_DIR="$APP_DIR/common/src/main/java/${PACKAGE_PATH}"
mkdir -p "$JAVA_DIR"
MAIN_FILE_SOURCE="$SCRIPT_DIR/device-runner-app/main/${MAIN_NAME}.java"
if [ ! -f "$MAIN_FILE_SOURCE" ]; then
ba_log "Sample application source not found: $MAIN_FILE_SOURCE" >&2
exit 1
fi
cp "$MAIN_FILE_SOURCE" "$JAVA_DIR/${MAIN_NAME}.java"

ba_log "Setting Codename One application metadata"
set_prop "codename1.packageName" "$PACKAGE_NAME"
set_prop "codename1.mainName" "$MAIN_NAME"
# DeviceRunner integration is handled inside the copied sources, so unit test
# build mode is not required (and is unsupported for local Android builds).
# Ensure trailing newline
tail -c1 "$SETTINGS_FILE" | read -r _ || echo >> "$SETTINGS_FILE"

# --- Install DeviceRunner UI tests ---
TEST_SOURCE_DIR="$SCRIPT_DIR/device-runner-app/tests"
TEST_JAVA_DIR="$APP_DIR/common/src/main/java/${PACKAGE_PATH}/tests"
mkdir -p "$TEST_JAVA_DIR"
if [ ! -d "$TEST_SOURCE_DIR" ]; then
ba_log "DeviceRunner test sources not found: $TEST_SOURCE_DIR" >&2
exit 1
fi
cp "$TEST_SOURCE_DIR"/*.java "$TEST_JAVA_DIR"/
ba_log "Installed DeviceRunner UI tests in $TEST_JAVA_DIR"

# --- Normalize Codename One versions (use Maven Versions Plugin) ---
ba_log "Normalizing Codename One Maven coordinates to $CN1_VERSION"

# --- Build Android gradle project ---
ba_log "Building Android gradle project using Codename One port"
xvfb-run -a "${MAVEN_CMD[@]}" -q -f "$APP_DIR/pom.xml" package \
cd $APP_DIR
xvfb-run -a ./mvnw package \
-DskipTests \
-Dcodename1.platform=android \
-Dcodename1.buildTarget=android-source \
-Dopen=false \
"${EXTRA_MVN_ARGS[@]}"
-U -e
cd ../..

GRADLE_PROJECT_DIR=$(find "$APP_DIR/android/target" -maxdepth 2 -type d -name "*-android-source" | head -n 1 || true)
if [ -z "$GRADLE_PROJECT_DIR" ]; then
Expand All @@ -273,7 +102,7 @@ ba_log "Normalizing Android Gradle project in $GRADLE_PROJECT_DIR"
# --- Install Android instrumentation harness for coverage ---
ANDROID_TEST_SOURCE_DIR="$SCRIPT_DIR/device-runner-app/androidTest"
ANDROID_TEST_ROOT="$GRADLE_PROJECT_DIR/app/src/androidTest"
ANDROID_TEST_JAVA_DIR="$ANDROID_TEST_ROOT/java/${PACKAGE_PATH}"
ANDROID_TEST_JAVA_DIR="$ANDROID_TEST_ROOT/java/com/codenameone/examples/hellocodenameone"
if [ -d "$ANDROID_TEST_ROOT" ]; then
ba_log "Removing template Android instrumentation tests from $ANDROID_TEST_ROOT"
rm -rf "$ANDROID_TEST_ROOT"
Expand Down Expand Up @@ -342,7 +171,6 @@ if [ -n "${GITHUB_OUTPUT:-}" ]; then
{
echo "gradle_project_dir=$GRADLE_PROJECT_DIR"
echo "apk_path=$APK_PATH"
echo "package_name=$PACKAGE_NAME"
} >> "$GITHUB_OUTPUT"
ba_log "Published GitHub Actions outputs for downstream steps"
fi
Loading
Loading