Skip to content

Release builds for Windows and Linux (zip + AppImage) via GitHub Actions - #2

Merged
adrobi merged 25 commits into
masterfrom
release
Oct 31, 2026
Merged

adrobi merged 25 commits into
masterfrom
release

Conversation

@adrobi

@adrobi adrobi commented Oct 31, 2026

Copy link
Copy Markdown
Owner

Releases for Windows and Linux built by GitHub Actions. Stacked on #1 (foundation): once #1 is merged, retarget this PR to master.

What changes

The app runs on Linux

  • Tool names without .exe. Tools are looked up in bin/ first, then on PATH.
  • Settings go to ~/.config/phymlGUI (or $XDG_CONFIG_HOME), and never into the AppImage's temporary folder.
  • mpirun (OpenMPI) replaces mpiexec. A config brought over from Windows loads without errors.
  • "Open folder" uses xdg-open, and the theme follows the desktop palette.
  • PhyML picks the serial or the MPI build according to the MPI setting. The AppImage ships both, so serial PhyML works without OpenMPI.
  • Child programs no longer inherit the PyInstaller bundle's LD_LIBRARY_PATH.

Pinned third-party tools (packaging/third_party.json, every download checked by SHA256)

  • Windows: IQ-TREE, MUSCLE, PhyML-MPI. RAxML-NG 2.0.3 is built natively with MSYS2 plus packaging/patches/raxml-ng-2.0.3-windows.patch.
  • Linux: IQ-TREE, MUSCLE, RAxML-NG. PhyML and PhyML-MPI are built from source.
  • The appimagetool and AppImage runtime are pinned. The MS-MPI installer is pinned for the CI smoke test.

Packages and release (.github/workflows/release.yml)

  • PyInstaller onedir produces two packages:
    • phymlGUI-<v>-windows-x64.zip (phymlgui.exe plus phymlgui-cli.exe);
    • phymlGUI-<v>-x86_64.AppImage.
  • Each package is smoke-tested:
    • --version;
    • PhyML and IQ-TREE runs;
    • a PhyML-MPI run on Linux;
    • the window opens and closes offscreen.
  • On Linux the AppImage also runs in a clean ubuntu:22.04 container.
  • raxml_parity.py compares our Windows RAxML-NG build with the official Linux build: best tree RF = 0, |ΔlnL| < 1e-3, identical bootstrap replicates, and the same fixed-tree lnL.
  • A vX.Y.Z[-suffix] tag creates a draft release that is never published automatically. It holds the zip, the AppImage, SHA256SUMS, and the RAxML-NG source plus patch (AGPL-3.0). Tags with a suffix are marked pre-release.
  • A malformed tag fails the run before anything is built. An already published release is never modified.
  • tests.yml now runs Windows on Python 3.11/3.13 and Linux (ubuntu-22.04) on Python 3.12/3.13.

Verification

  • Local:
    • Windows: 596 passed, 1 skipped.
    • WSL Ubuntu: 597 passed, with real PhyML/MPI, IQ-TREE, MUSCLE and RAxML-NG.
  • A full trial run on GitHub, then the tag v2.0.0-rc1 (run 41192896314):
    • every job green;
    • a draft pre-release with all four files;
    • SHA256SUMS checked against the downloaded files.
  • A whole-branch review was done before merge. Its 2 Critical and 3 Important findings are fixed, each with a test.

Known limitation

On Linux with Python 3.11, the interpreter aborts at exit (bool_dealloc, an over-decref of True/False in a C extension) after every test has passed. It appears only in test files that create the main window; a bare PySide6/QApplication, matplotlib or psutil does not trigger it. Python 3.12+ makes these objects immortal, so the bug does not show there. The root cause was not isolated. Linux CI therefore uses 3.12/3.13, and the README says that running from source on Linux needs Python 3.12+. The packages bundle Python 3.13 and are not affected.

🤖 Generated with Claude Code

adrobi and others added 24 commits October 31, 2026 09:18
…b Actions)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Built and verified in Ubuntu: both binaries build from the v3.3.20260528
sources, a serial aLRT run and a 2-process MPI bootstrap run finish with
exit 0. Single-threaded make: parallel builds crashed GCC with an internal
compiler error in evolve.c. *.sh files are kept LF for Linux runners.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lder, theme

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The full suite (558 tests, incl. real PhyML/OpenMPI, IQ-TREE, MUSCLE runs)
passes on Ubuntu as on Windows: conftest finds tools by platform name and
on PATH, Windows-only test fakes got POSIX variants, and tests that check
Windows semantics pin the platform.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
third_party.json gains windows/linux sections (PhyML-MPI from the v1.2
release, RAxML-NG built from source on Windows; IQ-TREE, MUSCLE, RAxML-NG
official Linux builds and PhyML built from source on Linux). The fetch
script handles tar.gz, build commands and POSIX modes. The RAxML-NG
Windows recipe was verified in MSYS2 UCRT64. Upstream license texts are
bundled. CI now also runs the suite on ubuntu-22.04 with PhyML/OpenMPI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
packaging/package.py stamps the version into a build copy and runs
PyInstaller (one bundle, two executables on Windows: the windowed GUI and
a console phymlgui-cli.exe, since a windowed exe has no stdout). The CLI
gains --version and the entry point a --smoke-gui check. A local 0.0.0-dev
zip with all bundled tools (incl. RAxML-NG built in MSYS2) passed the smoke
test: --version, PhyML+MUSCLE and IQ-TREE runs, window open/close.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
package.py builds an AppDir (AppRun, .desktop, icon, PyInstaller bundle in
usr/bin, tools in usr/bin/bin, licenses) and packs it with the pinned
appimagetool 1.9.1 and type2 runtime 20251108 (--runtime-file, so nothing
unpinned is downloaded at build time). Inside an AppImage the app folder is
never used for settings: with --appimage-extract-and-run it is a throwaway
temp copy. A local 0.0.0-dev AppImage passed the smoke test in Ubuntu incl.
a PhyML-MPI run over OpenMPI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two steps because the binaries run on different CI runners: 'run' executes
an ML search, 50 bootstraps and a fixed-tree evaluation (seed 42) on a
synthetic alignment; 'compare' requires RF 0 and |dlnL| < 1e-3 for the best
tree, identical replicates and the same fixed-tree lnL to 6 decimals. The
locally built raxml-ng.exe matches the official Linux binary.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…elease scripts, child env, MS-MPI

- pick phyml or phyml-mpi by the MPI mode (the AppImage bundles both)
- move the synthetic dataset to tests/e2e/dataset_gen.py so release jobs need no pytest
- start child programs without the PyInstaller LD_LIBRARY_PATH (runner, Open folder)
- install pinned MS-MPI before the Windows smoke test; the bundled PhyML needs msmpi.dll
- pin the RAxML-NG SIMD kernel in the parity runs; a manual run never creates a release
- conftest uses its Windows .exe fallbacks only on Windows

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A trial build before release.yml reaches master; the release job still runs only for tags.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
English Windows runners pipe child output as cp1252; the fake crashed printing
a Cyrillic path. The Cyrillic-path test now forces cp1252 everywhere.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ource runs

On Python 3.11 a C extension's True/False over-decref aborts the interpreter at
exit on Linux (bool_dealloc) after all tests pass; 3.12+ makes those objects
immortal. The packages bundle Python 3.13.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…gger

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lease notes

- README.md and README.ru.md with screenshots of real runs (scripts/make_screenshots.py)
- CHANGELOG.md in Keep a Changelog format
- release notes in English and Russian, with per-version highlights from
  packaging/release_notes/<version>[.ru].md
- version 2.0.0 in the sources; drop the stale 'v1.4' panel labels; 'Наклонная'
  for the slanted tree layout

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@adrobi
adrobi changed the base branch from foundation to master October 31, 2026 11:03
PhyML's configure.ac compiles with -march=native, so the binary built on one
CI runner died with SIGILL (illegal instruction) on another, and the AppImage
would do the same on CPUs older than the build runner. x86-64-v2 keeps the SSE
likelihood code; the script fails if -march=native is left in a Makefile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@adrobi
adrobi merged commit 6bcea14 into master Oct 31, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant