# OpenViking Release Guide

This document explains the release goals, version and tag conventions, primary release flows, republishing paths, and verification steps for the OpenViking repository. It is based on the tracked GitHub Actions workflows, build configuration, and package configuration in this repository.

## Release Goals

OpenViking does not release a single artifact. A release publishes a set of related assets for different usage paths:

- `openviking` Python package: for users who need the local runtime, server, CLI, and full feature set.
- Python SDK `openviking-sdk`: for lightweight HTTP clients that call an existing OpenViking server.
- Docker images: for containerized deployments, published to GHCR and Docker Hub.
- TOS release assets: for source archives, installation scripts, and stable download paths.
- Rust CLI / npm packages: for users who install the `ov` CLI through npm.
- OpenClaw / ClawHub plugin: for OpenClaw plugin distribution.
- VikingBot: currently distributed through `openviking[bot]` and the official Docker image; historical standalone release entries are documented separately to avoid misuse.

A formal main-package release should keep the Python package, Docker images, and TOS assets on the same main release tag. SDK, CLI, and ClawHub plugin releases use their own tag or version namespaces.

## Version and Tag Conventions

Use the following tag conventions:

| Artifact | Recommended tag / version | Notes |
| --- | --- | --- |
| `openviking` main package | `vX.Y.Z` | Main release tag, for example `v0.3.26`. |
| `openviking-sdk` | `python-sdk@X.Y.Z` | SDK-only tag, for example `python-sdk@0.1.3`. |
| Rust CLI / npm CLI | `cli@X.Y.Z` | CLI-only tag, for example `cli@0.2.0`. |
| ClawHub plugin latest | `YYYY.M.D` or `YYYY.M.D-N` | Generated by the workflow or specified manually. |
| ClawHub plugin dev | `YYYY.M.D-dev.N` | Used for the dev channel. |

The main package version is resolved from Git tags through `setuptools_scm`; formal main releases should use `vX.Y.Z`. The SDK also uses `setuptools_scm`, but it only matches `python-sdk@*` tags so it does not conflict with main package tags.

## Formal Main Package Release Flow

Formal main package releases go through GitHub Releases in the root repository:

1. Confirm the release changes are merged into the target branch and PR / main branch checks have passed.
2. Create a main package tag, for example `v0.3.26`.
3. Publish a GitHub Release based on that tag.
4. The `03. Release` workflow runs when the Release is published.
5. The workflow reuses `_Build Distribution` to build the sdist and multi-platform wheels.
6. The workflow publishes the distributions to PyPI.
7. The workflow builds and pushes multi-architecture Docker images.
8. The `Release TOS Upload` workflow uploads the source archive and installation scripts to TOS.

A formal main release publishes to:

- PyPI: `openviking`
- GHCR: `ghcr.io/<owner>/<repo>`
- Docker Hub: `<dockerhub-user>/openviking`
- TOS: versioned release paths and optional `latest` stable paths

## Manual Main Package Builds, Test Publishing, and Republishing

The root release workflow also supports manual dispatch with these targets:

- `none`: build only, without publishing.
- `testpypi`: publish to TestPyPI.
- `pypi`: publish to PyPI.
- `both`: publish to both TestPyPI and PyPI.

If Python distributions were built successfully but publishing failed, use the `_Publish Distribution` workflow with the relevant build run id. This path is intended for recovery and republishing, not as the normal release entry point.

## Docker Image Publishing and Republishing

During a formal main release, Docker images are built and published by the main release workflow. Images are pushed to GHCR and Docker Hub with the release version tag and `latest` tag.

The repository also provides a standalone `Build and Push Docker Image` workflow for:

- Rebuilding an image with a manually specified version.
- Building images from the `main` branch.
- Rebuilding or republishing images after a tag-triggered run.

Note: the standalone Docker workflow currently also runs on `v*.*.*` tag pushes. The formal GitHub Release source of truth is still the `03. Release` workflow; treat the standalone Docker workflow as an image-specific build or republish path to avoid confusing it with the formal release artifact set.

To avoid duplicate publishing, use the main release workflow for formal versions. Use the standalone Docker workflow only for image republishing or special verification.

## TOS Release Assets

The TOS release flow creates a source archive and uploads these assets:

- `releases/<tag>/openviking-<tag>-source.zip`
- Claude Code memory plugin install script
- Codex memory plugin install script
- Matching TOS install scripts

Formal GitHub Releases trigger the TOS upload automatically. Manual republishing can specify a tag and use `update_latest` to decide whether to overwrite stable paths.

If TOS secrets are not fully configured, the workflow skips uploading and reports it in the step summary without failing the whole workflow.

## Python SDK Release Flow

The Python SDK lives under `sdk/python`, and its PyPI package name is `openviking-sdk`. SDK releases use an independent tag namespace:

```text
python-sdk@X.Y.Z
```

Typical flow:

1. Merge SDK-related changes.
2. Create and push a tag, for example `python-sdk@0.1.3`.
3. The `Python SDK Release` workflow runs from the tag.
4. The workflow resolves the SDK version with `setuptools_scm`.
5. The workflow verifies that the current tag equals `python-sdk@<resolved-version>`.
6. The workflow builds `sdk/python` and publishes it to PyPI.

The SDK workflow also supports manual dispatch with `testpypi`, `pypi`, or `both`. Manual dispatch is useful for validation and recovery; formal SDK releases should use `python-sdk@X.Y.Z` tags.

## Rust CLI / npm Release Flow

The Rust CLI tag format is:

```text
cli@X.Y.Z
```

After a `cli@*` tag is pushed, the `Rust CLI Build` workflow builds the `ov` binary for multiple platforms and publishes npm packages:

- Platform packages: `@openviking/cli-linux-x64`, `@openviking/cli-linux-arm64`, `@openviking/cli-darwin-x64`, `@openviking/cli-darwin-arm64`, `@openviking/cli-win32-x64`
- Wrapper package: `@openviking/cli`

The workflow injects the version from the tag into the platform packages and wrapper package. If the same version already exists on npm, the workflow skips the already published package.

## OpenClaw / ClawHub Plugin Release

The OpenClaw plugin is published manually through the `ClawHub release (OpenViking plugin)` workflow. Inputs include:

- `version`: optional; when empty, the workflow generates a date-based version.
- `channel`: `auto`, `dev`, or `latest`.
- `changelog`: release notes for the plugin release.

The workflow resolves the channel and version, packs `examples/openclaw-plugin`, pushes a generated package branch, and then calls ClawHub's official trusted publishing workflow.

Recommended usage:

- Use `latest` or `auto` for the formal channel.
- Use `dev` for development validation.
- When specifying `version` manually, ensure it matches the required format for the selected channel.

## VikingBot Release Notes

VikingBot is no longer maintained as a recommended standalone PyPI release path. The current distribution model is through the main package:

- Python install entry point: `pip install "openviking[bot]"`.
- Source development entry point: `uv pip install -e ".[bot]"`.
- The official Docker image already includes VikingBot by default; disable it with `--without-bot` or `OPENVIKING_WITH_BOT=0`.

The root repository still contains a `First Release to PyPI` workflow, but it builds an independent Python package from the `bot` directory. The current `bot/` directory does not contain an independent `pyproject.toml`, `setup.py`, or `setup.cfg`, so this workflow should be treated as historical leftover configuration and should not be used for new VikingBot releases.

The file `bot/.github/workflows/release.yml` lives under the `bot` subdirectory. Treat it as a historical bot subproject or split-repository release reference, not as a GitHub Actions workflow that the current root repository can directly trigger. Restoring an independent `vikingbot` package would first require adding standalone Python package metadata, a versioning strategy, and a publishing credential strategy under `bot/`.

## Pre-release Checklist

Before releasing, confirm that:

- The changes to be released are merged into the target branch.
- CI / PR checks have passed.
- The version has not already been published to PyPI, npm, or the Docker registry.
- The tag name follows the convention for the target artifact.
- Python dependencies, build configuration, and README files are synchronized.
- Required secrets or trusted publishing settings are configured for Docker Hub, PyPI/TestPyPI, TOS, npm, and ClawHub.
- Release notes are ready and document breaking changes, migration steps, and important fixes.

## Post-release Verification Checklist

After releasing, verify that:

- The package version on PyPI / TestPyPI matches the tag.
- `pip install openviking==<version>` or `pip install openviking-sdk==<version>` succeeds.
- Docker registries contain the version tag and the expected `latest` / `main` tag.
- The multi-architecture Docker manifest can be pulled.
- TOS versioned paths and stable paths are accessible.
- npm contains the expected CLI platform packages and wrapper package.
- The ClawHub plugin channel and version match expectations.

## Failure Handling and Republishing Principles

- PyPI and npm versions generally cannot be overwritten; if package content is wrong, publish a new version.
- Docker `latest`, `main`, and manually specified tags can be rebuilt through the image republishing workflow, but keep released version tags traceable.
- Treat TOS versioned paths as immutable assets; stable paths may be overwritten through the manual workflow.
- If build succeeds but publishing fails, prefer the republishing workflow or manual dispatch instead of recreating the same tag with different content.
- If a tag is wrong, delete and recreate it only if it has not triggered irreversible publishing.
