# 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. - TypeScript SDK `@openviking/sdk`: for TypeScript and JavaScript HTTP clients. - OpenCode plugin `@openviking/opencode-plugin`: for OpenCode integration distribution. - Controlplane MCP `mcp-server-openviking-controlplane`: MCP server and `ov-cp` CLI for the control plane. - 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`. | | `@openviking/sdk` (TypeScript) | `typescript-sdk@X.Y.Z` | TypeScript SDK tag. | | 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 `20. Release TOS Upload` workflow uploads the source archive and installation scripts to TOS. A formal main release publishes to: - PyPI: `openviking` - GHCR: `ghcr.io//` - Docker Hub: `/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//openviking--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@`. 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 `OpenViking OpenClaw plugin release` 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. ## Other Release Flows - **TypeScript SDK Release** (`typescript-sdk-release.yml`): triggered by pushing a `typescript-sdk@X.Y.Z` tag, or manually. Publishes `@openviking/sdk` to npm. - **OpenCode Plugin Release** (`opencode-plugin-release.yml`): runs automatically on pushes to `main` that touch `examples/opencode-plugin/**`, or manually. Publishes `@openviking/opencode-plugin` to npm and skips versions that already exist. - **Controlplane MCP Release** (`controlplane-mcp-release.yml`): manual only. Publishes `mcp-server-openviking-controlplane`, including the `ov-cp` CLI. ## 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 former root-level `First Release to PyPI` workflow has been removed. The current `bot/` directory does not contain an independent `pyproject.toml`, `setup.py`, or `setup.cfg`, so it cannot be released as a standalone Python package from this repository. 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==` or `pip install openviking-sdk==` 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.