# Release-plz Workflow and Unified Workspace Versioning in OpenLogi

> Explore OpenLogi's unified workspace versioning with release-plz. Discover how this strategy simplifies releases and automates CI tasks for shared crate versioning and artifact distribution.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: internals
- Published: 2026-08-24

---

**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`](https://github.com/AprilNEA/OpenLogi/blob/main/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`](https://github.com/AprilNEA/OpenLogi/blob/main/release-plz.toml) file (lines 23-33) defines the central behavior:

```toml
[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:

```toml
[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`](https://github.com/AprilNEA/OpenLogi/blob/main/release-plz.toml), this configuration delegates changelog generation to **git-cliff** (configured in [`.config/cliff.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/.config/cliff.toml)) and reserves GitHub Release creation for the [`release.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/release.yml) workflow.

### Per-Crate Tagging

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

```toml
[[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`](https://github.com/AprilNEA/OpenLogi/blob/main/.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`](https://github.com/AprilNEA/OpenLogi/blob/main/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`](https://github.com/AprilNEA/OpenLogi/blob/main/.github/workflows/release.yml), initiating the official release pipeline.

### Step 3: Build and Sign Artifacts

The [`release.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/release.yml) workflow calls the reusable [`build.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/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`](https://github.com/AprilNEA/OpenLogi/blob/main/release.yml) orchestrates final distribution:

```bash

# 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:

```bash

# 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`](https://github.com/AprilNEA/OpenLogi/blob/main/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`](https://github.com/AprilNEA/OpenLogi/blob/main/latest.json) updater manifest locally:

```bash
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`](https://github.com/AprilNEA/OpenLogi/blob/main/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:

```bash
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`](https://github.com/AprilNEA/OpenLogi/blob/main/Cargo.toml) keeps all OpenLogi crates synchronized to a single version number.
- **Tag-only mode** in release-plz (configured in [`release-plz.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/release-plz.toml) lines 23-33) separates version management from GitHub Release creation, allowing complex build pipelines in [`release.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/release.yml).
- **Automated changelog** generation is handled by **git-cliff** (configured in [`.config/cliff.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/.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`](https://github.com/AprilNEA/OpenLogi/blob/main/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`](https://github.com/AprilNEA/OpenLogi/blob/main/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`](https://github.com/AprilNEA/OpenLogi/blob/main/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`](https://github.com/AprilNEA/OpenLogi/blob/main/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`](https://github.com/AprilNEA/OpenLogi/blob/main/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.