Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .github/workflows/ci-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ name: Release
# Triggered by an eXist-* tag (created by ci-release-prepare.yml).
# Four jobs run in parallel then converge on a single GitHub Release:
# build-linux — Maven Central deploy + zip/tar archives (Ubuntu)
# build-mac — signed + notarized DMG (macOS)
# build-windows — signed installer JAR + Authenticode .exe (Windows)
# build-mac — signed + notarized DMG (macOS; installer excluded)
# build-windows — jarsigner + Authenticode signed installer JAR + .exe (Windows)
# publish-github-release — collects all artifacts, creates the GitHub Release
#
# The installer JAR is built and deployed to Maven Central from build-linux (GPG-signed).
# The Windows job re-builds and jarsigner-signs it for the GitHub Release download.

on:
push:
Expand Down Expand Up @@ -155,6 +158,7 @@ jobs:
-Dexistdb.release.notarize.key-path=/tmp/notarytool.p8 \
-Dexistdb.release.notarize.key-id="$EXISTDB_APPLE_API_KEY_ID" \
-Dexistdb.release.notarize.issuer-id="$EXISTDB_APPLE_API_ISSUER_ID" \
--projects '!exist-installer' \
clean package

- name: Remove Apple API key
Expand Down
12 changes: 8 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ JAVA_HOME=$(/usr/libexec/java_home -v 21) \
-Pskip-build-dist-archives
```

On macOS this still produces an unsigned DMG (`mac-dmg-on-mac` is active by default on Mac runners). Add `-P '!mac-dmg-on-mac'` to skip it.
On macOS, `-P skip-build-dist-archives` also suppresses the `.app` bundle and DMG (sets `skip.mac.dist=true` internally). Use `-P '!mac-dmg-on-mac'` only if you want the archives but not the DMG.

### Build a single module

Expand All @@ -45,8 +45,7 @@ mvn test -pl exist-core -Dtest="org.exist.xquery.XPathQueryTest" -Ddependency-ch

### Distribution artifacts (zip, tar.bz2, DMG)

Produces release archives and, on macOS, an unsigned DMG suitable for local testing.
Output lands in `exist-distribution/target/`.
Produces release archives and platform-specific packages. Output lands in `exist-distribution/target/`.

```bash
JAVA_HOME=$(/usr/libexec/java_home -v 21) \
Expand All @@ -58,7 +57,11 @@ JAVA_HOME=$(/usr/libexec/java_home -v 21) \
-Drevision=7.0.0-SNAPSHOT
```

The DMG is unsigned. For the fully signed and notarized DMG used in releases, see `exist-versioning-release.md`.
**macOS**: the `mac-dmg-on-mac` profile is active by default and produces an unsigned `.app` bundle and DMG. Suppress both with `-P '!mac-dmg-on-mac'`. For the fully signed and notarized DMG used in releases, see `exist-versioning-release.md`.

**Linux**: the `mac-dmg-on-unix` profile is active by default on non-CI Linux machines (suppressed when `env.CI=true`) and produces an unsigned DMG. Requires `hfsplus-tools` (`apt-get install hfsprogs hfsplus` / `yum install hfsutils hfsplus-tools`); warns and skips gracefully if missing. Suppress with `-P '!mac-dmg-on-unix'`.

Both DMG profiles are suppressed automatically by `-P skip-build-dist-archives` via the `skip.mac.dist` property.

### IzPack installer JAR

Expand All @@ -67,6 +70,7 @@ Produces the cross-platform installer JAR in `exist-installer/target/`.
```bash
JAVA_HOME=$(/usr/libexec/java_home -v 21) \
mvn -T1.5C clean package \
-Prelease-build \
-pl exist-installer -am \
-DskipTests \
-Ddependency-check.skip=true \
Expand Down
244 changes: 145 additions & 99 deletions exist-distribution/pom.xml

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions exist-distribution/src/main/scripts/codesign-jansi-mac.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,18 @@ set -e
# for each jar file
for jar in "${1}/jansi-${2}.jar" "${1}/jline-${2}-${5}.jar"
do
# macOS dropped i386 support in 10.15 (Catalina). Remove the dead Mac/x86 slice
# from the JAR before codesigning so it does not trigger signing warnings.
zip -d "${jar}" "org/jline/nativ/Mac/x86/libjlinenative.jnilib" || true

# ensure a clean temp work directory for each jar
if [ -d "${3}/org" ]
then
rm -rf "${3}/org"
fi

# for each native arch
archs=('arm64' 'x86' 'x86_64')
# for each supported native arch (i386/x86 intentionally excluded — see above)
archs=('arm64' 'x86_64')
for arch in "${archs[@]}"
do
# create the temp output dirs
Expand Down
40 changes: 20 additions & 20 deletions exist-distribution/src/main/scripts/create-dmg-mac.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,41 +44,41 @@ tmp_dmg_mount=$tmp_dmg-mount
final_app_dir="$(dirname "$1")/$2.app"

