Index: trunk/.github/workflows/ant-test.yml
===================================================================
--- trunk/.github/workflows/ant-test.yml	(revision 18993)
+++ trunk/.github/workflows/ant-test.yml	(revision 19030)
@@ -20,5 +20,5 @@
       matrix:
         # test against latest update of each major Java version, as well as specific updates of LTS versions:
-        java: [8, 11, 17, 21, 22-ea]
+        java: [8, 11, 17, 21, 22]
         os: [ubuntu-latest, macos-latest, windows-latest]
     name: Java ${{ matrix.java }} on ${{ matrix.os }}
@@ -44,5 +44,5 @@
 
       - name: Install Ant
-        uses: JOSM/JOSMPluginAction/actions/setup-ant@v1
+        uses: JOSM/JOSMPluginAction/actions/setup-ant@v2
 
       - name: Test with Ant
Index: trunk/.github/workflows/ant.yml
===================================================================
--- trunk/.github/workflows/ant.yml	(revision 18993)
+++ trunk/.github/workflows/ant.yml	(revision 19030)
@@ -1,5 +1,4 @@
 name: Java CI Build
 env:
-  junit_platform_version: '1.9.3'
   JAVAFX_VERSION: '17.0.7'
 on:
@@ -60,4 +59,5 @@
           draft: false
           prerelease: ${{ env.josm_prerelease }}
+        if: github.ref == 'refs/heads/master'
 
   build:
@@ -70,6 +70,6 @@
       matrix:
         # test against latest update of each major Java version, as well as specific updates of LTS versions:
-        java: [8, 11, 17, 21, 22-ea]
-        os: [ubuntu-latest, macos-latest, windows-latest]
+        java: [8, 11, 17, 21, 22]
+        os: [ubuntu-latest, macos-14, windows-latest]
     name: Java ${{ matrix.java }} on ${{ matrix.os }}
     steps:
@@ -93,6 +93,14 @@
           java-version: ${{ matrix.java }}
 
+      - name: Setup x64 Java (Mac) ${{ matrix.java }}
+        if: ${{ runner.os == 'macos' && runner.arch == 'ARM64' && always() }}
+        uses: actions/setup-java@v4
+        with:
+          distribution: 'zulu'
+          java-version: ${{ matrix.java }}
+          architecture: x64
+
       - name: Install Ant
-        uses: JOSM/JOSMPluginAction/actions/setup-ant@v1
+        uses: JOSM/JOSMPluginAction/actions/setup-ant@v2
 
       - name: Optimise images
@@ -114,6 +122,8 @@
         # Calls ant with -Dreleasebuild=true if we're a 'tested' build
         run: |
-          export SIGN_KEYSTORE=certificate.p12
-          echo "$SIGN_CERT" | base64 --decode > $SIGN_KEYSTORE
+          if [ ! -z "${SIGN_CERT}" ]; then
+            export SIGN_KEYSTORE=certificate.p12
+            echo "$SIGN_CERT" | base64 --decode > $SIGN_KEYSTORE
+          fi
           if [ "${{ needs.createrelease.outputs.josm_prerelease }}" == "true" ]; then
             ANT="ant"
@@ -122,8 +132,8 @@
           fi
           $ANT dist
-          rm $SIGN_KEYSTORE
+          if [ ! -z "${SIGN_KEYSTORE}" ]; then rm $SIGN_KEYSTORE; fi
 
       - name: Upload jar
-        if: ${{ always() }}
+        if: ${{ always() && needs.createrelease.outputs.upload_url }}
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -144,10 +154,20 @@
           APPLE_ID_TEAM: ${{ secrets.APPLE_ID_TEAM }}
         run: |
