> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mirurobotics.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a release

export const AdminBadge = ({size = "md"}) => {
  return <Tooltip tip="Workspace owners and administrators can execute this action." cta="Workspace roles" href="/admin/users/access-control">
            <Badge icon="shield-check" color="blue" size={size}>admin</Badge>
        </Tooltip>;
};

To keep things simple, we've provided a [getting-started repository](https://github.com/mirurobotics/getting-started) that contains everything you need to create a release. Follow along with us by cloning the repository.

```bash theme={null}
git clone https://github.com/mirurobotics/getting-started.git
```

## Define the schemas

Releases are defined by the config schemas they contain. The getting-started repository contains two sets of schemas for each of the supported [schema languages](/cfg-mgmt/primitives/schemas/languages/overview):

* Empty schemas - regard all config instances as valid
* Strict schemas - constrain the valid fields, types, and values for instances of the config type they belong to

For this tutorial, choose one of these schema sets to create your release with.

If you're unfamiliar with schema languages, we recommend starting with [JSON Schema](/cfg-mgmt/primitives/schemas/languages/jsonschema). If you don't currently use a schema, we recommend starting with an empty schema and gradually adding constraints as needed.

<Tabs>
  <Tab title="JSON Schema">
    **Empty Schemas**

    <CodeGroup>
      ```yaml Communication theme={null}
      x-miru-config-type: "communication"
      x-miru-instance-filepath: "/srv/miru/configs/communication.yaml"
      $schema: "http://json-schema.org/draft/2020-12/schema"
      ```

      ```yaml Mobility theme={null}
      x-miru-config-type: "mobility"
      x-miru-instance-filepath: "/srv/miru/configs/mobility.json"
      $schema: "http://json-schema.org/draft/2020-12/schema"
      ```

      ```yaml Planning theme={null}
      x-miru-config-type: "planning"
      x-miru-instance-filepath: "/srv/miru/configs/planning.json"
      $schema: "http://json-schema.org/draft/2020-12/schema"
      ```
    </CodeGroup>

    **Strict Schemas**

    <CodeGroup>
      ```yaml Communication expandable theme={null}
      x-miru-config-type: "communication"
      x-miru-instance-filepath: "/srv/miru/configs/communication.yaml"
      $schema: "http://json-schema.org/draft/2020-12/schema"
      type: object
      required:
          - control_loop_rate_hz
          - watchdog_timeout_ms
          - network
          - logging
          - error_handling
      properties:
          control_loop_rate_hz:
          type: integer
          description: Control loop frequency in Hertz
          minimum: 1
          maximum: 1000  
          default: 50
          watchdog_timeout_ms:
          type: integer
          description: Watchdog timeout duration in milliseconds
          minimum: 100   
          maximum: 5000  
          default: 500
          network:
          type: object
          required:
              - max_latency_ms
              - connection_timeout_ms
              - reconnect_attempts
              - reconnect_interval_ms
              - heartbeat_interval_ms
          properties:
              max_latency_ms:
              type: integer
              description: Maximum acceptable network latency in milliseconds
              minimum: 10    
              maximum: 1000  
              default: 100
              connection_timeout_ms:
              type: integer
              description: Connection timeout duration in milliseconds
              minimum: 100    
              maximum: 10000  
              default: 2000
              reconnect_attempts:
              type: integer
              description: Number of reconnection attempts
              minimum: 1
              maximum: 10    
              default: 3
              reconnect_interval_ms:
              type: integer
              description: Interval between reconnection attempts in milliseconds
              minimum: 100    
              maximum: 5000   
              default: 1000
              heartbeat_interval_ms:
              type: integer
              description: Interval between heartbeat messages in milliseconds
              minimum: 50     
              maximum: 1000   
              default: 250
          logging:
          type: object
          required:
              - enable_packet_logging
              - log_level
              - max_log_size_mb
              - retain_logs_days
          properties:
              enable_packet_logging:
              type: boolean
              description: Enable or disable packet logging
              default: true
              log_level:
              type: string
              description: Logging level
              enum: ["debug", "info", "warn", "error"]
              default: "info"
              max_log_size_mb:
              type: integer
              description: Maximum log file size in megabytes
              minimum: 1
              maximum: 1024  
              default: 100
              retain_logs_days:
              type: integer
              description: Number of days to retain log files
              minimum: 1
              maximum: 90    
              default: 30
          error_handling:
          type: object
          required:
              - max_consecutive_failures
              - failure_timeout_ms
              - enable_auto_recovery
          properties:
              max_consecutive_failures:
              type: integer
              description: Maximum number of consecutive failures allowed
              minimum: 1
              maximum: 20    
              default: 5
              failure_timeout_ms:
              type: integer
              description: Timeout duration for failure handling in milliseconds
              minimum: 100    
              maximum: 30000  
              default: 5000
              enable_auto_recovery:
              type: boolean
              description: Enable or disable automatic recovery from failures
              default: true
      ```

      ```yaml Mobility expandable theme={null}
      x-miru-config-type: "mobility"
      x-miru-instance-filepath: "/srv/miru/configs/mobility.json"
      $schema: "http://json-schema.org/draft/2020-12/schema"
      type: object
      properties:
          max_linear_speed_mps:
          type: number
          minimum: 0.1
          maximum: 5.0
          default: 1.2
          max_angular_speed_radps:
          type: number
          minimum: 0.2
          maximum: 3.0
          default: 1.0
          obstacle_avoidance_enabled:
          type: boolean
          default: true
          navigation_mode:
          type: string
          enum: [conservative, balanced, aggressive]
          default: balanced
          telemetry:
          type: object
          properties:
              upload_interval_sec:
              type: integer
              minimum: 10
              maximum: 300
              default: 60
              heartbeat_interval_sec:
              type: integer
              minimum: 1
              maximum: 60
              default: 10
          required:
              - upload_interval_sec
              - heartbeat_interval_sec
      required:
          - max_linear_speed_mps
          - max_angular_speed_radps
          - obstacle_avoidance_enabled
          - navigation_mode
          - telemetry
      ```

      ```yaml Planning expandable theme={null}
      x-miru-config-type: "planning"
      x-miru-instance-filepath: "/srv/miru/configs/planning.json"
      $schema: "http://json-schema.org/draft/2020-12/schema"
      type: object
      required:
          - planning_frequency_hz
          - control_frequency_hz
          - planning_timeout_s
          - path_following
          - trajectory
          - local_planner
          - global_planner
          - obstacle_avoidance
          - smoothing
          - recovery
      properties:
          planning_frequency_hz:
          type: number
          description: Planning loop frequency in Hertz
          minimum: 1.0
          maximum: 100.0  
          default: 20.0
          control_frequency_hz:
          type: number
          description: Control loop frequency in Hertz
          minimum: 10.0   
          maximum: 200.0  
          default: 50.0
          planning_timeout_s:
          type: number
          description: Planning timeout in seconds
          minimum: 0.1    
          maximum: 5.0    
          default: 1.0
          path_following:
          type: object
          required:
              - lookahead_distance_m
              - lookahead_time_s
              - path_tolerance_m
              - goal_tolerance_m
              - heading_tolerance_rad
              - min_lookahead_distance_m
              - max_lookahead_distance_m
          properties:
              lookahead_distance_m:
              type: number
              description: Look-ahead distance in meters
              minimum: 0.1
              maximum: 2.0
              default: 0.3
              lookahead_time_s:
              type: number
              description: Look-ahead time in seconds
              minimum: 0.1
              maximum: 2.0
              default: 0.5
              path_tolerance_m:
              type: number
              description: Path following tolerance in meters
              minimum: 0.01
              maximum: 0.5
              default: 0.05
              goal_tolerance_m:
              type: number
              description: Goal reaching tolerance in meters
              minimum: 0.01
              maximum: 0.5
              default: 0.1
              heading_tolerance_rad:
              type: number
              description: Heading tolerance in radians
              minimum: 0.01
              maximum: 0.5  # About 28.6 degrees
              default: 0.05
              min_lookahead_distance_m:
              type: number
              description: Minimum look-ahead distance in meters
              minimum: 0.05
              maximum: 1.0
              default: 0.1
              max_lookahead_distance_m:
              type: number
              description: Maximum look-ahead distance in meters
              minimum: 0.2
              maximum: 5.0
              default: 0.5
          trajectory:
          type: object
          required:
              - max_path_velocity_mps
              - min_path_velocity_mps
              - path_acceleration_mps2
              - path_deceleration_mps2
              - max_centripetal_acceleration_mps2
              - path_jerk_mps3
          properties:
              max_path_velocity_mps:
              type: number
              description: Maximum path velocity in meters per second
              minimum: 0.2
              maximum: 5.0
              default: 1.5
              min_path_velocity_mps:
              type: number
              description: Minimum path velocity in meters per second
              minimum: 0.05
              maximum: 0.5
              default: 0.1
              path_acceleration_mps2:
              type: number
              description: Path acceleration in meters per second squared
              minimum: 0.1
              maximum: 3.0
              default: 1.0
              path_deceleration_mps2:
              type: number
              description: Path deceleration in meters per second squared
              minimum: 0.1
              maximum: 4.0
              default: 1.2
              max_centripetal_acceleration_mps2:
              type: number
              description: Maximum centripetal acceleration in meters per second squared
              minimum: 0.1
              maximum: 2.0
              default: 0.5
              path_jerk_mps3:
              type: number
              description: Path jerk in meters per second cubed
              minimum: 0.1
              maximum: 5.0
              default: 0.5
          local_planner:
          type: object
          required:
              - min_samples
              - max_samples
              - sampling_time_s
              - resolution_m
              - horizon_m
          properties:
              min_samples:
              type: integer
              description: Minimum number of samples
              minimum: 5
              maximum: 100
              default: 10
              max_samples:
              type: integer
              description: Maximum number of samples
              minimum: 10
              maximum: 500
              default: 50
              sampling_time_s:
              type: number
              description: Sampling time in seconds
              minimum: 0.1
              maximum: 2.0
              default: 0.8
              resolution_m:
              type: number
              description: Resolution in meters
              minimum: 0.01
              maximum: 0.5
              default: 0.05
              horizon_m:
              type: number
              description: Planning horizon in meters
              minimum: 0.5
              maximum: 10.0
              default: 2.0
          global_planner:
          type: object
          required:
              - grid_resolution_m
              - inflation_radius_m
              - cost_scaling_factor
              - lethal_cost_value
              - neutral_cost_value
          properties:
              grid_resolution_m:
              type: number
              description: Grid resolution in meters
              minimum: 0.01
              maximum: 0.5
              default: 0.1
              inflation_radius_m:
              type: number
              description: Inflation radius in meters
              minimum: 0.1
              maximum: 2.0
              default: 0.5
              cost_scaling_factor:
              type: number
              description: Cost scaling factor
              minimum: 0.1
              maximum: 10.0
              default: 2.0
              lethal_cost_value:
              type: integer
              description: Lethal cost value
              minimum: 100
              maximum: 255
              default: 253
              neutral_cost_value:
              type: integer
              description: Neutral cost value
              minimum: 0
              maximum: 100
              default: 50
          obstacle_avoidance:
          type: object
          required:
              - min_obstacle_distance_m
              - max_obstacle_distance_m
              - obstacle_inflation_m
              - dynamic_obstacle_velocity_threshold_mps
          properties:
              min_obstacle_distance_m:
              type: number
              description: Minimum obstacle distance in meters
              minimum: 0.1
              maximum: 1.0
              default: 0.5
              max_obstacle_distance_m:
              type: number
              description: Maximum obstacle distance in meters
              minimum: 0.5
              maximum: 5.0
              default: 2.0
              obstacle_inflation_m:
              type: number
              description: Obstacle inflation in meters
              minimum: 0.05
              maximum: 1.0
              default: 0.2
              dynamic_obstacle_velocity_threshold_mps:
              type: number
              description: Dynamic obstacle velocity threshold in meters per second
              minimum: 0.05
              maximum: 2.0
              default: 0.2
          smoothing:
          type: object
          required:
              - curve_weight
              - smooth_weight
              - tolerance
              - max_iterations
          properties:
              curve_weight:
              type: number
              description: Curve weight for smoothing
              minimum: 0.0
              maximum: 1.0
              default: 0.3
              smooth_weight:
              type: number
              description: Smooth weight for smoothing
              minimum: 0.0
              maximum: 1.0
              default: 0.3
              tolerance:
              type: number
              description: Smoothing tolerance
              minimum: 0.0001
              maximum: 0.1
              default: 0.01
              max_iterations:
              type: integer
              description: Maximum smoothing iterations
              minimum: 5
              maximum: 1000
              default: 10
          recovery:
          type: object
          required:
              - enable_backoff
              - backoff_distance_m
              - enable_rotation_in_place
              - max_rotation_angle_rad
              - clear_costmap_before_recovery
          properties:
              enable_backoff:
              type: boolean
              description: Enable backoff recovery behavior
              default: true
              backoff_distance_m:
              type: number
              description: Backoff distance in meters
              minimum: 0.1
              maximum: 2.0
              default: 0.3
              enable_rotation_in_place:
              type: boolean
              description: Enable rotation in place recovery
              default: true
              max_rotation_angle_rad:
              type: number
              description: Maximum rotation angle in radians
              minimum: 0.1
              maximum: 6.28318  # 2π
              default: 1.57     # π/2
              clear_costmap_before_recovery:
              type: boolean
              description: Clear costmap before recovery attempt
              default: true 
      ```
    </CodeGroup>
  </Tab>

  <Tab title="CUE">
    **Empty Schemas**

    <CodeGroup>
      ```cue Communication theme={null}
      @miru(config_type="communication",instance_filepath="/srv/miru/configs/communication.yaml")
      {
      	...
      }
      ```

      ```cue Mobility theme={null}
      @miru(config_type="mobility",instance_filepath="/srv/miru/configs/mobility.json")
      {
      	...
      }
      ```

      ```cue Planning theme={null}
      @miru(config_type="planning",instance_filepath="/srv/miru/configs/planning.json")
      {
      	...
      }
      ```
    </CodeGroup>

    **Strict Schemas**

    <CodeGroup>
      ```cue Communication expandable theme={null}
      @miru(config_type="communication",instance_filepath="/srv/miru/configs/communication.yaml")
      {
      	control_loop_rate_hz: int & >=1 & <=1000 | *50
      	watchdog_timeout_ms: int & >=100 & <=5000 | *500

      	network: {
      		max_latency_ms: int & >=10 & <=1000 | *100
      		connection_timeout_ms: int & >=100 & <=10000 | *2000
      		reconnect_attempts: int & >=1 & <=10 | *3
      		reconnect_interval_ms: int & >=100 & <=5000 | *1000
      		heartbeat_interval_ms: int & >=50 & <=1000 | *250
      	}

      	logging: {
      		enable_packet_logging: bool | *true
      		log_level: "debug" | "info" | "warn" | "error" | *"info"
      		max_log_size_mb: int & >=1 & <=1024 | *100
      		retain_logs_days: int & >=1 & <=90 | *30
      	}

      	error_handling: {
      		max_consecutive_failures: int & >=1 & <=20 | *5
      		failure_timeout_ms: int & >=100 & <=30000 | *5000
      		enable_auto_recovery: bool | *true
      	}
      }
      ```

      ```cue Mobility expandable theme={null}
      @miru(config_type="mobility",instance_filepath="/srv/miru/configs/mobility.json")
      {
      	max_linear_speed_mps: number & >=0.1 & <=5.0 | *1.2
      	max_angular_speed_radps: number & >=0.1 & <=3.0 | *1.0
      	obstacle_avoidance_enabled: bool | *true
      	navigation_mode: "conservative" | "balanced" | "aggressive" | *"balanced"

      	telemetry: {
      		upload_interval_sec: int & >=10 & <=300 | *60
      		heartbeat_interval_sec: int & >=1 & <=60 | *10
      	}
      }
      ```

      ```cue Planning expandable theme={null}
      @miru(config_type="planning",instance_filepath="/srv/miru/configs/planning.json")
      {
      	planning_frequency_hz: number & >=1.0 & <=100.0 | *20.0
      	control_frequency_hz: number & >=10.0 & <=200.0 | *50.0
      	planning_timeout_s: number & >=0.1 & <=5.0 | *1.0

      	path_following: {
      		lookahead_distance_m: number & >=0.1 & <=2.0 | *0.3
      		lookahead_time_s: number & >=0.1 & <=2.0 | *0.5
      		path_tolerance_m: number & >=0.01 & <=0.5 | *0.05
      		goal_tolerance_m: number & >=0.01 & <=0.5 | *0.1
      		heading_tolerance_rad: number & >=0.01 & <=0.5 | *0.05
      		min_lookahead_distance_m: number & >=0.05 & <=1.0 | *0.1
      		max_lookahead_distance_m: number & >=0.2 & <=5.0 | *0.5
      	}

      	trajectory: {
      		max_path_velocity_mps: number & >=0.2 & <=5.0 | *1.5
      		min_path_velocity_mps: number & >=0.05 & <=0.5 | *0.1
      		path_acceleration_mps2: number & >=0.1 & <=3.0 | *1.0
      		path_deceleration_mps2: number & >=0.1 & <=4.0 | *1.2
      		max_centripetal_acceleration_mps2: number & >=0.1 & <=2.0 | *0.5
      		path_jerk_mps3: number & >=0.1 & <=5.0 | *0.5
      	}

      	local_planner: {
      		min_samples: int & >=5 & <=100 | *10
      		max_samples: int & >=10 & <=500 | *50
      		sampling_time_s: number & >=0.1 & <=2.0 | *0.8
      		resolution_m: number & >=0.01 & <=0.5 | *0.05
      		horizon_m: number & >=0.5 & <=10.0 | *2.0
      	}

      	global_planner: {
      		grid_resolution_m: number & >=0.01 & <=0.5 | *0.1
      		inflation_radius_m: number & >=0.1 & <=2.0 | *0.5
      		cost_scaling_factor: number & >=0.1 & <=10.0 | *2.0
      		lethal_cost_value: int & >=100 & <=255 | *253
      		neutral_cost_value: int & >=0 & <=100 | *50
      	}

      	obstacle_avoidance: {
      		min_obstacle_distance_m: number & >=0.1 & <=1.0 | *0.5
      		max_obstacle_distance_m: number & >=0.5 & <=5.0 | *2.0
      		obstacle_inflation_m: number & >=0.05 & <=1.0 | *0.2
      		dynamic_obstacle_velocity_threshold_mps: number & >=0.05 & <=2.0 | *0.2
      	}

      	smoothing: {
      		curve_weight: number & >=0.0 & <=1.0 | *0.3
      		smooth_weight: number & >=0.0 & <=1.0 | *0.3
      		tolerance: number & >=0.0001 & <=0.1 | *0.01
      		max_iterations: int & >=5 & <=1000 | *10
      	}

      	recovery: {
      		enable_backoff: bool | *true
      		backoff_distance_m: number & >=0.1 & <=2.0 | *0.3
      		enable_rotation_in_place: bool | *true
      		max_rotation_angle_rad: number & >=0.1 & <=6.28318 | *1.57
      		clear_costmap_before_recovery: bool | *true
      	}
      }
      ```
    </CodeGroup>
  </Tab>
</Tabs>

### Schema annotations

Each of the above schema examples are annotated with the `x-miru-config-type` and `x-miru-instance-filepath` fields. These annotations are crucial metadata that Miru uses to process the schema and deploy config instances to the correct location on the device.

<ParamField path="config type" required>
  The config type is a required annotation that identifies the config type to which a schema belongs. Below is the syntax for annotating a schema with a [config type slug](/cfg-mgmt/primitives/config-types#param-slug).

  <CodeGroup>
    ```yaml JSON Schema theme={null}
    x-miru-config-type: "{config-type-slug}"
    ```

    ```cue CUE theme={null}
    @miru(config_type="{config-type-slug}")
    ```
  </CodeGroup>

  If the provided config type slug does not yet exist, it is automatically created. To edit a config type after creation, visit the [config types documentation](/cfg-mgmt/primitives/config-types#edit-a-config-type).

  Examples: `mobility`, `communication`, `perception`
</ParamField>

<ParamField path="instance file path">
  The instance file path is the absolute file system path where config instances for this schema are written on the device.

  <Warning>
    The Miru Agent ships with out-of-the-box access to `/srv/miru`. To deploy configs to a custom directory, please visit the [File system access](/developers/agent/filesys-access#configs) page.
  </Warning>

  Instance file paths control the type of file that config instances are deployed as. Currently, JSON (`.json`) and YAML (`.yaml`, `.yml`) are supported.

  This annotation is optional and defaults to `/srv/miru/configs/{config-type-slug}.json`.

  <CodeGroup>
    ```yaml JSON Schema theme={null}
    x-miru-instance-filepath: "/srv/miru/configs/{config-type-slug}.json"
    ```

    ```cue CUE theme={null}
    @miru(instance_filepath="/srv/miru/configs/{config-type-slug}.json")
    ```
  </CodeGroup>

  Examples:

  * `/srv/miru/configs/mobility.json`
  * `/home/myapp/configs/communication.yaml`
  * `/var/lib/myapp/configs/safety.yaml`
</ParamField>

## Set up the CLI

Next, we'll install the CLI—the primary method of creating releases in Miru.

Creating releases via the CLI is a deliberate design choice. We believe a release's schemas should live in a Git repository. This allows them to be versioned alongside the code that uses them and encourages better software development practices.

While this tutorial covers creating releases on your local machine, the CLI can also be used to create releases in a [CI pipeline](/developers/ci/overview).

**Install**

The CLI is only available on macOS and Linux. Windows is not supported.

<Tabs>
  <Tab title="macOS">
    Install via Homebrew.

    ```bash theme={null}
    brew install mirurobotics/cli/miru
    ```

    <Info>
      If you are not seeing the latest CLI version, refresh Homebrew with `brew update`.
    </Info>
  </Tab>

  <Tab title="Linux">
    The CLI is distributed to Linux as a Debian package. Other package formats are not yet supported.

    We recommend using `apt` to install the CLI. However, you can manually install the Debian package by downloading it from GitHub and installing it with `dpkg`.

    <Tabs>
      <Tab title="APT">
        <Steps>
          <Step title="Set up">
            Set up Miru's `apt` repository.

            ```bash theme={null}
            # ensure the appropriate dependencies are installed
            sudo apt-get update
            sudo apt-get install -y ca-certificates curl gnupg

            # add Miru's signing key
            sudo install -m 0755 -d /etc/apt/keyrings
            curl -fsSL https://packages.mirurobotics.com/apt/miru.gpg -o /tmp/miru.gpg.armor
            sudo gpg --dearmor -o /etc/apt/keyrings/miru-archive-keyring.gpg /tmp/miru.gpg.armor
            rm /tmp/miru.gpg.armor
            sudo chmod a+r /etc/apt/keyrings/miru-archive-keyring.gpg

            # add the repository to your sources list
            sudo tee /etc/apt/sources.list.d/miru.sources > /dev/null <<EOF
            Types: deb
            URIs: https://packages.mirurobotics.com/apt
            Suites: stable
            Components: main
            Architectures: $(dpkg --print-architecture)
            Signed-By: /etc/apt/keyrings/miru-archive-keyring.gpg
            EOF
            ```
          </Step>

          <Step title="Install">
            After configuring the `apt` repository, install the CLI.

            ```bash theme={null}
            sudo apt-get update
            sudo apt-get install miru-cli
            ```

            <Tip>
              Install a specific version with `sudo apt-get install miru-cli=<version>` (e.g. `0.9.1`, `0.10.0`, etc.).
            </Tip>
          </Step>
        </Steps>
      </Tab>

      <Tab title="Manual">
        <Steps>
          <Step title="Download">
            All Miru CLI releases are available as Debian packages [on GitHub](https://github.com/mirurobotics/cli/releases). You can find the latest release [here](https://github.com/mirurobotics/cli/releases/latest).

            To download the CLI, drop down the **Assets** section for the desired release. The assets ending with the `.deb` extension are the Debian packages for the Miru CLI.

            <Frame>
              <img src="https://assets.mirurobotics.com/docs/v04/images/cli/github-assets.light.png" alt="GitHub release assets" className="block dark:hidden" />

              <img src="https://assets.mirurobotics.com/docs/v04/images/cli/github-assets.dark.png" alt="GitHub release assets" className="hidden dark:block" />
            </Frame>

            Find the architecture that matches your target machine's architecture and download the package.

            For example, if your robot is an `x86_64` machine, you'll want to download the `miru-cli_<version>_amd64.deb` package. If your robot is an `aarch64` machine, you'll want to download the `miru-cli_<version>_arm64.deb` package.
          </Step>

          <Step title="Install">
            After downloading the package, install it using `dpkg`.

            ```bash theme={null}
            sudo dpkg -i <...>.deb
            ```
          </Step>
        </Steps>
      </Tab>
    </Tabs>
  </Tab>
</Tabs>

**Login**

To log in, run the `login` command.

```bash theme={null}
miru login
```

Retrieve your authentication token from the [Secrets](https://app.mirurobotics.com/settings/cli-token) page. <AdminBadge />

<Frame>
  <img src="https://assets.mirurobotics.com/docs/v04/images/secrets/cli-token/page.png" style={{ borderRadius:"16px" }} />
</Frame>

Paste the token into the CLI.

```
Please retrieve your authentication token from the following URL:
🔗 https://app.mirurobotics.com/settings/cli-token

🔑 Paste your authentication token: **********

Validating authentication token...
✅ Successfully logged in as Benjamin
```

## Create a release

With the CLI setup, we are ready to create a release in Miru.

Navigate to the root of the [getting-started](https://github.com/mirurobotics/getting-started) repository and create the release with a schema set of your choice.

<Tabs>
  <Tab title="JSON Schema">
    <CodeGroup>
      ```bash Empty Schemas theme={null}
      miru release create \
        --version "v1.0.0" \
        --schemas ./jsonschema/empty-schemas/
      ```

      ```bash Strict Schemas theme={null}
      miru release create \
        --version "v1.0.0" \
        --schemas ./jsonschema/strict-schemas/
      ```
    </CodeGroup>
  </Tab>

  <Tab title="CUE">
    <CodeGroup>
      ```bash Empty Schemas theme={null}
      miru release create \
        --version "v1.0.0" \
        --schemas ./cue/empty-schemas/
      ```

      ```bash Strict Schemas theme={null}
      miru release create \
        --version "v1.0.0" \
        --schemas ./cue/strict-schemas/
      ```
    </CodeGroup>
  </Tab>
</Tabs>

Upon a successful creation, you'll see a confirmation message similar to the following:

```bash theme={null}
$ miru release create \
  --version v1.0.0 \
  --schemas ./{schema-language}/{schema-type}/

◐ Creating release v1.0.0

  ✓ Pushed git commit (new)
    1c7f7a8 · mirurobotics/getting-started

  ◐ Pushing schemas
    ✓ Mobility · SCH-D5nFP (new)
    ✓ Planning · SCH-37QAr (new)
    ✓ Communication · SCH-9WfCx (new)

✓ Created release v1.0.0
```

<Info>
  Git metadata is pulled from the local Git repository that the schemas are defined in.
</Info>

To view the release in Miru, navigate to the [releases page](https://app.mirurobotics.com/releases) and click into the release.

<Frame>
  ![Releases page](https://assets.mirurobotics.com/docs/v04/images/releases/page.png)
</Frame>

Then select the overview tab at the top of the page to view the release's details.

<Frame>
  ![Release overview page](https://assets.mirurobotics.com/docs/v04/images/releases/overview.png)
</Frame>

For a more comprehensive guide on creating releases, visit the [define releases](/cfg-mgmt/create-a-release) documentation. For a concise reference of the CLI command, visit the [CLI Reference](/references/cli/release-create).
