How azlin gets built, versioned, tagged, and distributed.
The GitHub Actions workflow .github/workflows/rust-release.yml runs when:
- A push to
mainchanges any file underrust/— automatic release. - Manual dispatch — click "Run workflow" in the Actions tab.
The workflow skips entirely if the triggering commit message contains [skip ci]
(this prevents the version-bump commit from re-triggering itself).
| Platform | Target triple | Asset name |
|---|---|---|
| Linux x86_64 | x86_64-unknown-linux-gnu |
azlin-linux-x86_64 |
| Linux aarch64 | aarch64-unknown-linux-gnu |
azlin-linux-aarch64 |
| macOS x86_64 | x86_64-apple-darwin |
azlin-macos-x86_64 |
| macOS aarch64 | aarch64-apple-darwin |
azlin-macos-aarch64 |
| Windows x86_64 | x86_64-pc-windows-msvc |
azlin-windows-x86_64 |
Each platform produces a .tar.gz archive containing both azlin and azdoit
binaries. Python wheels (via maturin) are also built for all platforms.
Every release creates a GitHub Release at
https://github.com/rysweet/azlin/releases with:
- Platform-specific
.tar.gzarchives (native binaries) - Python
.whlfiles (forpip install azlin-rs)
<major>.<minor>.<patch>
- Patch is auto-incremented by the release workflow on every merge to main.
- Minor and major bumps are manual (edit
rust/Cargo.toml).
The version-bump job in the release workflow:
- Reads the current version from
rust/Cargo.toml(e.g.2.6.0). - Queries existing GitHub Release tags for the same
major.minorprefix. - Finds the highest patch number among those tags (e.g.
v2.6.3-rust.abc1234has patch3). - Sets the new version to
major.minor.(highest_patch + 1)(e.g.2.6.4). - Updates all version files:
rust/Cargo.toml,pyproject.toml,rust/pyproject.toml,src/azlin/__init__.py. - Commits with
[skip ci]to prevent re-triggering the workflow. - Pushes the commit. All subsequent build jobs check out this commit.
If no prior release exists for the current major.minor, the patch number from
Cargo.toml is used as-is.
v<major>.<minor>.<patch>-rust.<short-sha>
Examples:
v2.6.4-rust.abc1234v2.7.0-rust.def5678
The -rust suffix distinguishes Rust releases from any legacy Python releases.
The short SHA identifies the exact commit the binaries were built from.
The azlin update command (implemented in rust/crates/azlin/src/cmd_self_update.rs):
- Queries the GitHub Releases API for
rysweet/azlin:- First tries
gh api(authenticated, no rate limits). - Falls back to
curl(unauthenticated, 60 req/hr limit).
- First tries
- Finds the latest release whose tag contains
-rust. - Matches the platform-specific
.tar.gzasset (e.g.azlin-linux-x86_64.tar.gz). - Downloads the archive with
curl, extracts it withtar. - Replaces the running binary:
- Renames current binary to
.old(backup). - Copies new binary into place.
- Sets executable permissions.
- Removes backup and temp files.
- Renames current binary to
- Prints
Updated azlin: <old_version> → <new_version>.
If the current version already matches the latest release, it prints "Already at the latest version" and exits.
The Python package (pip install azlin) ships a thin bridge at
src/azlin/rust_bridge.py that does not contain any CLI logic. It only
bootstraps the Rust binary:
- Probe known locations (in order):
~/.azlin/bin/azlin(managed install from GitHub Releases)~/.cargo/bin/azlin(cargo install)/usr/local/bin/azlin(system package)
- If not found, download from GitHub Releases — same mechanism as
azlin update, using the Releases API to find the latest-rusttagged release and downloading the platform-specific archive. - If download fails, build from source — runs
cargo install --git https://github.com/rysweet/azlin --bin azlin. - If all methods fail, exit with error — prints clear instructions for manual installation. There is no Python fallback.
- exec() the Rust binary — replaces the Python process entirely.
For minor or major bumps, edit the workspace version in rust/Cargo.toml:
[workspace.package]
version = "2.7.0" # ← change thisAll crates inherit the workspace version (version.workspace = true), so only
the root Cargo.toml needs changing. The release workflow will then update the
remaining files (pyproject.toml, rust/pyproject.toml, src/azlin/__init__.py)
automatically during the next release — or you can update them manually for
consistency:
# Files that contain the version string:
rust/Cargo.toml # workspace version (source of truth)
pyproject.toml # Python package version
rust/pyproject.toml # maturin wheel version
src/azlin/__init__.py # __version__ stringAfter editing, commit and push to main. The release workflow picks up the new
base version and auto-increments from there.
| Platform | Binary | Wheel | Tested |
|---|---|---|---|
| linux-x86_64 | yes | yes | CI |
| linux-aarch64 | yes (cross) | yes (cross) | CI |
| macos-x86_64 | yes | yes | CI |
| macos-aarch64 | yes | yes | CI |
| windows-x86_64 | yes | yes | CI |