# Copy the produced .app to `volname`.app
cp -r $1 $final_app_dir
cp -r "$1" "$final_app_dir"

# Create a temporary Disk Image
/usr/bin/hdiutil create -fs HFS+ -srcfolder $final_app_dir -volname $2 -ov $tmp_dmg -format UDRW
/usr/bin/hdiutil create -fs HFS+ -srcfolder "$final_app_dir" -volname "$2" -ov "$tmp_dmg" -format UDRW

# Attach the temporary image
/usr/bin/hdiutil attach $tmp_dmg.dmg -mountroot $tmp_dmg_mount
/usr/bin/hdiutil attach "$tmp_dmg.dmg" -mountroot "$tmp_dmg_mount"

# Copy the background, the volume icon and DS_Store files
mkdir -p $tmp_dmg_mount/$2/.DropDMGBackground
cp $3 $tmp_dmg_mount/$2/.DropDMGBackground/
cp $4 $tmp_dmg_mount/$2/.VolumeIcon.icns
cp $5 $tmp_dmg_mount/$2/.DS_Store

# Indicate that we want a custom icon
if [[ -f "/Applications/Xcode.app/Contents/Developer/Tools/SetFile" ]]; then
/Applications/Xcode.app/Contents/Developer/Tools/SetFile -a -c $tmp_dmg_mount/$2
else
/usr/bin/SetFile -a -c $tmp_dmg_mount/$2
fi
mkdir -p "$tmp_dmg_mount/$2/.DropDMGBackground"
cp "$3" "$tmp_dmg_mount/$2/.DropDMGBackground/"
cp "$4" "$tmp_dmg_mount/$2/.VolumeIcon.icns"
cp "$5" "$tmp_dmg_mount/$2/.DS_Store"

# Set the kHasCustomIcon (0x0400) Finder flag so Finder uses .VolumeIcon.icns.
# Uses xattr to write the 32-byte com.apple.FinderInfo blob directly, replacing
# the SetFile tool that was removed in Xcode 12.
xattr -wx com.apple.FinderInfo \
"0000000000000000040000000000000000000000000000000000000000000000" \
"$tmp_dmg_mount/$2"

# Add a symbolic link to the Applications directory
ln -s /Applications $tmp_dmg_mount/$2/Applications
ln -s /Applications "$tmp_dmg_mount/$2/Applications"

# Detach the temporary image
/usr/bin/hdiutil detach $tmp_dmg_mount/$2
/usr/bin/hdiutil detach "$tmp_dmg_mount/$2"

# Compress it to a new image
/usr/bin/hdiutil convert $tmp_dmg.dmg -format UDZO -o $6
/usr/bin/hdiutil convert "$tmp_dmg.dmg" -format UDZO -o "$6"

# Delete the temporary image
rm $tmp_dmg.dmg
rm "$tmp_dmg.dmg"

# Delete the mount point
rm -r $tmp_dmg_mount
rm -r "$tmp_dmg_mount"

# Delete the copied `volname`.app used for the DMG
rm -r $final_app_dir
rm -r "$final_app_dir"
55 changes: 33 additions & 22 deletions exist-distribution/src/main/scripts/create-dmg-unix.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ set -x

if [ ! -e /sbin/mkfs.hfsplus ]
then
>&2 echo "ERROR: Skipping DMG creation because /sbin/mkfs.hfsplus is missing!"
>&2 echo " To install it, you might run:"
>&2 echo " * CentOS & co.: sudo yum install hfsutils hfsplus-tools"
>&2 echo " * Debian, Ubuntu & co.: sudo apt-get install hfsprogs hfsplus"
exit 1
>&2 echo "WARNING: Skipping DMG creation because /sbin/mkfs.hfsplus is missing."
>&2 echo " To install it, you might run:"
>&2 echo " * CentOS & co.: sudo yum install hfsutils hfsplus-tools"
>&2 echo " * Debian, Ubuntu & co.: sudo apt-get install hfsprogs hfsplus"
exit 0
fi

# cleanup any previous DMG before creating a new DMG
Expand All @@ -53,44 +53,55 @@ tmp_dmg_mount=$tmp_dmg-mount
final_app_dir="$(dirname "$1")/$2.app"

# Copy the produced .app to `volname`.app
cp -r $1 $final_app_dir
cp -r "$1" "$final_app_dir"

# Calculate the size for an image and add 10MB to ensure there is enough space!
base_size=$(du -sm $1 | sed 's/\([0-9]*\).*/\1/')
base_size=$(du -sm "$1" | sed 's/\([0-9]*\).*/\1/')
img_size=$(($base_size + 10))

