-
Notifications
You must be signed in to change notification settings - Fork 82
Expand file tree
/
Copy pathbuild_release.xml
More file actions
420 lines (350 loc) · 19.7 KB
/
Copy pathbuild_release.xml
File metadata and controls
420 lines (350 loc) · 19.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
<!--
build_release.xml
ANT build file used by GitHub Actions to package BEAST X releases for
Mac, Windows and Linux. It is intentionally separate from build.xml so
that CI packaging concerns (pre-built JARs, hardened-runtime signing,
GNU-tar archives) do not pollute the local development build.
Usage (all three targets run on a macOS runner):
ant -f build_release.xml package-mac \
-Dversion=10.5.1 \
-Dapple.signer.app="Developer ID Application: ..."
ant -f build_release.xml package-windows \
-Dversion=10.5.1
ant -f build_release.xml package-linux \
-Dversion=10.5.1
Required property (must be supplied via -D):
version e.g. 10.5.1
Optional properties (all have sensible defaults):
extra_release_tag e.g. -beta4 (default: empty)
dist.dir directory containing pre-built beast.jar / beauti.jar
(default: build/dist)
package-mac-bundled-jvm (optional, depends on package-mac):
Embeds a JDK inside each .app bundle so the app is self-contained and
runs without requiring a system-installed Java.
Required extra property:
jdk.bundle.dir Absolute path to the JDK .jdk directory to embed.
On macOS this is typically a directory such as:
/Library/Java/JavaVirtualMachines/zulu-21.jdk
(install with Homebrew: brew install -cask zulu@21)
The Azul Zulu cask installs a universal binary
(aarch64 + x86_64) so one DMG runs natively on
both Apple Silicon and Intel Macs.
The last path component (e.g. zulu-21.jdk) becomes the PlugIns sub-
directory name and is written into each Info.plist as JVMRuntime so that
universalJavaApplicationStub can locate the bundled JVM.
Example:
ant -f build_release.xml package-mac-bundled-jvm \\
-Dversion=10.5.1 \\
-Djdk.bundle.dir=/Library/Java/JavaVirtualMachines/zulu-21.jdk
-->
<project basedir="." default="package-all" name="BEAST-Release">
<!-- ============================================================
Version / release properties (override with -D on CLI)
============================================================ -->
<property name="version" value="10.5.0"/>
<property name="version_number" value="${version}"/>
<property name="extra_release_tag" value=""/>
<property name="jvm_version" value="1.8+"/>
<property name="copyright" value="Copyright 2002-2025"/>
<!-- Pre-built JARs location -->
<property name="dist.dir" value="build/dist"/>
<!-- ============================================================
Directory layout (mirrors build.xml conventions)
============================================================ -->
<property name="release_dir" value="release"/>
<property name="common_dir" value="${release_dir}/common"/>
<property name="Mac_dir" value="${release_dir}/Mac"/>
<property name="Linux_dir" value="${release_dir}/Linux"/>
<property name="Windows_dir" value="${release_dir}/Windows"/>
<property name="packaging_tools" value="packaging_tools"/>
<property name="Packaging_dir" value="${packaging_tools}/windows"/>
<!-- Package / app names -->
<property name="BEAST_name" value="BEAST"/>
<property name="BEAST_package_name" value="BEAST X"/>
<property name="BEAST_package_name_linux" value="BEAST_X"/>
<property name="BEAUti_name" value="BEAUti"/>
<property name="TreeAnnotator_name" value="TreeAnnotator"/>
<property name="LogCombiner_name" value="LogCombiner"/>
<!-- Platform package staging directories -->
<property name="Mac_package_dir"
value="${Mac_dir}/${BEAST_package_name} v${version}"/>
<property name="Linux_package_dir"
value="${Linux_dir}/${BEAST_package_name_linux}_v${version}"/>
<property name="Windows_package_dir"
value="${Windows_dir}/${BEAST_package_name} v${version}"/>
<!-- ==============================================================
package-linux
Produces: release/BEAST_X_v<version><tag>.tgz
Runs on: macOS or Linux runner
Uses GNU tar format (via ANT tar task) for Linux compatibility.
============================================================== -->
<target name="package-linux" description="Package Linux/Unix release">
<delete dir="${Linux_package_dir}"/>
<mkdir dir="${Linux_package_dir}"/>
<copy todir="${Linux_package_dir}/bin">
<fileset dir="${Linux_dir}/scripts"/>
</copy>
<!-- Preserve executable bits on the shell scripts -->
<chmod dir="${Linux_package_dir}/bin" perm="755" includes="**/**"/>
<copy todir="${Linux_package_dir}/examples">
<fileset dir="examples"/>
</copy>
<copy file="${common_dir}/icons/beast.png" todir="${Linux_package_dir}/images"/>
<copy file="${common_dir}/icons/beauti.png" todir="${Linux_package_dir}/images"/>
<copy file="${common_dir}/icons/utility.png" todir="${Linux_package_dir}/images"/>
<copy file="${dist.dir}/beast.jar" todir="${Linux_package_dir}/lib"/>
<copy file="${dist.dir}/beauti.jar" todir="${Linux_package_dir}/lib"/>
<!--
ANT's built-in tar task is Java-based and writes a POSIX-compatible
archive that GNU tar (Linux) reads correctly. The filemode attribute
on the bin tarfileset preserves executable permissions for scripts.
-->
<tar destfile="${release_dir}/${BEAST_package_name_linux}_v${version}${extra_release_tag}.tgz"
compression="gzip"
longfile="gnu">
<tarfileset dir="${Linux_package_dir}"
prefix="${BEAST_name}v${version}"
filemode="755">
<include name="bin/**"/>
</tarfileset>
<tarfileset dir="${Linux_package_dir}"
prefix="${BEAST_name}v${version}">
<exclude name="bin/**"/>
<include name="**/**"/>
</tarfileset>
</tar>
<echo message="Linux/Unix package: ${release_dir}/${BEAST_package_name_linux}_v${version}${extra_release_tag}.tgz"/>
</target>
<!-- ==============================================================
package-windows
Produces: release/BEAST X v<version><tag>.zip
Runs on: macOS runner (the repo ships the macOS launch4j binaries,
which cross-compile Windows PE executables on macOS).
============================================================== -->
<target name="package-windows" description="Package Windows release (cross-compiled on macOS)">
<delete dir="${Windows_package_dir}"/>
<mkdir dir="${Windows_package_dir}"/>
<!-- launch4j is bundled with macOS binaries in packaging_tools/windows/launch4j -->
<property name="launch4j.dir" location="${Packaging_dir}/launch4j"/>
<taskdef name="launch4j"
classname="net.sf.launch4j.ant.Launch4jTask"
classpath="${launch4j.dir}/launch4j.jar${path.separator}${launch4j.dir}/lib/xstream.jar"/>
<copy todir="${Windows_package_dir}/examples">
<fileset dir="examples"/>
</copy>
<copy todir="${Windows_package_dir}/bin">
<fileset dir="${Windows_dir}/scripts"/>
</copy>
<copy file="${dist.dir}/beast.jar" todir="${Windows_package_dir}/lib"/>
<copy file="${dist.dir}/beauti.jar" todir="${Windows_package_dir}/lib"/>
<!-- BEAUti -->
<launch4j configFile="${Windows_dir}/BEAUti_launch4j.xml"
jar="${dist.dir}/beauti.jar"
outfile="${Windows_package_dir}/${BEAUti_name} v${version}.exe"
fileVersion="${version_number}.0"
txtFileVersion="${version}"
productVersion="${version_number}.0"
txtProductVersion="${version}"/>
<!-- BEAST -->
<launch4j configFile="${Windows_dir}/BEAST_launch4j.xml"
jar="${dist.dir}/beast.jar"
outfile="${Windows_package_dir}/${BEAST_name} v${version}.exe"
fileVersion="${version_number}.0"
txtFileVersion="${version}"
productVersion="${version_number}.0"
txtProductVersion="${version}"/>
<!-- TreeAnnotator -->
<launch4j configFile="${Windows_dir}/TreeAnnotator_launch4j.xml"
jar="${dist.dir}/beast.jar"
outfile="${Windows_package_dir}/${TreeAnnotator_name} v${version}.exe"
fileVersion="${version_number}.0"
txtFileVersion="${version}"
productVersion="${version_number}.0"
txtProductVersion="${version}"/>
<!-- LogCombiner -->
<launch4j configFile="${Windows_dir}/LogCombiner_launch4j.xml"
jar="${dist.dir}/beast.jar"
outfile="${Windows_package_dir}/${LogCombiner_name} v${version}.exe"
fileVersion="${version_number}.0"
txtFileVersion="${version}"
productVersion="${version_number}.0"
txtProductVersion="${version}"/>
<zip destfile="${release_dir}/${BEAST_package_name} v${version}${extra_release_tag}.zip">
<zipfileset dir="${Windows_package_dir}"
prefix="${BEAST_package_name} v${version}"/>
</zip>
<echo message="Windows package: ${release_dir}/${BEAST_package_name} v${version}${extra_release_tag}.zip"/>
</target>
<!-- ==============================================================
package-mac
Produces: release/Mac/BEAST X v<version>/ — staging directory
containing the four unsigned .app bundles.
Runs on: macOS runner only (requires jarbundler).
Signing, DMG creation, notarisation and stapling are all handled
by the GitHub Actions workflow so that this target can be run
locally without any Apple certificates.
============================================================== -->
<target name="package-mac" description="Create Mac .app bundles (unsigned) in staging directory">
<delete dir="${Mac_package_dir}"/>
<mkdir dir="${Mac_package_dir}"/>
<copy todir="${Mac_package_dir}/bin">
<fileset dir="${Mac_dir}/scripts"/>
</copy>
<chmod dir="${Mac_package_dir}/bin" perm="755" includes="**/**"/>
<copy todir="${Mac_package_dir}/examples">
<fileset dir="examples"/>
</copy>
<!-- beast.jar / beauti.jar from the pre-built dist directory -->
<copy file="${dist.dir}/beast.jar" todir="${Mac_package_dir}/lib"/>
<copy file="${dist.dir}/beauti.jar" todir="${Mac_package_dir}/lib"/>
<!-- Additional lib JARs (for BEAUti plugins etc.) -->
<copy todir="${Mac_package_dir}/lib">
<fileset dir="lib">
<include name="*.jar"/>
</fileset>
</copy>
<taskdef name="jarbundler"
classname="com.ultramixer.jarbundler.JarBundler"
classpath="${packaging_tools}/mac/jarbundler-core-3.3.0.jar"/>
<!-- ── BEAST.app ────────────────────────────────────────── -->
<jarbundler dir="${Mac_package_dir}"
name="${BEAST_name} v${version}"
mainclass="dr.app.beast.BeastMain"
stubfile="${packaging_tools}/mac/universalJavaApplicationStub"
useJavaXKey="true"
icon="${common_dir}/icons/beast.icns"
jvmversion="${jvm_version}"
vmoptions="-Xmx2048M -Djava.library.path=/usr/local/lib"
arguments="-window -working -options"
highresolutioncapable="true"
version="${version}"
copyright="${BEAST_name} v${version}, ${copyright}, Alexei J. Drummond, Andrew Rambaut and Marc A. Suchard"
bundleid="dr.app.beast">
<javaproperty name="apple.laf.useScreenMenuBar" value="true"/>
<jarfileset dir="${Mac_package_dir}/lib">
<include name="**/beast.jar"/>
</jarfileset>
</jarbundler>
<!-- ── BEAUti.app ───────────────────────────────────────── -->
<jarbundler dir="${Mac_package_dir}"
name="${BEAUti_name} v${version}"
mainclass="dr.app.beauti.BeautiApp"
stubfile="${packaging_tools}/mac/universalJavaApplicationStub"
useJavaXKey="true"
icon="${common_dir}/icons/beauti.icns"
jvmversion="${jvm_version}"
vmoptions="-Xmx2048M"
arguments=""
version="${version}"
highresolutioncapable="true"
copyright="${BEAUti_name} v${version}, ${copyright}, Alexei J. Drummond, Andrew Rambaut and Marc A. Suchard"
bundleid="dr.app.beauti">
<documenttype name="BEAUti document"
extensions="beauti bti"
iconFile="beautidoc.icns"
role="Editor"/>
<jarfileset dir="${Mac_package_dir}/lib">
<include name="**/beauti.jar"/>
</jarfileset>
<javaproperty name="apple.laf.useScreenMenuBar" value="true"/>
</jarbundler>
<!-- ── LogCombiner.app ──────────────────────────────────── -->
<jarbundler dir="${Mac_package_dir}"
name="${LogCombiner_name} v${version}"
mainclass="dr.app.tools.logcombiner.LogCombiner"
stubfile="${packaging_tools}/mac/universalJavaApplicationStub"
useJavaXKey="true"
icon="${common_dir}/icons/utility.icns"
jvmversion="${jvm_version}"
vmoptions="-Xmx2048M"
highresolutioncapable="true"
arguments=""
version="${version}"
copyright="${LogCombiner_name} v${version}, ${copyright}, Alexei J. Drummond, Andrew Rambaut and Marc A. Suchard"
bundleid="dr.app.tools.logcombiner">
<jarfileset dir="${Mac_package_dir}/lib">
<include name="**/beast.jar"/>
</jarfileset>
<javaproperty name="apple.laf.useScreenMenuBar" value="true"/>
</jarbundler>
<!-- ── TreeAnnotator.app ────────────────────────────────── -->
<jarbundler dir="${Mac_package_dir}"
name="${TreeAnnotator_name} v${version}"
mainclass="dr.app.tools.treeannotator.TreeAnnotator"
stubfile="${packaging_tools}/mac/universalJavaApplicationStub"
useJavaXKey="true"
icon="${common_dir}/icons/utility.icns"
jvmversion="${jvm_version}"
vmoptions="-Xmx4096M"
highresolutioncapable="true"
arguments=""
version="${version}"
copyright="${TreeAnnotator_name} v${version}, ${copyright}, Alexei J. Drummond, Andrew Rambaut and Marc A. Suchard"
bundleid="dr.app.tools.treeannotator">
<jarfileset dir="${Mac_package_dir}/lib">
<include name="**/beast.jar"/>
</jarfileset>
<javaproperty name="apple.laf.useScreenMenuBar" value="true"/>
</jarbundler>
<echo message="Mac bundles created in: ${Mac_package_dir}"/>
<echo message="Next (CI): codesign each .app, hdiutil create DMG, codesign DMG, notarytool, stapler."/>
</target>
<!-- ==============================================================
embed-jvm macrodef
Copies an external JDK into a single .app bundle's PlugIns
directory and writes the JVMRuntime key into its Info.plist.
universalJavaApplicationStub checks for JVMRuntime in the JavaX
dict of Info.plist; when present it uses the bundled JDK instead
of searching the system.
cp -rp is used instead of ANT <copy> so that symlinks and
execute bits inside the JDK tree are preserved exactly.
============================================================== -->
<macrodef name="embed-jvm">
<attribute name="appdir" description="Path to the .app bundle"/>
<sequential>
<mkdir dir="@{appdir}/Contents/PlugIns"/>
<!-- Preserve symlinks and execute bits (required for a valid JDK) -->
<exec executable="cp" failonerror="true">
<arg value="-rp"/>
<arg value="${jdk.bundle.dir}"/>
<arg value="@{appdir}/Contents/PlugIns/"/>
</exec>
<!-- Point universalJavaApplicationStub at the bundled JVM -->
<exec executable="/usr/libexec/PlistBuddy" failonerror="true">
<arg value="-c"/>
<arg value="Add :JavaX:JVMRuntime string ${jdk.plugin.name}"/>
<arg value="@{appdir}/Contents/Info.plist"/>
</exec>
</sequential>
</macrodef>
<!-- ==============================================================
package-mac-bundled-jvm
Produces: release/Mac/BEAST X v<version>/ — same staging dir
as package-mac but with a JDK embedded in each .app.
Requires:
-Djdk.bundle.dir=/path/to/jdk-21.jdk
Note for CI signing:
Apple requires each Mach-O binary inside the PlugIns JDK to be
individually signed (codesign with the -deep flag covers it)
before the outer .app is submitted for notarisation.
============================================================== -->
<target name="package-mac-bundled-jvm" depends="package-mac"
description="Create Mac .app bundles with embedded JDK (self-contained)">
<fail unless="jdk.bundle.dir"
message="Supply the JDK to embed via -Djdk.bundle.dir=/path/to/jdk.jdk"/>
<!-- Derive the PlugIns subfolder name from the last path component -->
<basename property="jdk.plugin.name" file="${jdk.bundle.dir}"/>
<echo message="Embedding JDK '${jdk.plugin.name}' into .app bundles..."/>
<embed-jvm appdir="${Mac_package_dir}/${BEAST_name} v${version}.app"/>
<embed-jvm appdir="${Mac_package_dir}/${BEAUti_name} v${version}.app"/>
<embed-jvm appdir="${Mac_package_dir}/${LogCombiner_name} v${version}.app"/>
<embed-jvm appdir="${Mac_package_dir}/${TreeAnnotator_name} v${version}.app"/>
<echo message="JDK '${jdk.plugin.name}' embedded into all four .app bundles."/>
<echo message="Next (CI): codesign --deep each .app (PlugIns binaries are covered),"/>
<echo message=" hdiutil create DMG, codesign DMG, notarytool, stapler."/>
</target>
<!-- ── Convenience target: build all three packages ────────── -->
<target name="package-all"
depends="package-linux, package-windows, package-mac"
description="Build all three platform packages (macOS runner only)"/>
</project>