-          if [ ! -f tools/openjfx-${JAVAFX_VERSION}_${{ runner.os }}-jmods.zip ]; then
-            curl -o tools/openjfx-${JAVAFX_VERSION}_${{ runner.os }}-jmods.zip https://download2.gluonhq.com/openjfx/${JAVAFX_VERSION}/openjfx-${JAVAFX_VERSION}_osx-x64_bin-jmods.zip
-          fi
-          unzip tools/openjfx-${JAVAFX_VERSION}_${{ runner.os }}-jmods.zip
-          mv javafx-jmods-${JAVAFX_VERSION}/*.jmod $JAVA_HOME/jmods/
-          ./native/macosx/macos-jpackage.sh ${{ needs.createrelease.outputs.josm_revision }}
+          function setup_openjfx() {
+            if [ ! -f tools/openjfx-${JAVAFX_VERSION}_${{ runner.os }}_${2}-jmods.zip ]; then
+              curl -o tools/openjfx-${JAVAFX_VERSION}_${{ runner.os }}_${2}-jmods.zip https://download2.gluonhq.com/openjfx/${JAVAFX_VERSION}/openjfx-${JAVAFX_VERSION}_osx-${1}_bin-jmods.zip
+            fi
+            unzip tools/openjfx-${JAVAFX_VERSION}_${{ runner.os }}_${2}-jmods.zip
+            mv javafx-jmods-${JAVAFX_VERSION}/*.jmod $JAVA_HOME/jmods/
+          }
+
+          if [ ${{ runner.arch }} == "ARM64" ]; then
+            JAVA_HOME="${JAVA_HOME_${{ matrix.java }}_ARM64}" PATH="${JAVA_HOME_${{ matrix.java }}_ARM64}/bin:${PATH}" setup_openjfx aarch64 ARM64
+            JAVA_HOME="${JAVA_HOME_${{ matrix.java }}_X64}" PATH="${JAVA_HOME_${{ matrix.java }}_X64}/bin:${PATH}" setup_openjfx x64 X64
+            JAVA_HOME="${JAVA_HOME_${{ matrix.java }}_ARM64}" ./native/macosx/macos-jpackage.sh ${{ needs.createrelease.outputs.josm_revision }} "${JAVA_HOME_${{ matrix.java }}_X64}"
+          else
+            setup_openjfx x64 X64
+            ./native/macosx/macos-jpackage.sh ${{ needs.createrelease.outputs.josm_revision }}
+          fi
 
       - name: Setup Windows PATH
@@ -173,5 +193,5 @@
 
       - name: Upload macOS app
-        if: ${{ runner.os == 'macos' && matrix.java != '8' && matrix.java != '11' && always() }}
+        if: ${{ runner.os == 'macos' && matrix.java != '8' && matrix.java != '11' && always() && needs.createrelease.outputs.upload_url }}
         uses: actions/upload-release-asset@v1
         env:
@@ -183,6 +203,28 @@
           asset_content_type: application/zip
 
+      - name: Upload macOS app (x64)
+        if: ${{ runner.os == 'macos' && matrix.java != '8' && matrix.java != '11' && always() && runner.arch == 'ARM64' && needs.createrelease.outputs.upload_url }}
+        uses: actions/upload-release-asset@v1
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          upload_url: ${{ needs.createrelease.outputs.upload_url }} # This pulls from the CREATE RELEASE job above, referencing its ID to get its outputs object, which include a `upload_url`.
+          asset_path: app/JOSM_${{ matrix.java }}_x86_64.zip
+          asset_name: JOSM-${{ runner.os}}-java${{ matrix.java }}-${{ needs.createrelease.outputs.josm_revision }}-x64.zip
+          asset_content_type: application/zip
+
+      - name: Upload macOS app (aarch64)
+        if: ${{ runner.os == 'macos' && matrix.java != '8' && matrix.java != '11' && always() && runner.arch == 'ARM64' && needs.createrelease.outputs.upload_url }}
+        uses: actions/upload-release-asset@v1
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          upload_url: ${{ needs.createrelease.outputs.upload_url }} # This pulls from the CREATE RELEASE job above, referencing its ID to get its outputs object, which include a `upload_url`.
+          asset_path: app/JOSM_${{ matrix.java }}_arm64.zip
+          asset_name: JOSM-${{ runner.os}}-java${{ matrix.java }}-${{ needs.createrelease.outputs.josm_revision }}-aarch64.zip
+          asset_content_type: application/zip
+
       - name: Upload Windows Installer executable
-        if: ${{ runner.os == 'windows' && matrix.java != '8' && matrix.java != '11' && always() }}
+        if: ${{ runner.os == 'windows' && matrix.java != '8' && matrix.java != '11' && always() && needs.createrelease.outputs.upload_url }}
         uses: actions/upload-release-asset@v1
         env:
@@ -195,5 +237,5 @@
 
       - name: Upload Windows Installer package
-        if: ${{ runner.os == 'windows' && matrix.java != '8' && matrix.java != '11' && always() }}
+        if: ${{ runner.os == 'windows' && matrix.java != '8' && matrix.java != '11' && always() && needs.createrelease.outputs.upload_url }}
         uses: actions/upload-release-asset@v1
         env:
