Repository navigation
Package the command: jlink image, AppCDS, man pages, completions, release workflow - #41
Merged
Merged
Conversation
`relix completion zsh` printed bash's script, which zsh runs through bashcompinit when it is sourced. Homebrew installs zsh completions as a file on $fpath instead, which compinit binds by its first line and runs as a function on the first Tab. The script now starts with `#compdef relix`, and ends by completing the word it was called for when it runs inside a completion; sourced, it does what it did before. Part of #15.
…ease ./gradlew releaseArchive builds this platform's archive: the jlink image, with relix-solver-ojalgo and relix-docs, picocli and the H2 driver force-merged; man/man1, one page per command from picocli's ManPageGenerator through Asciidoctor's manpage backend; and completions/ for bash, zsh, fish and PowerShell. H2 is now a runtime dependency, the one driver the image bundles. Each stage of a pipeline starts a JVM, so the image carries an AppCDS archive (lib/relix.jsa), trained at build time on a run that joins and groups a bound CSV file, over the JDK archive jlink generates. The launcher maps it and sends the JVM's warnings to standard error rather than into the rows. The generated launchers are patched: the sh one resolves a relative symbolic link, as Homebrew installs it, and the Windows one no longer runs from its own bin directory, which took relative paths and .relix/ discovery away from the user's. ./gradlew packageTest unpacks the archive with the system's tar and runs its launcher: a script on stdin over a catalog in a temporary tree (a CSV source and an H2 connection, trusted first), tsv out; OPTIMIZE and relix doc, for the providers jlink would drop unnoticed; -Xshare:on with the command's classes loaded from the archive, and the same flag refusing a missing one; and man over every page. CI runs it on each platform. The Release workflow builds and tests the five platform archives. On a tag it attaches them and checksums.txt to the GitHub Release and pushes the formula and the manifest, written whole from packaging/, to the tap and the bucket; run by hand it is a dry run, which checks their checksums against the archives and publishes nothing. Part of #15.
This was referenced Oct 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #15 (S11). It leaves the issue open until the dry-run release has run from
main.What it adds
./gradlew releaseArchivebuildsrelix-<version>-<platform>.tar.gz(.zipon Windows). It contains:relix-solver-ojalgoandrelix-docs, and picocli and H2 force-mergedman/man1, one page per command, from picocli'sManPageGeneratorthrough Asciidoctor'smanpagebackendcompletions/for bash, zsh, fish and PowerShellH2 becomes a runtime dependency: it is the one driver the image bundles.
AppCDS. The image carries
lib/relix.jsa, trained at build time on top of the JDK archive that jlink generates. The launcher passes-XX:SharedArchiveFile. The JVM's warnings go to stderr instead of stdout, where they would mix with the rows. On macOS arm64, the training run's script started about 19% faster than with-Xshare:off(0.67 s against 0.82 s). Nothing asserts a time.Launcher fixes.
bin.install_symlinkinstalls it..batranpushd %DIR%, so it ran from its ownbindirectory. Relative script paths and.relix/discovery broke on Windows. That line is removed.zsh completion now starts with
#compdef relix, so it works as_relixon$fpathas well as sourced../gradlew packageTestunpacks the archive with the system'starand runs its launcher. CI now runs it on all three OSes.relix doc, the providers that jlink would drop without any error.-Xshare:onwithcli.Mainloaded fromshared objects file (top), and-Xshare:onrefusing to start when the archive is missing.man -lover every page. macOS'smantakes a path instead.Release workflow (
.github/workflows/release.yml) builds and tests the five platform archives: macOS arm64 and x86_64, Linux x86_64 and arm64, Windows x86_64.vX.Y.Z: attaches the archives andchecksums.txtto the GitHub Release, then pushes the formula and the manifest to the tap and the bucket. A suffixed tag makes a pre-release and leaves the tap and the bucket alone.packaging/release.pywrites the formula and the manifest from the templates inpackaging/, then fails unless every archive they name has the checksum they give it. The result is uploaded as therelease-filesartifact.Formula: installs the man pages and the bash, zsh and fish completions. Its
test doblock pipes a script intorelixwith a CSV input. Manifest: apost_installadds a guarded line to the PowerShell profile that loads the completion, and the uninstaller removes it. Both declareApache-2.0and point at this repository.Acceptance
-Xshare:on.man -lon Linux).main.Before the first public release
DarkCollective/homebrew-relixandDarkCollective/scoop-relixare public.HOMEBREW_TAP_PATandSCOOP_BUCKET_PATsecrets are set here.packaging/on every release.What remains for #15 is the dry-run release, which can be dispatched once this is on
main.