initializr: default to Java 17, drop Experimental label, bundle Claude Code skill #4730
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
| name: PR CI | |
| on: | |
| workflow_dispatch: | |
| pull_request: | |
| branches: | |
| - master | |
| paths-ignore: | |
| - '.github/workflows/scripts-android.yml' | |
| - '.github/workflows/scripts-ios.yml' | |
| - 'scripts/**' | |
| - '!scripts/setup-workspace.sh' | |
| - 'docs/**' | |
| - '**/*.md' | |
| - '.github/workflows/developer-guide-docs.yml' | |
| - '.github/workflows/website-docs.yml' | |
| - '.github/workflows/initializr-cn1-version-pr.yml' | |
| - 'CodenameOneDesigner/**' | |
| - 'Ports/IOSPort/**' | |
| push: | |
| branches: | |
| - master | |
| paths-ignore: | |
| - '.github/workflows/scripts-android.yml' | |
| - '.github/workflows/scripts-ios.yml' | |
| - 'scripts/**' | |
| - '!scripts/setup-workspace.sh' | |
| - 'docs/**' | |
| - '**/*.md' | |
| - '.github/workflows/developer-guide-docs.yml' | |
| - '.github/workflows/website-docs.yml' | |
| - '.github/workflows/initializr-cn1-version-pr.yml' | |
| - 'CodenameOneDesigner/**' | |
| - 'Ports/IOSPort/**' | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| issues: write | |
| packages: read | |
| jobs: | |
| build-test: | |
| runs-on: ubuntu-latest | |
| container: ghcr.io/codenameone/codenameone/pr-ci-container:latest | |
| defaults: | |
| run: | |
| shell: bash | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| java-version: [8, 17, 21] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Validate Java 25 markdown docs style (CodenameOne + CLDC11) | |
| run: ./.github/scripts/validate-java25-markdown-docs.sh | |
| - name: Set up Java | |
| run: | | |
| if [ "${{ matrix.java-version }}" = "8" ]; then | |
| echo "JAVA_HOME=${JAVA_HOME_8}" >> $GITHUB_ENV | |
| echo "${JAVA_HOME_8}/bin" >> $GITHUB_PATH | |
| elif [ "${{ matrix.java-version }}" = "17" ]; then | |
| echo "JAVA_HOME=${JAVA_HOME_17}" >> $GITHUB_ENV | |
| echo "${JAVA_HOME_17}/bin" >> $GITHUB_PATH | |
| elif [ "${{ matrix.java-version }}" = "21" ]; then | |
| echo "JAVA_HOME=${JAVA_HOME_21}" >> $GITHUB_ENV | |
| echo "${JAVA_HOME_21}/bin" >> $GITHUB_PATH | |
| fi | |
| - name: Cache Maven dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.m2 | |
| key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-m2 | |
| - name: Set up Node | |
| if: ${{ matrix.java-version == 8 }} | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Run Unit Tests | |
| run: | | |
| MVN_ARGS="" | |
| if [ "${{ matrix.java-version }}" != "8" ]; then | |
| MVN_ARGS="-Dspotbugs.skip=true" | |
| fi | |
| cd maven | |
| mvn clean verify -DunitTests=true -pl core-unittests -am -Dmaven.javadoc.skip=true -Plocal-dev-javase $MVN_ARGS | |
| cd .. | |
| - name: Build CSS compiler and smoke native-themes | |
| run: | | |
| cd maven | |
| mvn -B -pl css-compiler -am install -DskipTests -Dmaven.javadoc.skip=true -Plocal-dev-javase | |
| cd .. | |
| ./scripts/build-native-themes.sh | |
| test -f Themes/iOSModernTheme.res || { echo "missing Themes/iOSModernTheme.res"; exit 1; } | |
| test -f Themes/AndroidMaterialTheme.res || { echo "missing Themes/AndroidMaterialTheme.res"; exit 1; } | |
| - name: Prepare Codename One binaries for Maven plugin tests | |
| run: | | |
| set -euo pipefail | |
| rm -rf maven/target/cn1-binaries | |
| mkdir -p maven/target | |
| cp -r /opt/cn1-binaries maven/target/cn1-binaries | |
| - name: Run Maven plugin tests | |
| working-directory: maven | |
| env: | |
| CN1_BINARIES: ${{ github.workspace }}/maven/target/cn1-binaries | |
| run: | | |
| mvn -B -Dmaven.javadoc.skip=true \ | |
| -DunitTests=true \ | |
| -Dcodename1.platform=javase \ | |
| -Dcn1.binaries="${CN1_BINARIES}" \ | |
| -pl codenameone-maven-plugin -am -Plocal-dev-javase test | |
| - name: Run JavaSE port unit tests | |
| # Surface regressions in the simulator-side helpers (CSSWatcher | |
| # localization, MavenUtils designer-jar resolution, JavaSEPort font | |
| # mapping). Without this step the tests in maven/javase compile but | |
| # never execute on PRs. We install the javase module's transitive | |
| # deps first (sqlite-jdbc, factory, etc. -- earlier steps don't | |
| # publish them to the local repo) so the test invocation can resolve | |
| # them, then run javase's tests in isolation. | |
| working-directory: maven | |
| env: | |
| CN1_BINARIES: ${{ github.workspace }}/maven/target/cn1-binaries | |
| run: | | |
| mvn -B -Dmaven.javadoc.skip=true \ | |
| -Dcodename1.platform=javase \ | |
| -Dcn1.binaries="${CN1_BINARIES}" \ | |
| -pl javase -am -Plocal-dev-javase -DskipTests install | |
| mvn -B -Dmaven.javadoc.skip=true \ | |
| -Dcodename1.platform=javase \ | |
| -Dcn1.binaries="${CN1_BINARIES}" \ | |
| -pl javase -Plocal-dev-javase test | |
| - name: Run SpotBugs for ports and Maven plugin | |
| if: ${{ matrix.java-version == 8 }} | |
| working-directory: maven | |
| env: | |
| CN1_BINARIES: ${{ github.workspace }}/maven/target/cn1-binaries | |
| run: | | |
| mvn -B -DskipTests=true \ | |
| -Dcn1.binaries="${CN1_BINARIES}" \ | |
| -Pcompile-android \ | |
| -pl android,ios,codenameone-maven-plugin -am verify | |
| - name: Run SpotBugs for ByteCodeTranslator | |
| if: ${{ matrix.java-version == 8 }} | |
| run: mvn -B -DskipTests=true -f vm/ByteCodeTranslator/pom.xml verify | |
| - name: Run JavaScript Port smoke integration | |
| if: ${{ matrix.java-version == 8 }} | |
| working-directory: vm | |
| run: mvn -B test -pl tests -am -DfailIfNoTests=false -Dsurefire.failIfNoSpecifiedTests=false -Dtest=JavaScriptPortSmokeIntegrationTest | |
| - name: Generate static analysis HTML summaries | |
| if: ${{ always() && matrix.java-version == 8 }} | |
| env: | |
| QUALITY_REPORT_TARGET_DIRS: maven/core-unittests/target:maven/android/target:maven/ios/target:vm/ByteCodeTranslator/target:maven/codenameone-maven-plugin/target | |
| QUALITY_REPORT_SERVER_URL: ${{ github.server_url }} | |
| QUALITY_REPORT_REPOSITORY: ${{ github.repository }} | |
| QUALITY_REPORT_REF: ${{ github.event.pull_request.head.sha || github.sha }} | |
| QUALITY_REPORT_GENERATE_HTML_ONLY: "1" | |
| run: python3 .github/scripts/generate-quality-report.py | |
| - name: Collect quality artifacts | |
| if: ${{ always() && matrix.java-version == 8 }} | |
| run: | | |
| set -euo pipefail | |
| mkdir -p quality-artifacts/static-analysis | |
| mkdir -p quality-artifacts/coverage | |
| shopt -s nullglob | |
| for entry in \ | |
| "core-unittests:maven/core-unittests/target" \ | |
| "android:maven/android/target" \ | |
| "ios:maven/ios/target" \ | |
| "bytecode-translator:vm/ByteCodeTranslator/target" \ | |
| "maven-plugin:maven/codenameone-maven-plugin/target"; do | |
| label="${entry%%:*}" | |
| dir="${entry#*:}" | |
| for filename in spotbugsXml.xml spotbugs.xml; do | |
| if [ -f "${dir}/${filename}" ]; then | |
| cp "${dir}/${filename}" "quality-artifacts/static-analysis/spotbugs-${label}.xml" | |
| break | |
| fi | |
| done | |
| done | |
| if [ -f maven/core-unittests/target/pmd.xml ]; then | |
| cp maven/core-unittests/target/pmd.xml quality-artifacts/static-analysis/ | |
| fi | |
| if [ -f maven/core-unittests/target/checkstyle-result.xml ]; then | |
| cp maven/core-unittests/target/checkstyle-result.xml quality-artifacts/static-analysis/ | |
| fi | |
| if [ -d target/quality-report ]; then | |
| mkdir -p quality-artifacts/static-analysis/html | |
| cp -R target/quality-report/. quality-artifacts/static-analysis/html/ | |
| fi | |
| if [ -d maven/core-unittests/target/site/jacoco ]; then | |
| cp -R maven/core-unittests/target/site/jacoco quality-artifacts/coverage/ | |
| fi | |
| if [ "$(find quality-artifacts -type f | wc -l)" -eq 0 ]; then | |
| echo "No quality artifacts were generated." > quality-artifacts/README.txt | |
| fi | |
| - name: Upload quality artifacts | |
| if: ${{ always() && matrix.java-version == 8 }} | |
| id: upload-quality-artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: quality-artifacts | |
| path: quality-artifacts | |
| - name: Publish quality report previews | |
| if: ${{ always() && matrix.java-version == 8 && github.server_url == 'https://github.com' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) }} | |
| id: publish-quality-previews | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| SERVER_URL: ${{ github.server_url }} | |
| REPOSITORY: ${{ github.repository }} | |
| RUN_ID: ${{ github.run_id }} | |
| RUN_ATTEMPT: ${{ github.run_attempt }} | |
| run: | | |
| set -euo pipefail | |
| if [ "${SERVER_URL}" != "https://github.com" ]; then | |
| echo "HTML previews are only published for github.com instances." | |
| exit 0 | |
| fi | |
| run_dir="runs/${RUN_ID}-${RUN_ATTEMPT}" | |
| tmp_dir=$(mktemp -d) | |
| dest_dir="${tmp_dir}/${run_dir}" | |
| mkdir -p "${dest_dir}" | |
| has_content=0 | |
| if compgen -G "target/quality-report/*.html" > /dev/null; then | |
| mkdir -p "${dest_dir}/static-analysis" | |
| cp target/quality-report/*.html "${dest_dir}/static-analysis/" | |
| has_content=1 | |
| fi | |
| if [ -d maven/core-unittests/target/site/jacoco ] && [ -f maven/core-unittests/target/site/jacoco/index.html ]; then | |
| mkdir -p "${dest_dir}/coverage" | |
| cp -R maven/core-unittests/target/site/jacoco/. "${dest_dir}/coverage/" | |
| has_content=1 | |
| fi | |
| if [ "${has_content}" -eq 0 ]; then | |
| echo "No HTML outputs detected; skipping preview publishing." | |
| exit 0 | |
| fi | |
| printf '%s\n%s\n%s\n' \ | |
| '# Quality report previews' \ | |
| '' \ | |
| 'This branch is automatically managed by the PR CI workflow and may be force-pushed.' \ | |
| > "${tmp_dir}/README.md" | |
| git -C "${tmp_dir}" init -b previews >/dev/null | |
| git -C "${tmp_dir}" config user.name "github-actions[bot]" | |
| git -C "${tmp_dir}" config user.email "github-actions[bot]@users.noreply.github.com" | |
| git -C "${tmp_dir}" add . | |
| git -C "${tmp_dir}" commit -m "Publish quality report previews for run ${RUN_ID} (attempt ${RUN_ATTEMPT})" >/dev/null | |
| remote_url="${SERVER_URL}/${REPOSITORY}.git" | |
| token_remote_url="${remote_url/https:\/\//https://x-access-token:${GITHUB_TOKEN}@}" | |
| git -C "${tmp_dir}" push --force "${token_remote_url}" previews:quality-report-previews >/dev/null | |
| commit_sha=$(git -C "${tmp_dir}" rev-parse HEAD) | |
| raw_base="https://raw.githubusercontent.com/${REPOSITORY}/${commit_sha}/${run_dir}" | |
| preview_base="https://htmlpreview.github.io/?${raw_base}" | |
| { | |
| echo "commit=${commit_sha}" | |
| echo "run_path=${run_dir}" | |
| } >> "$GITHUB_OUTPUT" | |
| if [ -f "${dest_dir}/static-analysis/spotbugs.html" ]; then | |
| echo "spotbugs_url=${preview_base}/static-analysis/spotbugs.html" >> "$GITHUB_OUTPUT" | |
| fi | |
| if [ -f "${dest_dir}/static-analysis/pmd.html" ]; then | |
| echo "pmd_url=${preview_base}/static-analysis/pmd.html" >> "$GITHUB_OUTPUT" | |
| fi | |
| if [ -f "${dest_dir}/static-analysis/checkstyle.html" ]; then | |
| echo "checkstyle_url=${preview_base}/static-analysis/checkstyle.html" >> "$GITHUB_OUTPUT" | |
| fi | |
| if [ -f "${dest_dir}/coverage/index.html" ]; then | |
| echo "jacoco_url=${preview_base}/coverage/index.html" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Generate quality report summary | |
| if: ${{ always() && matrix.java-version == 8 }} | |
| env: | |
| QUALITY_REPORT_TARGET_DIRS: maven/core-unittests/target:maven/android/target:maven/ios/target:vm/ByteCodeTranslator/target:maven/codenameone-maven-plugin/target | |
| QUALITY_REPORT_SERVER_URL: ${{ github.server_url }} | |
| QUALITY_REPORT_REPOSITORY: ${{ github.repository }} | |
| QUALITY_REPORT_REF: ${{ github.event.pull_request.head.sha || github.sha }} | |
| SPOTBUGS_REPORT_URL: ${{ steps.upload-quality-artifacts.outputs.artifact-url }} | |
| PMD_REPORT_URL: ${{ steps.upload-quality-artifacts.outputs.artifact-url }} | |
| CHECKSTYLE_REPORT_URL: ${{ steps.upload-quality-artifacts.outputs.artifact-url }} | |
| JACOCO_REPORT_URL: ${{ steps.upload-quality-artifacts.outputs.artifact-url }} | |
| SPOTBUGS_HTML_URL: ${{ steps.publish-quality-previews.outputs.spotbugs_url }} | |
| PMD_HTML_URL: ${{ steps.publish-quality-previews.outputs.pmd_url }} | |
| CHECKSTYLE_HTML_URL: ${{ steps.publish-quality-previews.outputs.checkstyle_url }} | |
| JACOCO_HTML_URL: ${{ steps.publish-quality-previews.outputs.jacoco_url }} | |
| run: python3 .github/scripts/generate-quality-report.py | |
| - name: Upload quality report summary | |
| if: ${{ always() && matrix.java-version == 8 }} | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: quality-report | |
| path: quality-report.md | |
| - name: Publish quality report comment | |
| if: ${{ github.event_name == 'pull_request' && matrix.java-version == 8 }} | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const { publishQualityComment } = require('./.github/scripts/publish-quality-comment.js'); | |
| await publishQualityComment({ github, context, core }); | |
| - name: Link cn1-binaries | |
| run: ln -s /opt/cn1-binaries ../cn1-binaries | |
| - name: Build CLDC11 JAR | |
| run: | | |
| ANT_OPTS_ARGS="" | |
| if [ "${{ matrix.java-version }}" != "8" ]; then | |
| ANT_OPTS_ARGS="-Djavac.source=1.8 -Djavac.target=1.8" | |
| fi | |
| ant $ANT_OPTS_ARGS -noinput -buildfile Ports/CLDC11/build.xml jar | |
| - name: Build with Ant | |
| run: | | |
| mkdir -p ~/.codenameone | |
| cp maven/UpdateCodenameOne.jar ~/.codenameone/ | |
| ANT_OPTS_ARGS="" | |
| if [ "${{ matrix.java-version }}" != "8" ]; then | |
| ANT_OPTS_ARGS="-Djavac.source=1.8 -Djavac.target=1.8" | |
| fi | |
| xvfb-run ant $ANT_OPTS_ARGS test-javase | |
| - name: Build Release | |
| if: matrix.java-version == 8 | |
| run: ant -noinput -buildfile CodenameOne/build.xml weeklyLibUpdate | |
| - name: Set up Java 25 for JavaDocs | |
| if: matrix.java-version == 8 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: '25' | |
| - name: Build JavaDocs | |
| if: matrix.java-version == 8 | |
| run: ./.github/scripts/build_javadocs.sh | |
| - name: Restore Java 8 after JavaDocs | |
| if: matrix.java-version == 8 | |
| run: | | |
| echo "JAVA_HOME=${JAVA_HOME_8}" >> $GITHUB_ENV | |
| echo "${JAVA_HOME_8}/bin" >> $GITHUB_PATH | |
| - name: Upload JavaDocs artifact | |
| if: matrix.java-version == 8 | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: CodenameOne-javadocs | |
| path: CodenameOne/javadocs.zip | |
| - name: Build iOS Port | |
| run: | | |
| ANT_OPTS_ARGS="" | |
| if [ "${{ matrix.java-version }}" != "8" ]; then | |
| ANT_OPTS_ARGS="-Djavac.source=1.8 -Djavac.target=1.8" | |
| fi | |
| ant $ANT_OPTS_ARGS -noinput -buildfile Ports/iOSPort/build.xml jar | |
| - name: Build iOS VM API | |
| run: mvn -f vm/JavaAPI/pom.xml package | |
| - name: Upload a Build Artifact | |
| if: matrix.java-version == 8 | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: JavaAPI.jar | |
| path: vm/JavaAPI/target/JavaAPI-1.0-SNAPSHOT.jar | |
| - name: Build iOS VM | |
| run: mvn -f vm/ByteCodeTranslator/pom.xml package | |
| - name: Upload a Build Artifact | |
| if: matrix.java-version == 8 | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ByteCodeTranslator.jar | |
| path: vm/ByteCodeTranslator/target/ByteCodeTranslator-1.0-SNAPSHOT.jar | |
| - name: Upload a Build Artifact | |
| if: matrix.java-version == 8 | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: CLDC11.jar | |
| path: Ports/CLDC11/dist/CLDC11.jar | |
| - name: Build Android Port | |
| run: | | |
| ANT_OPTS_ARGS="" | |
| if [ "${{ matrix.java-version }}" != "8" ]; then | |
| ANT_OPTS_ARGS="-Djavac.source=1.8 -Djavac.target=1.8" | |
| fi | |
| ant $ANT_OPTS_ARGS -noinput -buildfile Ports/Android/build.xml jar | |
| - name: Packaging Everything | |
| if: matrix.java-version == 8 | |
| 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 | |
| - name: Copying Files to Server | |
| if: matrix.java-version == 8 | |
| uses: marcodallasanta/ssh-scp-deploy@v1.0.5 | |
| with: | |
| host: ${{ secrets.WP_HOST }} | |
| user: ${{ secrets.WP_USER }} | |
| password: ${{ secrets.WP_PASSWORD }} | |
| local: result.zip | |
| - name: Upload a Build Artifact | |
| if: matrix.java-version == 8 | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: JavaSE.jar | |
| path: Ports/JavaSE/dist/JavaSE.jar | |