Release-plz Workflow and Unified Workspace Versioning in OpenLogi

OpenLogi uses a single-workspace versioning strategy managed by release-plz, where all crates share one version number and the CI pipeline handles tag creation, artifact building, and signed distribution automatically.

The AprilNEA/OpenLogi repository implements a sophisticated release-plz workflow with unified workspace versioning to streamline their Rust CI/CD pipeline. This approach ensures every crate in the workspace remains version-locked while automating changelog generation, tagging, and multi-platform releases through GitHub Actions.

Unified Workspace Versioning Strategy

OpenLogi employs a unified versioning model where the entire workspace advances as a single unit. This prevents version drift between crates and simplifies dependency management across the project.

Workspace Configuration

In the root Cargo.toml, the version.workspace = true directive forces all member crates to inherit the same version number from the workspace definition. This configuration ensures that when the workspace version bumps from 1.2.3 to 1.2.4, every crate updates simultaneously.

The release-plz.toml file (lines 23-33) defines the central behavior:

[workspace]
pr_branch_prefix = "release-plz/"
semver_check = false
git_tag_enable = false
git_release_enable = false
changelog_update = false

Version Groups

Crates are grouped under version_group = "openlogi" in the release-plz configuration. This grouping ensures that release-plz calculates the highest next version among all crates in the group and applies it uniformly. Each participating crate has an individual [[package]] entry that references this group, ensuring lock-step versioning across the workspace.

Release-plz Configuration and Tag-Only Mode

OpenLogi configures release-plz in tag-only mode, separating version bumping from the actual GitHub Release creation. This decoupling allows the project to use release-plz for versioning and tagging while delegating complex artifact building and publishing to a dedicated workflow.

Centralized Settings

The workspace-level settings explicitly disable automatic GitHub releases and changelog updates:

[workspace]
git_tag_enable = false        # Tags created per-crate, not workspace

git_release_enable = false    # GH Release created by release.yml instead

changelog_update = false      # git-cliff handles changelog generation

According to the source code in release-plz.toml, this configuration delegates changelog generation to git-cliff (configured in .config/cliff.toml) and reserves GitHub Release creation for the release.yml workflow.

Per-Crate Tagging

While the workspace disables tagging, individual packages enable it to create the actual Git tag:

[[package]]
name = "openlogi"
version_group = "openlogi"
git_tag_enable = true
git_tag_name = "v{{ version }}"
git_release_enable = false

This setup ensures that when the release-plz PR merges, the workflow pushes a tag v{version} that triggers the downstream release pipeline.

The Automated Release Pipeline

The complete release workflow spans multiple GitHub Actions files and handles everything from version bumping to Homebrew tap updates.

Step 1: Release PR Creation

The .github/workflows/release-plz.yml runs release-plz on branches matching release-plz/*. When executed, release-plz:

  1. Bumps the unified version in the root Cargo.toml
  2. Generates a condensed changelog entry
  3. Opens a PR on a branch prefixed with release-plz/

The PR contains the version bump and changelog updates, requiring manual review before merging.

Step 2: Tag Push and Trigger

Upon merging the release-plz PR, the CI pushes the tag vX.Y.Z. This tag push triggers the on.push.tags event in .github/workflows/release.yml, initiating the official release pipeline.

Step 3: Build and Sign Artifacts

The release.yml workflow calls the reusable build.yml workflow to construct platform-specific installers:

  • macOS: DMG packages with notarization
  • Windows: MSI and ZIP with code-signing
  • Linux: DEB and RPM packages with GPG signing

Artifacts are stored as workflow outputs and signed using minisign for verification.

Step 4: Publish and Distribute

The publish job in release.yml orchestrates final distribution:


# Generate SHA-256 checksums

sha256sum * > SHA256SUMS

# Sign artifacts with minisign

minisign -S -m OpenLogi-1.2.3.dmg

# Create updater manifest via xtask

cargo run -p xtask --release latest-json \
    --dist ./dist \
    --tag v1.2.3 \
    --base-url https://openlogi.example.com/releases \
    --output ./dist/latest.json

The workflow uploads artifacts to GitHub Releases (using softprops/action-gh-release), publishes to Cloudflare R2 for static hosting, and dispatches an event to update the Homebrew tap repository.

Practical Usage and Local Testing

Developers can interact with the release system both through CI triggers and local tooling.

Creating a Release PR

To manually trigger version bumping and PR creation:


# Install release-plz if needed

cargo install release-plz

# Run from repository root

release-plz release

This creates a branch release-plz/vX.Y.Z, updates Cargo.toml versions, and opens a pull request. Merging triggers the tag push automatically.

Generating Updater Manifests

The xtask crate provides utilities for local release testing. To generate the latest.json updater manifest locally:

cargo run -p xtask --release latest-json \
    --dist ./dist \
    --tag v1.2.3 \
    --base-url https://openlogi.example.com/releases \
    --include-windows \
    --output ./dist/latest.json

See xtask/src/main.rs for additional release-related commands and CLI options.

Verifying Signed Artifacts

End users can verify downloaded artifacts using the project's minisign public key:

minisign -V -P <public-key> \
    -m OpenLogi-1.2.3.dmg \
    -x OpenLogi-1.2.3.dmg.minisig

Summary

  • Unified versioning via version.workspace = true in the root Cargo.toml keeps all OpenLogi crates synchronized to a single version number.
  • Tag-only mode in release-plz (configured in release-plz.toml lines 23-33) separates version management from GitHub Release creation, allowing complex build pipelines in release.yml.
  • Automated changelog generation is handled by git-cliff (configured in .config/cliff.toml) rather than release-plz's internal changelogger.
  • Multi-platform artifacts (DMG, MSI, DEB, RPM) are built, signed with minisign, and published to both GitHub Releases and Cloudflare R2 via the release.yml workflow.
  • Local tooling via the xtask crate supports generating updater manifests and testing release workflows without triggering CI.

Frequently Asked Questions

What is unified workspace versioning in OpenLogi?

Unified workspace versioning means every crate in the OpenLogi repository shares the exact same version number defined in the root Cargo.toml. By setting version.workspace = true in each crate's configuration and using release-plz's version_group setting, the project ensures that bumping from version 1.2.3 to 1.2.4 updates every crate simultaneously, preventing dependency conflicts and simplifying release management.

Why does OpenLogi use tag-only mode with release-plz?

OpenLogi uses tag-only mode (where git_release_enable = false for the workspace but git_tag_enable = true for packages) because the project requires complex artifact building, code signing, and multi-platform packaging that release-plz does not handle natively. In this configuration, release-plz manages versioning and creates Git tags, while the custom release.yml workflow handles the actual GitHub Release creation, artifact uploading, and distribution to Cloudflare R2 and Homebrew.

How are the release artifacts signed and verified?

Every release artifact is signed using minisign, a simple and secure signature system. During the release.yml workflow, the publish job generates SHA-256 checksums and creates .minisig signature files for each artifact. Users verify downloads by running minisign -V with the project's public key, the artifact file, and its corresponding signature file, ensuring the integrity and authenticity of downloaded DMGs, MSIs, and Linux packages.

Can I run the release workflow locally for testing?

Yes, local testing is supported through the xtask crate located in xtask/src/main.rs. Developers can generate updater manifests, test build configurations, and validate release artifacts without triggering the full CI pipeline. The cargo run -p xtask command provides subcommands like latest-json for creating the auto-updater manifest locally, allowing validation of release metadata before pushing tags to the repository.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →