diff --git a/.github/workflows/ant-test.yml b/.github/workflows/ant-test.yml index 9cca5c2040a..9b0d016fbce 100644 --- a/.github/workflows/ant-test.yml +++ b/.github/workflows/ant-test.yml @@ -19,7 +19,7 @@ jobs: fail-fast: false 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 }} steps: @@ -43,7 +43,7 @@ jobs: java-version: ${{ matrix.java }} - name: Install Ant - uses: JOSM/JOSMPluginAction/actions/setup-ant@v1 + uses: JOSM/JOSMPluginAction/actions/setup-ant@v2 - name: Test with Ant run: | diff --git a/.github/workflows/ant.yml b/.github/workflows/ant.yml index 5b4db2f5a2c..e5ebc81658d 100644 --- a/.github/workflows/ant.yml +++ b/.github/workflows/ant.yml @@ -1,10 +1,9 @@ name: Java CI Build env: - junit_platform_version: '1.9.3' JAVAFX_VERSION: '17.0.7' on: push: - branches: [master] + branches: [master, windows-installer] defaults: run: @@ -59,6 +58,7 @@ jobs: JOSM release ${{ env.josm_release_tag }} draft: false prerelease: ${{ env.josm_prerelease }} + if: github.ref == 'refs/heads/master' build: needs: createrelease @@ -69,7 +69,7 @@ jobs: fail-fast: false 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 }} steps: @@ -92,8 +92,16 @@ jobs: distribution: 'zulu' 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 if: ${{ runner.os == 'macos' && always() }} @@ -113,18 +121,20 @@ jobs: SIGN_TSA: ${{ secrets.SIGN_TSA }} # 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" else ANT="ant -Dreleasebuild=true" 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 }} uses: actions/upload-release-asset@v1 @@ -134,6 +144,15 @@ jobs: asset_name: JOSM-${{ runner.os}}-java${{ matrix.java }}-${{ needs.createrelease.outputs.josm_revision }}.jar asset_content_type: application/java-archive + - name: Upload jar + if: ${{ always() && !needs.createrelease.outputs.upload_url }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: actions/upload-artifact@v4 + with: + path: dist/josm-custom.jar + name: JOSM-${{ runner.os}}-java${{ matrix.java }}-${{ needs.createrelease.outputs.josm_revision }}.jar + - name: Build and package for macOS if: ${{ runner.os == 'macos' && matrix.java != '8' && matrix.java != '11' && always() }} env: @@ -143,12 +162,22 @@ jobs: APPLE_ID_PW: ${{ secrets.APPLE_ID_PW }} 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 + 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 - 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 }} - name: Setup Windows PATH if: ${{ runner.os == 'windows' && matrix.java != '8' && matrix.java != '11' && always() }} @@ -172,7 +201,7 @@ jobs: ./native/windows/win-jpackage.sh ${{ needs.createrelease.outputs.josm_revision }} - 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: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -182,8 +211,35 @@ jobs: asset_name: JOSM-${{ runner.os}}-java${{ matrix.java }}-${{ needs.createrelease.outputs.josm_revision }}.zip asset_content_type: application/zip + - name: Upload macOS app + if: ${{ runner.os == 'macos' && matrix.java != '8' && matrix.java != '11' && always() && !needs.createrelease.outputs.upload_url }} + uses: actions/upload-artifact@v4 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + path: app/JOSM.zip + name: JOSM-${{ runner.os}}-java${{ matrix.java }}-${{ needs.createrelease.outputs.josm_revision }}.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-artifact@v4 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + path: app/JOSM_${{ matrix.java }}_x86_64.zip + name: JOSM-${{ runner.os}}-java${{ matrix.java }}-${{ needs.createrelease.outputs.josm_revision }}-x64.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-artifact@v4 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + path: app/JOSM_${{ matrix.java }}_arm64.zip + name: JOSM-${{ runner.os}}-java${{ matrix.java }}-${{ needs.createrelease.outputs.josm_revision }}-aarch64.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: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -193,8 +249,17 @@ jobs: asset_name: JOSM-${{ runner.os}}-java${{ matrix.java }}-${{ needs.createrelease.outputs.josm_revision }}.exe asset_content_type: application/vnd.microsoft.portable-executable + - name: Upload Windows Installer executable + if: ${{ runner.os == 'windows' && matrix.java != '8' && matrix.java != '11' && always() && !needs.createrelease.outputs.upload_url }} + uses: actions/upload-artifact@v4 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + path: app/JOSM.exe + name: JOSM-${{ runner.os}}-java${{ matrix.java }}-${{ needs.createrelease.outputs.josm_revision }}.exe + - 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: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -203,3 +268,12 @@ jobs: asset_path: app/JOSM.msi asset_name: JOSM-${{ runner.os}}-java${{ matrix.java }}-${{ needs.createrelease.outputs.josm_revision }}.msi asset_content_type: application/x-ole-storage + + - name: Upload Windows Installer package + if: ${{ runner.os == 'windows' && matrix.java != '8' && matrix.java != '11' && always() && !needs.createrelease.outputs.upload_url }} + uses: actions/upload-artifact@v4 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + path: app/JOSM.msi + name: JOSM-${{ runner.os}}-java${{ matrix.java }}-${{ needs.createrelease.outputs.josm_revision }}.msi diff --git a/native/macosx/macos-jpackage.sh b/native/macosx/macos-jpackage.sh index dbbb948bae6..a058cfcced7 100755 --- a/native/macosx/macos-jpackage.sh +++ b/native/macosx/macos-jpackage.sh @@ -15,7 +15,7 @@ IMPORT_AND_UNLOCK_KEYCHAIN=${IMPORT_AND_UNLOCK_KEYCHAIN:-1} if [ -z "${1-}" ] then - echo "Usage: $0 josm_revision" + echo "Usage: $0 josm_revision [other_arch_jdk]" exit 1 fi @@ -52,46 +52,102 @@ fi set -u -echo "Building and signing app" -# We specifically need the options to not be quoted -- we _want_ the word splitting. -# shellcheck disable=SC2086 -jpackage $JPACKAGEOPTIONS -n "JOSM" --input dist --main-jar josm-custom.jar \ - --main-class org.openstreetmap.josm.gui.MainApplication \ - --icon ./native/macosx/JOSM.icns --type app-image --dest app \ - --java-options "--add-modules java.scripting,java.sql,javafx.controls,javafx.media,javafx.swing,javafx.web" \ - --java-options "--add-exports=java.base/sun.security.action=ALL-UNNAMED" \ - --java-options "--add-exports=java.desktop/com.apple.eawt=ALL-UNNAMED" \ - --java-options "--add-exports=java.desktop/com.sun.imageio.plugins.jpeg=ALL-UNNAMED" \ - --java-options "--add-exports=java.desktop/com.sun.imageio.spi=ALL-UNNAMED" \ - --java-options "--add-opens=java.base/java.lang=ALL-UNNAMED" \ - --java-options "--add-opens=java.base/java.nio=ALL-UNNAMED" \ - --java-options "--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED" \ - --java-options "--add-opens=java.base/jdk.internal.ref=ALL-UNNAMED" \ - --java-options "--add-opens=java.desktop/javax.imageio.spi=ALL-UNNAMED" \ - --java-options "--add-opens=java.desktop/javax.swing.text.html=ALL-UNNAMED" \ - --java-options "--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED" \ - --app-version "$1" \ - --copyright "JOSM, and all its integral parts, are released under the GNU General Public License v2 or later" \ - --vendor "JOSM" \ - --mac-package-identifier de.openstreetmap.josm \ - --mac-package-signing-prefix de.openstreetmap.josm \ - --file-associations native/file-associations/bz2.properties \ - --file-associations native/file-associations/geojson.properties \ - --file-associations native/file-associations/gpx.properties \ - --file-associations native/file-associations/gz.properties \ - --file-associations native/file-associations/jos.properties \ - --file-associations native/file-associations/joz.properties \ - --file-associations native/file-associations/osm.properties \ - --file-associations native/file-associations/xz.properties \ - --file-associations native/file-associations/zip.properties \ - --add-modules java.compiler,java.base,java.datatransfer,java.desktop,java.logging,java.management,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.sql,java.transaction.xa,java.xml,jdk.crypto.ec,jdk.jfr,jdk.jsobject,jdk.unsupported,jdk.unsupported.desktop,jdk.xml.dom,javafx.controls,javafx.media,javafx.swing,javafx.web - -echo "Building done." - -if $SIGNAPP; then - echo "Preparing for notarization" - ditto -c -k --zlibCompressionLevel 9 --keepParent app/JOSM.app app/JOSM.zip - - echo "Uploading to Apple" - xcrun notarytool submit --apple-id "$APPLE_ID" --password "$APPLE_ID_PW" --team-id "$APPLE_ID_TEAM" --wait app/JOSM.zip +function do_jpackage() { + echo "Building app (${JAVA_HOME})" + # We specifically need the options to not be quoted -- we _want_ the word splitting. + # shellcheck disable=SC2086 + "${JAVA_HOME}/bin/jpackage" $JPACKAGEOPTIONS -n "JOSM" --input dist --main-jar josm-custom.jar \ + --main-class org.openstreetmap.josm.gui.MainApplication \ + --icon ./native/macosx/JOSM.icns --type app-image --dest app \ + --java-options "--add-modules java.scripting,java.sql,javafx.controls,javafx.media,javafx.swing,javafx.web" \ + --java-options "--add-exports=java.base/sun.security.action=ALL-UNNAMED" \ + --java-options "--add-exports=java.desktop/com.apple.eawt=ALL-UNNAMED" \ + --java-options "--add-exports=java.desktop/com.sun.imageio.plugins.jpeg=ALL-UNNAMED" \ + --java-options "--add-exports=java.desktop/com.sun.imageio.spi=ALL-UNNAMED" \ + --java-options "--add-opens=java.base/java.lang=ALL-UNNAMED" \ + --java-options "--add-opens=java.base/java.nio=ALL-UNNAMED" \ + --java-options "--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED" \ + --java-options "--add-opens=java.base/jdk.internal.ref=ALL-UNNAMED" \ + --java-options "--add-opens=java.desktop/javax.imageio.spi=ALL-UNNAMED" \ + --java-options "--add-opens=java.desktop/javax.swing.text.html=ALL-UNNAMED" \ + --java-options "--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED" \ + --app-version "$1" \ + --copyright "JOSM, and all its integral parts, are released under the GNU General Public License v2 or later" \ + --vendor "JOSM" \ + --mac-package-identifier de.openstreetmap.josm \ + --mac-package-signing-prefix de.openstreetmap.josm \ + --file-associations native/file-associations/bz2.properties \ + --file-associations native/file-associations/geojson.properties \ + --file-associations native/file-associations/gpx.properties \ + --file-associations native/file-associations/gz.properties \ + --file-associations native/file-associations/jos.properties \ + --file-associations native/file-associations/joz.properties \ + --file-associations native/file-associations/osm.properties \ + --file-associations native/file-associations/xz.properties \ + --file-associations native/file-associations/zip.properties \ + --add-modules java.compiler,java.base,java.datatransfer,java.desktop,java.logging,java.management,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.sql,java.transaction.xa,java.xml,jdk.crypto.ec,jdk.jfr,jdk.jsobject,jdk.unsupported,jdk.unsupported.desktop,jdk.xml.dom,javafx.controls,javafx.media,javafx.swing,javafx.web + echo "Building done (${JAVA_HOME})." +} +function do_signapp() { + echo "Compressing app (${1})" + ditto -c -k --zlibCompressionLevel 9 --keepParent "app/${1}.app" "app/${1}.zip" + if $SIGNAPP; then + echo "Signing app (${1})" + echo "Preparing for notarization" + echo "Uploading to Apple" + xcrun notarytool submit --apple-id "$APPLE_ID" --password "$APPLE_ID_PW" --team-id "$APPLE_ID_TEAM" --wait "app/${1}.zip" + fi +} + +function merge() { + if [ "$(command -v lipo)" ]; then + lipo -create -output "${1}" "${2}" "${3}" + elif [ "$(command -v llvm-lipo-15)" ]; then + llvm-lipo-15 -create -output "${1}" "${2}" "${3}" + fi +} + +function copy() { + # Trim the root path + FILE="${1#*/}" + if [ ! -e "${2}/${FILE}" ]; then + # Only make directories if we aren't looking at the root files + if [[ "${FILE}" == *"/"* ]]; then mkdir -p "${2}/${FILE%/*}"; fi + if file "${1}" | grep -q 'Mach-O' ; then + merge "${2}/${FILE}" "${3}/${FILE}" "${4}/${FILE}" + if file "${1}" | grep -q 'executable'; then + chmod 755 "${2}/${FILE}" + fi + else + cp -a "${1}" "${2}/${FILE}" + fi + fi +} + +function directory_iterate() { + while IFS= read -r -d '' file + do + copy "${file}" "${2}" "${3}" "${4}" & + done < <(find "${1}" -type f,l -print0) + wait +} + +do_jpackage "${1}" +if [ -n "${2}" ]; then + function get_name() { + echo "$("${JAVA_HOME}/bin/java" --version | head -n1 | awk '{print $2}' | awk -F'.' '{print $1}')_$(file "${JAVA_HOME}/bin/java" | awk -F' executable ' '{print $2}')" + } + first="$(get_name)" + JAVA_HOME="${2}" second="$(get_name)" + mv app/JOSM.app "app/JOSM_${first}.app" + JAVA_HOME="${2}" do_jpackage "${1}" + mv app/JOSM.app "app/JOSM_${second}.app" + mkdir app/JOSM.app + (cd app + directory_iterate "JOSM_${first}.app" "JOSM.app" "JOSM_${first}.app" "JOSM_${second}.app" + directory_iterate "JOSM_${second}.app" "JOSM.app" "JOSM_${first}.app" "JOSM_${second}.app" + ) + do_signapp "JOSM_${first}" + do_signapp "JOSM_${second}" fi +do_signapp JOSM