name: Deployment on: push: branches: - main - main-release paths-ignore: - 'docs/**' - 'src/test/**' - 'README.md' tags: - '*' pull_request: merge_group: 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: strategy: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-13] 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: macos-13 # intel image displayName: macOS runs-on: ${{ matrix.os }} outputs: major: ${{ steps.gitversion.outputs.Major }} minor: ${{ steps.gitversion.outputs.Minor }} branchname: ${{ steps.gitversion.outputs.branchName }} name: ${{ matrix.displayName }} installer and portable version 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') uses: awalsh128/cache-apt-pkgs-action@latest 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 - name: Setup JDK uses: actions/setup-java@v4 with: java-version: 23.0.1 distribution: 'temurin' - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 with: gradle-home-cache-cleanup: true - name: Prepare merged jars and modules dir (macOS) # prepareModulesDir is executing a build, which should run through even if no upload to builds.jabref.org is made if: (matrix.os == 'macos-13') || (steps.checksecrets.outputs.secretspresent == 'NO') run: ./gradlew -i -PprojVersion="${{ steps.gitversion.outputs.AssemblySemVer }}" -PprojVersionInfo="${{ steps.gitversion.outputs.InformationalVersion }}" prepareModulesDir - name: Setup macOS key chain if: (matrix.os == 'macos-13') && (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: Setup macOS key chain for app id cert if: (matrix.os == 'macos-13') && (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 dmg (macOS) if: (matrix.os == 'macos-13') && (steps.checksecrets.outputs.secretspresent == 'YES') shell: bash run: | jpackage \ --module org.jabref/org.jabref.Launcher \ --module-path ${{env.JAVA_HOME}}/jmods/:build/jlinkbase/jlinkjars \ --add-modules org.jabref,org.jabref.merged.module \ --add-modules jdk.incubator.vector \ --dest build/distribution \ --app-content buildres/mac/jabrefHost.py \ --app-content buildres/mac/native-messaging-host \ --name JabRef \ --app-version ${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }} \ --verbose \ --mac-sign \ --vendor "JabRef e.V." \ --mac-package-identifier JabRef \ --mac-package-name JabRef \ --type dmg --mac-signing-key-user-name "JabRef e.V. (6792V39SK3)" \ --mac-package-signing-prefix org.jabref \ --mac-entitlements buildres/mac/jabref.entitlements \ --icon src/main/resources/icons/jabref.icns \ --resource-dir buildres/mac \ --file-associations buildres/mac/bibtexAssociations.properties \ --jlink-options --bind-services \ --java-options --add-exports=javafx.base/com.sun.javafx.event=org.jabref.merged.module \ --java-options --add-exports=javafx.controls/com.sun.javafx.scene.control=org.jabref.merged.module \ --java-options --add-opens=javafx.graphics/javafx.scene=org.jabref.merged.module \ --java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref.merged.module \ --java-options --add-opens=javafx.controls/javafx.scene.control.skin=org.jabref.merged.module \ --java-options --add-opens=javafx.controls/com.sun.javafx.scene.control=org.jabref.merged.module \ --java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref \ --java-options --add-exports=javafx.base/com.sun.javafx.event=org.jabref \ --java-options --add-exports=javafx.controls/com.sun.javafx.scene.control=org.jabref \ --java-options --add-opens=javafx.graphics/javafx.scene=org.jabref \ --java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref \ --java-options --add-opens=javafx.controls/com.sun.javafx.scene.control=org.jabref \ --java-options --add-opens=javafx.base/javafx.collections=org.jabref \ --java-options --add-opens=javafx.base/javafx.collections.transformation=org.jabref \ --java-options --add-modules=jdk.incubator.vector - name: Build pkg (macOS) if: (matrix.os == 'macos-13') && (steps.checksecrets.outputs.secretspresent == 'YES') shell: bash run: | jpackage \ --module org.jabref/org.jabref.Launcher \ --module-path ${{env.JAVA_HOME}}/jmods/:build/jlinkbase/jlinkjars \ --add-modules org.jabref,org.jabref.merged.module \ --add-modules jdk.incubator.vector \ --dest build/distribution \ --app-content buildres/mac/jabrefHost.py \ --app-content buildres/mac/native-messaging-host \ --name JabRef \ --app-version ${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }} \ --verbose \ --mac-sign \ --vendor "JabRef e.V." \ --mac-package-identifier JabRef \ --mac-package-name JabRef \ --type pkg --mac-signing-key-user-name "JabRef e.V. (6792V39SK3)" \ --mac-package-signing-prefix org.jabref \ --mac-entitlements buildres/mac/jabref.entitlements \ --icon src/main/resources/icons/jabref.icns \ --resource-dir buildres/mac \ --file-associations buildres/mac/bibtexAssociations.properties \ --jlink-options --bind-services \ --java-options --add-exports=javafx.base/com.sun.javafx.event=org.jabref.merged.module \ --java-options --add-exports=javafx.controls/com.sun.javafx.scene.control=org.jabref.merged.module \ --java-options --add-opens=javafx.graphics/javafx.scene=org.jabref.merged.module \ --java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref.merged.module \ --java-options --add-opens=javafx.controls/javafx.scene.control.skin=org.jabref.merged.module \ --java-options --add-opens=javafx.controls/com.sun.javafx.scene.control=org.jabref.merged.module \ --java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref \ --java-options --add-exports=javafx.base/com.sun.javafx.event=org.jabref \ --java-options --add-exports=javafx.controls/com.sun.javafx.scene.control=org.jabref \ --java-options --add-opens=javafx.graphics/javafx.scene=org.jabref \ --java-options --add-opens=javafx.controls/javafx.scene.control=org.jabref \ --java-options --add-opens=javafx.controls/com.sun.javafx.scene.control=org.jabref \ --java-options --add-opens=javafx.base/javafx.collections=org.jabref \ --java-options --add-opens=javafx.base/javafx.collections.transformation=org.jabref \ --java-options --add-modules=jdk.incubator.vector - name: Build runtime image and installer (linux, Windows) if: (matrix.os != 'macos-13') && (steps.checksecrets.outputs.secretspresent == 'YES') shell: bash run: ./gradlew -i -PprojVersion="${{ steps.gitversion.outputs.AssemblySemVer }}" -PprojVersionInfo="${{ steps.gitversion.outputs.InformationalVersion }}" jpackage jlinkZip - name: Package application image (linux, Windows) if: (matrix.os != 'macos-13') && (steps.checksecrets.outputs.secretspresent == 'YES') shell: bash run: ${{ matrix.archivePortable }} - name: Rename files if: (matrix.os != 'macos-13') && (steps.checksecrets.outputs.secretspresent == 'YES') 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') && (steps.checksecrets.outputs.secretspresent == 'YES') 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: Setup rsync (macOS) if: ${{ (!startsWith(github.ref, 'refs/heads/gh-readonly-queue')) && (steps.checksecrets.outputs.secretspresent == 'YES') && ((matrix.os == 'macos-13') && !((startsWith(github.ref, 'refs/tags/') || inputs.notarization == true))) }} run: brew install rsync - name: Setup rsync (Windows) if: (matrix.os == 'windows-latest') && (steps.checksecrets.outputs.secretspresent == 'YES') && (!startsWith(github.ref, 'refs/heads/gh-readonly-queue')) # 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: Setup SSH key if: ${{ (steps.checksecrets.outputs.secretspresent == 'YES') && (!startsWith(github.ref, 'refs/heads/gh-readonly-queue')) && ((matrix.os != 'macos-13') || !((startsWith(github.ref, 'refs/tags/') || (inputs.notarization == true)))) }} 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') && (!startsWith(github.ref, 'refs/heads/gh-readonly-queue')) 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/${{ steps.gitversion.outputs.branchName }} && 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/${{ steps.gitversion.outputs.branchName }}/ || true - name: Upload to builds.jabref.org (linux, macOS) # macOS: Negated condition of "Upload to GitHub workflow artifacts store (macOS)" # Reason: We either upload the non-notarized files - or notarize the files later (and upload these later) # needs to be on one line; multi line does not work if: ${{ (!startsWith(github.ref, 'refs/heads/gh-readonly-queue')) && (steps.checksecrets.outputs.secretspresent == 'YES') && ((matrix.os == 'ubuntu-latest') || ((matrix.os == 'macos-13') && !((startsWith(github.ref, 'refs/tags/') || inputs.notarization == true)))) }} 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/${{ steps.gitversion.outputs.branchName }} && rsync" -e 'ssh -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }}/ || true - name: Upload to GitHub workflow artifacts store (macOS) if: (matrix.os == 'macos-13') && (steps.checksecrets.outputs.secretspresent == 'YES') && (startsWith(github.ref, 'refs/tags/') || inputs.notarization == true) uses: actions/upload-artifact@v4 with: # tbn = to-be-notarized name: JabRef-macOS-tbn path: build/distribution compression-level: 0 # no compression - name: Upload to GitHub workflow artifacts store if: (steps.checksecrets.outputs.secretspresent != 'YES') uses: actions/upload-artifact@v4 with: name: JabRef-${{ matrix.os }} path: build/distribution compression-level: 0 # no compression announce: name: Comment on pull request runs-on: ubuntu-latest needs: [build] if: ${{ github.event_name == 'pull_request' }} 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: Comment PR if: (steps.checksecrets.outputs.secretspresent == 'YES') uses: thollander/actions-comment-pull-request@v3 with: message: | The build of this PR is available at . comment-tag: download-link mode: recreate notarize: # outsourced in a separate job to be able to rerun if this fails for timeouts name: macOS notarization runs-on: macos-13 needs: [build] if: ${{ startsWith(github.ref, 'refs/tags/') || inputs.notarization == true }} 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: Download from GitHub workflow artifacts store (macOS) if: (steps.checksecrets.outputs.secretspresent == 'YES') uses: actions/download-artifact@master with: name: JabRef-macOS-tbn path: build/distribution/ - name: Notarize dmg if: (steps.checksecrets.outputs.secretspresent == 'YES') shell: bash run: | xcrun notarytool store-credentials "notarytool-profile" --apple-id "vorstand@jabref.org" --team-id "6792V39SK3" --password "${{ secrets.OSX_NOTARIZATION_APP_PWD }}" xcrun notarytool submit build/distribution/JabRef-${{ needs.build.outputs.major }}.${{ needs.build.outputs.minor }}.dmg --keychain-profile "notarytool-profile" --wait xcrun stapler staple build/distribution/JabRef-${{ needs.build.outputs.major }}.${{ needs.build.outputs.minor }}.dmg - name: Notarize pkg if: (steps.checksecrets.outputs.secretspresent == 'YES') shell: bash run: | xcrun notarytool store-credentials "notarytool-profile" --apple-id "vorstand@jabref.org" --team-id "6792V39SK3" --password "${{ secrets.OSX_NOTARIZATION_APP_PWD }}" xcrun notarytool submit build/distribution/JabRef-${{ needs.build.outputs.major }}.${{ needs.build.outputs.minor }}.pkg --keychain-profile "notarytool-profile" --wait xcrun stapler staple build/distribution/JabRef-${{ needs.build.outputs.major }}.${{ needs.build.outputs.minor }}.pkg - name: Upload to builds.jabref.org if: (steps.checksecrets.outputs.secretspresent == 'YES') shell: bash run: | echo "${{ secrets.buildJabRefPrivateKey }}" > sshkey chmod 600 sshkey 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/${{ needs.build.outputs.branchname }} && rsync" -e 'ssh -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ needs.build.outputs.branchname }}/