# This workflow is a clone of "deployment.yml" # The difference is that this workflow uses JDK early access builds (jdk-ea) to check the build of JabRef # We separated this from the main workflow as we do not want to check on each PR if the JDK build, but only on main name: Deployment (JDK early access builds) on: schedule: - cron: "0 18 * * 1" pull_request: paths: - .github/workflows/deployment-jdk-ea.yml - build.gradle workflow_dispatch: inputs: notarization: type: boolean required: false default: false env: SpringerNatureAPIKey: ${{ secrets.SpringerNatureAPIKey }} AstrophysicsDataSystemAPIKey: ${{ secrets.AstrophysicsDataSystemAPIKey }} IEEEAPIKey: ${{ secrets.IEEEAPIKey }} BiodiversityHeritageApiKey: ${{ secrets.BiodiversityHeritageApiKey}} OSXCERT: ${{ secrets.OSX_SIGNING_CERT }} GRADLE_OPTS: -Xmx4g -Dorg.gradle.vfs.watch=false JAVA_OPTS: -Xmx4g concurrency: group: "${{ github.workflow }}-${{ github.head_ref || github.ref }}" cancel-in-progress: true jobs: build: if: github.repository_owner == 'JabRef' strategy: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest, buildjet-8vcpu-ubuntu-2204-arm] jdk: [23] javafx: [24] include: - os: ubuntu-latest displayName: linux archivePortable: tar -c -C build/distribution JabRef | pigz --rsyncable > build/distribution/JabRef-portable_linux.tar.gz && rm -R build/distribution/JabRef - os: windows-latest displayName: windows archivePortable: 7z a -r build/distribution/JabRef-portable_windows.zip ./build/distribution/JabRef && rm -R build/distribution/JabRef - os: buildjet-8vcpu-ubuntu-2204-arm displayName: "linux-arm" archivePortable: "tar -c -C build/distribution JabRef | pigz --rsyncable > build/distribution/JabRef-portable_linux-arm64.tar.gz && rm -R build/distribution/JabRef" - os: macos-latest displayName: macOS archivePortable: "brew install pigz && tar -c -C build/distribution JabRef.app | pigz --rsyncable > build/distribution/JabRef-portable_macos.tar.gz && rm -R build/distribution/JabRef.app" runs-on: ${{ matrix.os }} outputs: major: ${{ steps.gitversion.outputs.Major }} minor: ${{ steps.gitversion.outputs.Minor }} branchname: ${{ steps.gitversion.outputs.branchName }} name: "JDK ${{ matrix.jdk }}: ${{ matrix.displayName }} JavaFX ${{ matrix.javafx }}" steps: - name: Check secrets presence id: checksecrets shell: bash run: | if [ "$BUILDJABREFPRIVATEKEY" == "" ]; then echo "secretspresent=NO" >> $GITHUB_OUTPUT echo "❌ Secret BUILDJABREFPRIVATEKEY not present" else echo "secretspresent=YES" >> $GITHUB_OUTPUT echo "✔️ Secret BUILDJABREFPRIVATEKEY present" fi env: BUILDJABREFPRIVATEKEY: ${{ secrets.buildJabRefPrivateKey }} - name: Fetch all history for all tags and branches uses: actions/checkout@v4 with: fetch-depth: 0 submodules: 'true' show-progress: 'false' - name: Install pigz and cache (linux) if: (matrix.os == 'ubuntu-latest') || (matrix.os == 'buildjet-8vcpu-ubuntu-2204-arm') uses: awalsh128/cache-apt-pkgs-action@master with: packages: pigz version: 1.0 - name: Install GitVersion uses: gittools/actions/gitversion/setup@v3.0.0 with: versionSpec: "5.x" - name: Run GitVersion id: gitversion uses: gittools/actions/gitversion/execute@v3.0.0 # JDK - name: 'Set up JDK ${{ matrix.jdk }}' uses: actions/setup-java@v4 with: java-version: ${{ matrix.jdk }} distribution: 'temurin' - name: 'Set JDK${{ matrix.jdk }} env var' shell: bash run: echo "JDK${{ matrix.jdk }}=$JAVA_HOME" >> $GITHUB_ENV - name: 'Set JDK${{ matrix.jdk }} in toolchain (linux, Windows)' if: (matrix.os != 'macos-latest') shell: bash run: | sed -i 's/JavaLanguageVersion.of(.*)/JavaLanguageVersion.of(${{ matrix.jdk }})/' build.gradle sed -i 's/JavaVersion.VERSION_(.*)/JavaVersion.VERSION_(${{ matrix.jdk }})/' build.gradle - name: 'Set JDK${{ matrix.jdk }} in toolchain (macOS)' if: (matrix.os == 'macos-latest') shell: bash run: | sed -i'.bak' 's/JavaLanguageVersion.of(.*)/JavaLanguageVersion.of(${{ matrix.jdk }})/' build.gradle sed -i'.bak' 's/JavaVersion.VERSION_(.*)/JavaVersion.VERSION_(${{ matrix.jdk }})/' build.gradle # JavaFX - name: Download and extract JavaFX ${{ matrix.javafx }} if: (matrix.os != 'buildjet-8vcpu-ubuntu-2204-arm') shell: bash run: | cd javafx curl --no-progress-meter https://jdk.java.net/javafx${{ matrix.javafx }}/ > javafx.html case "${{ matrix.os }}" in "ubuntu-latest") OS="linux" EXTRACT="tar xzf *.tar.gz" EXT="tar.gz" ;; "buildjet-8vcpu-ubuntu-2204-arm") OS="linux" EXTRACT="tar xzf *.tar.gz" EXT="tar.gz" echo "There are no ARM EA builds" exit 0 ;; "windows-latest") OS="windows" EXTRACT="unzip -qq *.zip" EXT="zip" ;; "macos-latest") OS="macos" EXTRACT="tar xzf *.tar.gz" EXT="tar.gz" ;; *) echo "Unsupported OS" exit 1 ;; esac echo "OS set to $OS" URL_SDK=$(grep -o "https://download.java.net/java/.*/javafx.*${OS}-x64_bin-sdk.${EXT}" javafx.html | head -n 1) echo "Downloading $URL_SDK..." curl -OJ --no-progress-meter $URL_SDK $EXTRACT rm *.$EXT URL_JMODS=$(grep -o "https://download.java.net/java/.*/javafx.*${OS}-x64_bin-jmods.${EXT}" javafx.html | head -n 1) echo "Downloading $URL_JMODS..." curl -OJ --no-progress-meter $URL_JMODS $EXTRACT rm *.$EXT - name: 'Set JavaFX ${{ matrix.javafx }} (linux, Windows)' if: (matrix.os != 'macos-latest') && (matrix.os != 'buildjet-8vcpu-ubuntu-2204-arm') run: | sed -i '/javafx {/{n;s#version = ".*"#sdk = "javafx/javafx-sdk-${{ matrix.javafx }}"#}' build.gradle sed -i "s#jlink {#jlink { addExtraModulePath 'javafx/javafx-jmods-${{ matrix.javafx }}'#" build.gradle cat build.gradle - name: 'Set JavaFX ${{ matrix.javafx }} (macOS)' if: (matrix.os == 'macos-latest') && (matrix.os != 'buildjet-8vcpu-ubuntu-2204-arm') run: | sed -i '.bak' -e '/javafx {/{n' -e 's#version = ".*"#sdk = "javafx/javafx-sdk-${{ matrix.javafx }}"#;}' build.gradle sed -i '.bak' -e "s#jlink {#jlink { addExtraModulePath 'javafx/javafx-jmods-${{ matrix.javafx }}'#" build.gradle cat build.gradle - name: 'Set JavaFX ${{ matrix.javafx }} (linux-arm)' if: (matrix.os == 'buildjet-8vcpu-ubuntu-2204-arm') # No JavaFX EA build for ARM at https://jdk.java.net/javafx23/, therefore using Maven Central artifact run: | curl -s "https://search.maven.org/solrsearch/select?q=g:org.openjfx+AND+a:javafx&rows=10&core=gav" > /tmp/versions.json jq '[.response.docs[] | select(.v | test(".*-ea\\+.*")) | select(.v | test("^17|^18|^19|^20|^21|^22") | not) | {version: .v}] | group_by(.version | capture("^(?\\d+).*").major) | map(max_by(.version))' < /tmp/versions.json > /tmp/versions-latest.json JAVAFX=$(jq -r '.[-1].version' /tmp/versions-latest.json) echo "Using JavaFX ${JAVAFX}" sed -i "/javafx {/{n;s#version = \".*\"#version = \"${JAVAFX}\"#}" build.gradle && cat build.gradle # Gradle - name: Set up JDK uses: actions/setup-java@v4 with: java-version: 21 distribution: 'temurin' - name: Set up Gradle uses: gradle/actions/setup-gradle@v4 with: gradle-home-cache-cleanup: true - name: Prepare merged jars and modules dir # prepareModulesDir is executing a build, which should run through even if no upload to builds.jabref.org is made if: (steps.checksecrets.outputs.secretspresent == 'NO') run: ./gradlew -i -PprojVersion="${{ steps.gitversion.outputs.AssemblySemVer }}" -PprojVersionInfo="${{ steps.gitversion.outputs.InformationalVersion }}" prepareModulesDir - name: Set up macOS key chain if: (matrix.os == 'macos-latest') && (steps.checksecrets.outputs.secretspresent == 'YES') uses: slidoapp/import-codesign-certs@1923310662e8682dd05b76b612b53301f431cd5d with: p12-file-base64: ${{ secrets.OSX_SIGNING_CERT }} p12-password: ${{ secrets.OSX_CERT_PWD }} keychain-password: jabref - name: Set up macOS key chain for app id cert if: (matrix.os == 'macos-latest') && (steps.checksecrets.outputs.secretspresent == 'YES') uses: slidoapp/import-codesign-certs@1923310662e8682dd05b76b612b53301f431cd5d with: p12-file-base64: ${{ secrets.OSX_SIGNING_CERT_APPLICATION }} p12-password: ${{ secrets.OSX_CERT_PWD }} create-keychain: false keychain-password: jabref - name: Build runtime image and installer shell: bash run: ./gradlew -i -PprojVersion="${{ steps.gitversion.outputs.AssemblySemVer }}" -PprojVersionInfo="${{ steps.gitversion.outputs.InformationalVersion }}" jpackage jlinkZip - name: Package application image shell: bash run: ${{ matrix.archivePortable }} - name: Rename files if: (matrix.os != 'macos-latest') shell: pwsh run: | get-childitem -Path build/distribution/* | rename-item -NewName {$_.name -replace "${{ steps.gitversion.outputs.AssemblySemVer }}","${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}"} get-childitem -Path build/distribution/* | rename-item -NewName {$_.name -replace "portable","${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}-portable"} - name: Repack deb file for Debian if: (matrix.os == 'ubuntu-latest') shell: bash run: | cd build/distribution ar x jabref_${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}_amd64.deb zstd -d < control.tar.zst | xz > control.tar.xz zstd -d < data.tar.zst | xz > data.tar.xz ar -m -c -a sdsd jabref_${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}_amd64_repackaged.deb debian-binary control.tar.xz data.tar.xz rm debian-binary control.tar.* data.tar.* mv -f jabref_${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}_amd64_repackaged.deb jabref_${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}_amd64.deb - name: Rename files with JDK version shell: bash run: | for file in build/distribution/*.*; do base=${file%.*} ext=${file##*.} mv "$file" "${base}-jdk${{ matrix.jdk }}-javafx${{ matrix.javafx }}.${ext}" done # Upload - name: Set up rsync (macOS) if: (matrix.os == 'macos-latest') && (steps.checksecrets.outputs.secretspresent == 'YES') && (github.ref == 'refs/heads/main') run: brew install rsync - name: Set up rsync (Windows) if: (matrix.os == 'windows-latest') && (steps.checksecrets.outputs.secretspresent == 'YES') && (github.ref == 'refs/heads/main') # We want to have rsync available at this place to avoid uploading and downloading from GitHub artifact store (taking > 5 minutes in total) # We cannot use "action-rsyncer", because that requires Docker which is unavailable on Windows # We cannot use "setup-rsync", because that does not work on Windows # We do not use egor-tensin/setup-cygwin@v4, because it replaces the default shell run: choco install --no-progress rsync - name: Set up SSH key if: (steps.checksecrets.outputs.secretspresent == 'YES') && (github.ref == 'refs/heads/main') run: | echo "${{ secrets.buildJabRefPrivateKey }}" > sshkey chmod 600 sshkey - name: Upload to builds.jabref.org (Windows) if: (matrix.os == 'windows-latest') && (steps.checksecrets.outputs.secretspresent == 'YES') && (github.ref == 'refs/heads/main') shell: cmd # for rsync installed by chocolatey, we need the ssh.exe delivered with that installation run: | rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/jdk-ea && rsync" -e 'C:\ProgramData\chocolatey\lib\rsync\tools\bin\ssh.exe -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/jdk-ea/ || true - name: Upload to builds.jabref.org (linux, macOS) if: (matrix.os != 'windows-latest') && (steps.checksecrets.outputs.secretspresent == 'YES') && (github.ref == 'refs/heads/main') shell: bash run: | rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/jdk-ea && rsync" -e 'ssh -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/jdk-ea/ - name: Upload to GitHub workflow artifacts store if: (steps.checksecrets.outputs.secretspresent != 'YES') || (github.ref != 'refs/heads/main') uses: actions/upload-artifact@v4 with: name: JabRef-${{ matrix.os }} path: build/distribution compression-level: 0 # no compression