# How to Reproduce Every CI Job Locally in OpenLogi Using `cargo xtask ci`

> Reproduce OpenLogi CI jobs locally with cargo xtask ci. Run the same checks as GitHub Actions before pushing your code and ensure all validations pass.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: how-to-guide
- Published: 2026-08-30

---

**Use `cargo xtask ci` to execute the exact same checks locally that OpenLogi's GitHub Actions workflow runs in the cloud, ensuring your code passes all validation steps before you push.**

OpenLogi provides a built-in xtask runner that mirrors the CI pipeline defined in [`.github/workflows/ci.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/.github/workflows/ci.yml). By invoking `cargo xtask ci`, developers can reproduce every CI job locally—including formatting, linting, testing, and documentation checks—using the same environment variables and command sequences that the CI server uses. This approach eliminates the feedback loop of pushing broken builds and waiting for remote failures.

## Understanding the CI Architecture

OpenLogi's local CI reproduction system consists of two core components: the GitHub Actions workflow definition that serves as the source of truth, and the xtask binary that parses and executes those steps on your workstation.

### The CI Configuration

The [`.github/workflows/ci.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/.github/workflows/ci.yml) file declares all CI jobs, including `rustfmt`, `clippy`, `test`, and `rustdoc`. According to the source analysis, the xtask runner reads this workflow file to construct a mapping of job names to their corresponding shell commands. This ensures that when you run `cargo xtask ci`, you are executing the exact same steps that GitHub Actions would run on every pull request.

### The xtask Implementation

The command implementation lives in [`xtask/src/commands/ci.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/xtask/src/commands/ci.rs). This module parses the YAML workflow, extracts job definitions, and dispatches them as subprocess calls. As documented in [`AGENTS.md`](https://github.com/AprilNEA/OpenLogi/blob/main/AGENTS.md) (lines 63–73), the runner translates each CI job into the precise command sequence the CI server would execute, including environment variables like `RUSTFLAGS=-D warnings` that promote warnings to errors.

## Running CI Jobs Locally

The xtask CLI provides multiple modes for interacting with the CI pipeline, from full-suite execution to targeted single-job validation.

### Execute the Full Local Suite

To reproduce every CI job that your host operating system supports, run:

```bash
cargo xtask ci

```

This command iterates through all jobs defined in [`.github/workflows/ci.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/.github/workflows/ci.yml) and executes only those compatible with your current platform. Unsupported jobs are reported as "not run" rather than failing, preventing false positives on incompatible systems.

### List Available Jobs

Before executing, inspect what jobs are available and what commands they map to:

```bash
cargo xtask ci --list

```

As noted in [`AGENTS.md`](https://github.com/AprilNEA/OpenLogi/blob/main/AGENTS.md) (lines 71–73), this outputs a table of job name to command pairs, allowing you to verify exactly which binaries and flags will be invoked.

### Target Specific Jobs

To reproduce only specific CI jobs—such as formatting and linting—pass the job names as arguments:

```bash
cargo xtask ci rustfmt clippy

```

You can run any job ID defined in the workflow:

```bash
cargo xtask ci test
cargo xtask ci macos-bundle

```

This targeted approach saves time when you only need to validate a particular aspect of your changes.

### Validate with Dry-Run Mode

To preview the exact commands that would execute without running them, use the dry-run flag:

```bash
cargo xtask ci --dry-run

```

This mode guarantees you know what side-effects will occur before any code is formatted, compiled, or tested.

## Environment Setup and Constraints

Reproducing CI jobs locally requires proper environment configuration to match the CI server's toolchain and behavior.

### devenv and direnv Integration

When using `devenv` or other Nix-based development environments where Cargo is only available inside a managed shell, prepend `direnv exec .` to ensure the correct binary is on `PATH`:

```bash
direnv exec . cargo xtask ci

```

As documented in [`AGENTS.md`](https://github.com/AprilNEA/OpenLogi/blob/main/AGENTS.md) (lines 71–74), this ensures the xtask runner uses the same Cargo and Rust toolchain versions that the CI environment specifies.

### OS-Specific Job Filtering

The xtask runner automatically filters jobs based on host OS compatibility. Only jobs that the current platform can actually execute are run; others are explicitly marked as skipped. This behavior, described in [`AGENTS.md`](https://github.com/AprilNEA/OpenLogi/blob/main/AGENTS.md) (lines 77–79), prevents developers from attempting to run Linux-specific container jobs on macOS or Windows-specific tasks on Linux workstations.

### Strict Warning Handling

The local runner mirrors CI's strictness by setting `RUSTFLAGS=-D warnings` during compilation. This ensures that any warnings in your code become hard errors locally, just as they do in the GitHub Actions environment, preventing surprise build failures on the remote server.

## Summary

- **`cargo xtask ci`** parses [`.github/workflows/ci.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/.github/workflows/ci.yml) and executes the same jobs locally that run in GitHub Actions.
- **`cargo xtask ci --list`** displays a mapping of job names to their underlying shell commands.
- **`cargo xtask ci <job>`** runs specific jobs by name, such as `rustfmt`, `clippy`, or `test`.
- **`cargo xtask ci --dry-run`** shows exactly what commands would execute without running them.
- **Environment parity** is maintained through `RUSTFLAGS=-D warnings` and support for `direnv exec .` when using devenv.
- **OS filtering** automatically skips jobs that cannot run on the current host platform.

## Frequently Asked Questions

### What is `cargo xtask ci` and how does it work?

`cargo xtask ci` is a custom cargo command implemented in [`xtask/src/commands/ci.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/xtask/src/commands/ci.rs) that reads OpenLogi's [`.github/workflows/ci.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/.github/workflows/ci.yml) and reconstructs the CI jobs as local shell commands. It maps each job ID to its equivalent cargo or shell invocation, sets the same environment variables (including `RUSTFLAGS=-D warnings`), and executes them in sequence, providing local validation that matches remote CI behavior.

### How do I run only specific CI jobs locally?

Pass the job names as arguments to the command: `cargo xtask ci rustfmt clippy`. The runner will only execute the jobs you specify, skipping all others. This is useful when you want to quickly validate formatting or linting without running the full test suite.

### Can I reproduce CI jobs if I'm using devenv or Nix?

Yes. When your Cargo installation is managed by `devenv` or Nix and only available inside a specific shell environment, prepend `direnv exec .` to the command: `direnv exec . cargo xtask ci`. This ensures the xtask binary uses the correct Cargo and Rust toolchain from your development environment.

### Why are some CI jobs skipped when I run `cargo xtask ci`?

The xtask runner automatically detects which jobs are incompatible with your host operating system and reports them as "not run" rather than failing. For example, Linux-specific container jobs will be skipped on macOS, and Windows-specific jobs will be skipped on Linux. This behavior prevents false-positive failures while clearly indicating which validations were not performed locally.