# Create a temporary Disk Image
dd if=/dev/zero of=$tmp_dmg.dmg bs=1M count=$img_size
/sbin/mkfs.hfsplus -v $2 $tmp_dmg.dmg
dd if=/dev/zero of="$tmp_dmg.dmg" bs=1M count=$img_size
/sbin/mkfs.hfsplus -v "$2" "$tmp_dmg.dmg"

# Attach the temporary image
username=$(whoami)
mkdir -p $tmp_dmg_mount
sudo mount -o loop,uid=$username $tmp_dmg.dmg $tmp_dmg_mount
mkdir -p "$tmp_dmg_mount"
sudo mount -o loop,uid=$username "$tmp_dmg.dmg" "$tmp_dmg_mount"

# Copy the app into the image
cp -r $final_app_dir $tmp_dmg_mount
cp -r "$final_app_dir" "$tmp_dmg_mount"

# Copy the background, the volume icon and DS_Store files
mkdir -p $tmp_dmg_mount/$2/.DropDMGBackground
cp $3 $tmp_dmg_mount/$2/.DropDMGBackground/
cp $4 $tmp_dmg_mount/$2/.VolumeIcon.icns
cp $5 $tmp_dmg_mount/$2/.DS_Store
mkdir -p "$tmp_dmg_mount/$2/.DropDMGBackground"
cp "$3" "$tmp_dmg_mount/$2/.DropDMGBackground/"
cp "$4" "$tmp_dmg_mount/$2/.VolumeIcon.icns"
cp "$5" "$tmp_dmg_mount/$2/.DS_Store"

# Set the kHasCustomIcon (0x0400) Finder flag so Finder uses .VolumeIcon.icns.
# Best-effort: requires setfattr from the attr package. Cosmetic only — skip if unavailable.
if command -v setfattr &>/dev/null; then
setfattr -n "com.apple.FinderInfo" \
-v "0x0000000000000000040000000000000000000000000000000000000000000000" \
"$tmp_dmg_mount/$2"
else
>&2 echo "WARNING: setfattr not found; volume will not have a custom icon."
>&2 echo " Install with: apt-get install attr or yum install attr"
fi

# Add a symbolic link to the Applications directory
ln -s /Applications $tmp_dmg_mount/$2/Applications
ln -s /Applications "$tmp_dmg_mount/$2/Applications"

# Detach the temporary image
sudo umount $tmp_dmg_mount
sudo umount "$tmp_dmg_mount"

# Copy it to a new image
cp $tmp_dmg.dmg $6
cp "$tmp_dmg.dmg" "$6"

# Delete the temporary image
rm $tmp_dmg.dmg
rm "$tmp_dmg.dmg"

# Delete the mount point
rm -r $tmp_dmg_mount
rm -r "$tmp_dmg_mount"

# Delete the copied `volname`.app used for the DMG
rm -r $final_app_dir
rm -r "$final_app_dir"
80 changes: 47 additions & 33 deletions exist-installer/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@
<izpack.installation.info.appversion>${project.version}</izpack.installation.info.appversion>
<izpack.installation.info.author.name>${project.organization.name}</izpack.installation.info.author.name>
<izpack.installation.info.author.email>${contact.email}</izpack.installation.info.author.email>

<!-- This module has no Java sources. Suppress the real source/javadoc plugins
activated by the release-build profile; placeholder JARs are produced
instead to satisfy Maven Central requirements. -->
<maven.source.skip>true</maven.source.skip>
<maven.javadoc.skip>true</maven.javadoc.skip>
</properties>

<dependencies>
Expand Down Expand Up @@ -117,26 +123,43 @@
<configuration>
<installFile>${izpack.resources.target}/install.xml</installFile>
<baseDir>${project.basedir}/../exist-distribution/target/exist-distribution-dir</baseDir>
<includeProperties>apache.httpcomponents.core.version,apache.httpcomponents.version,apache.xmlrpc.version,appassembler.version,aspectj.version,git.commit.id,git.commit.id.abbrev,git.closest.tag.name,git.closest.tag.commit.count,git.commit.time,git.commit.id.describe,contact.email,exquery.distribution.version,icu.version,jetty.version,izpack.installation.info.appversion,izpack.installation.info.author.email,izpack.installation.info.author.name,izpack.installation.info.url,izpack.resources.src,izpack.resources.target,izpack.version,jansi.version,jaxb.api.version,jaxb.impl.version,log4j.version,lucene.version,milton.version,project.build.sourceEncoding,project.copyright.name,saxon.version,xmlresolver.version,maven.compiler.release</includeProperties>
<!-- DP: this is effecitvely a whitelist of safe properties to pass to the installer. 5 izpack..., mave.compiler, saxon and xmlresolver are in use. -->
<includeProperties>apache.httpcomponents.core.version,apache.httpcomponents.version,apache.xmlrpc.version,appassembler.version,aspectj.version,git.commit.id,git.commit.id.abbrev,git.closest.tag.name,git.closest.tag.commit.count,git.commit.time,git.commit.id.describe,contact.email,exquery.distribution.version,icu.version,jetty.version,izpack.installation.info.appversion,izpack.installation.info.author.email,izpack.installation.info.author.name,izpack.installation.info.url,izpack.resources.src,izpack.resources.target,izpack.version,jansi.version,jaxb.api.version,jaxb.impl.version,log4j.version,lucene.version,project.build.sourceEncoding,project.copyright.name,saxon.version,xmlresolver.version,maven.compiler.release</includeProperties>
<autoIncludeUrl>true</autoIncludeUrl>
<autoIncludeDevelopers>true</autoIncludeDevelopers>
</configuration>
</plugin>

<!-- Produce placeholder -sources.jar and -javadoc.jar for Maven Central.
Central requires these for all non-pom artifacts; a README is
sufficient when there are no Java sources to document. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>placeholder-sources</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>sources</classifier>
<classesDirectory>${project.basedir}/src/main/resources</classesDirectory>
</configuration>
</execution>
<execution>
<id>placeholder-javadoc</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>javadoc</classifier>
<classesDirectory>${project.basedir}/src/main/resources</classesDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Expand Down Expand Up @@ -179,34 +202,25 @@
<id>exist-release</id>
<build>
<plugins>
<!-- This is needed in a profile to workaround https://github.com/jutzig/github-release-plugin/issues/50 -->
<plugin>
<groupId>de.jutzig</groupId>
<artifactId>github-release-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>github-upload</id>
<phase>deploy</phase>
<goals>
<goal>release</goal>
<goal>exec</goal>
</goals>
<inherited>true</inherited>
<configuration>
<description>
Release Notes: https://exist-db.org/exist/apps/wiki/blogs/eXist/exist${project.version}

Maven Central: https://search.maven.org/search?q=g:org.exist-db
</description>
<releaseName>eXist-db ${project.version}</releaseName>
<tag>eXist-${project.version}</tag>
<fileSets>
<fileSet>
<directory>${project.build.directory}</directory>
<includes>
<include>${project.artifactId}-${project.version}.jar</include>
</includes>
</fileSet>
</fileSets>
<executable>bash</executable>
<arguments>
<argument>-c</argument>
<!-- Create the GitHub release if it does not yet exist (e.g. local
release with CI unavailable), otherwise upload into the existing
one (e.g. CI already created it from the tag push). -->
<argument>file="${project.build.directory}/${project.artifactId}-${project.version}.jar"; gh release create "eXist-${project.version}" --title "eXist-db ${project.version}" --generate-notes "$file" || gh release upload "eXist-${project.version}" "$file" --clobber</argument>
</arguments>
</configuration>
</execution>
</executions>
Expand Down
3 changes: 3 additions & 0 deletions exist-installer/src/main/resources/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
This artifact contains no Java sources or Javadoc.
The eXist-db IzPack installer is a self-contained cross-platform installer JAR.
Project sources: https://github.com/eXist-db/exist
6 changes: 1 addition & 5 deletions exist-parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1199,11 +1199,7 @@
<artifactId>maven-gpg-plugin</artifactId>
<version>3.2.8</version>
</plugin>
<plugin>
<groupId>de.jutzig</groupId>
<artifactId>github-release-plugin</artifactId>
<version>1.6.0</version>
</plugin>

<plugin>
<groupId>org.eluder.coveralls</groupId>
<artifactId>coveralls-maven-plugin</artifactId>
Expand Down
6 changes: 3 additions & 3 deletions exist-service/bin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ unzip commons-daemon-1.6.0-bin-windows.zip

## macOS Binary
The macOS Binary is compiled as a Universal Binary for x86_64 and arm64 from the native source code for unix provided by the Apache Commons Daemon project.
It is compiled for a minimum version of 10.13 of macOS so as to provide some backwards compatibility.
It is compiled for a minimum version of 11.0 of macOS, matching the minimum required by Java 21.

For example:

Expand All @@ -18,8 +18,8 @@ wget https://dlcdn.apache.org/commons/daemon/source/commons-daemon-1.6.0-native-
tar zxvf commons-daemon-1.6.0-native-src.tar.gz

cd commons-daemon-1.6.0-native-src/unix
export CFLAGS="-mmacosx-version-min=10.13 -arch x86_64 -arch arm64"
export LDFLAGS="-mmacosx-version-min=10.13 -arch x86_64 -arch arm64"
export CFLAGS="-mmacosx-version-min=11.0 -arch x86_64 -arch arm64"
export LDFLAGS="-mmacosx-version-min=11.0 -arch x86_64 -arch arm64"
sh support/buildconf.sh
./configure
make
Expand Down
Loading
Loading