6.4 KiB
Releasing Moli
The release workflow builds four native archives with stable asset names:
| System | Rust target | Archive |
|---|---|---|
| Linux x86_64 | x86_64-unknown-linux-gnu |
moli-x86_64-unknown-linux-gnu.tar.gz |
| macOS Intel | x86_64-apple-darwin |
moli-x86_64-apple-darwin.tar.gz |
| macOS Apple Silicon | aarch64-apple-darwin |
moli-aarch64-apple-darwin.tar.gz |
| Windows x86_64 | x86_64-pc-windows-msvc |
moli-x86_64-pc-windows-msvc.zip |
Every archive contains the moli executable, project licenses, README,
version marker, and third-party license notices. The workflow also publishes
moli-installer.sh and moli-installer.ps1. Skills are maintained separately
in the repository and are not included in release assets.
The workflow also assembles an npm CLI package set from those same native
archives. The public launcher is @lexmount/moli@<version>. Its optional
dependencies select one of four platform versions such as
@lexmount/moli@<version>-linux-x64, so npm downloads only the binary for the
host operating system and architecture. The launcher exposes the moli
command and forwards arguments, standard I/O, signals, and exit status to the
native executable. Linux npm installs currently require x86-64 glibc; Linux
ARM64 and musl are not advertised as supported targets.
Stable names are intentional: the latest non-prerelease asset is always
available at
https://github.com/lexmount/moli/releases/latest/download/<asset-name>.
The installers use those URLs, select the archive for the current platform,
and install the executable.
Each artifact is built on its native GitHub-hosted runner. The packager strips
only a staging copy, leaving the binary under target/release unchanged for
debugging. Because stripping invalidates a Mach-O signature, macOS staging
binaries are ad-hoc signed again and verified before packaging. They are not
Developer ID signed or notarized. Windows executables are not Authenticode
signed. The allocator behind the default jemalloc feature is target-gated
out on Windows, so Windows builds use the system allocator because upstream
treats the Windows/MSVC combination as untested.
Prepare the release
-
Update
versioninmoli/Cargo.tomland refreshCargo.lock. -
Commit and push those changes to the ref that should be released.
-
Optionally build the package for your current operating system locally.
Linux or macOS:
python3 scripts/release.py --version 0.1.1Windows PowerShell:
python scripts/release.py --version 0.1.1Artifacts are written to
dist/. The packager rejects a version that does not matchmoli/Cargo.toml, checks the native Rust target, strips the staged executable, and verifies the packaged binary's reported version.
Trigger GitHub Release
- Open Actions in GitHub and choose the Release workflow.
- Select Run workflow and choose the Git ref containing the release.
- Enter the version (with or without a leading
v). - Choose whether the release should be a prerelease or a draft.
- Enable npm publishing only after the npm trusted publisher described below is configured, then run the workflow.
The workflow validates the selected commit, builds all four native artifacts
in parallel, verifies the expected archives, creates the corresponding
vX.Y.Z tag, generates release notes, and uploads six assets: four archives
and two installers. It stops without creating a release if any platform fails,
if the requested version does not match the manifest, or if the tag already
exists. A published, non-prerelease release is explicitly marked as the latest
release so the stable installer URLs switch to it immediately.
Before creating the GitHub Release, the workflow builds five npm tarballs and
smoke-tests the Linux launcher against the real packaged binary. npm publishing
is disabled by default and is never attempted for draft releases. For a stable
release the launcher receives the latest dist-tag; for a prerelease it
receives next. Native platform versions are published first under
platform-specific dist-tags, and the launcher is published last so users never
receive a package whose required binary versions are incomplete.
Configure npm publishing
The unscoped moli package name is already owned by another publisher, so the
release uses the public scoped package @lexmount/moli. Confirm that the npm
organization or user controlling @lexmount can publish public packages before
enabling the workflow option.
An npm Trusted Publisher can only be attached after the package exists. For the
first npm release, leave npm publishing disabled when running the Release
workflow, download its npm-packages artifact, sign in to npm interactively,
and publish the verified package set from the extracted artifact:
npm login
python3 scripts/publish_npm.py /path/to/npm-packages/npm-packages.json \
--main-tag latest
Use --main-tag next instead when bootstrapping from a prerelease. The script
publishes the four native versions first and the launcher last. It is safe to
retry: versions whose registry integrity matches the artifact are skipped.
After this one-time publication, configure Trusted Publishing for subsequent
releases.
Configure an npm Trusted Publisher for the lexmount/moli GitHub repository
with these values:
- Workflow filename:
release.yml - Environment:
npm - Allowed action:
npm publish
The publish job runs on a GitHub-hosted runner with Node 24, npm 11.5.1 or
newer, and the id-token: write permission. The publish script checks these
minimum versions before touching the registry. It does not use a long-lived
npm token, and npm generates provenance automatically for the public package.
Add any required reviewers or branch/tag restrictions to the GitHub npm
environment. After the first successful publication, installation is:
npm install --global @lexmount/moli
moli --version
For local package validation, place all four native archives in dist/, then
run:
python3 scripts/package_npm.py --version 1.0.0
python3 scripts/publish_npm.py dist/npm/npm-packages.json --dry-run
The package manifest records the SHA-512 integrity of every tarball. A retried publish skips an existing version only when the registry reports the same integrity; a mismatch stops the release. npm does not allow a published name/version pair to be replaced, so release versions must be bumped before publishing changed contents.