Skip to content

This guide shows you how to manage changelog entries and publish releases with tenzir-ship. You’ll learn the complete workflow from adding your first entry to publishing a release on GitHub.

  • Python 3.12 or newer
  • uv installed locally
  • Access to the repository that hosts the changelog files

Initialize the changelog project:

Terminal window
uvx tenzir-ship init

The init command scaffolds a changelog/ subdirectory for standalone projects, writes config.yaml, and creates unreleased/. In repositories that already expose package.yaml next to changelog/, the CLI switches to package mode automatically and reuses the package id and name without creating an extra config file.

For non-interactive setup, pass --yes. Standalone mode requires an explicit project identifier:

Terminal window
uvx tenzir-ship init --yes --id my-project

Then create your first changelog entry:

Terminal window
uvx tenzir-ship add

The wizard will guide you through the process of creating a new changelog entry. It will ask you for the title, type, and description of the change, as well as the author. The first invocation of add can still bootstrap a missing changelog automatically, but init is the clearer entry point when you only want to set up the workspace.

View the current changelog for your working tree:

Terminal window
uvx tenzir-ship show

The default table lists every entry with row numbers, making it easy to reference specific items. Row numbers count backward from the newest entry, so #1 always targets the latest change.

Inspect a card layout with uvx tenzir-ship show --card 1 or export release notes with uvx tenzir-ship show v0.2.0 --release --markdown.

Add entries as you prepare pull requests:

Terminal window
uvx tenzir-ship add \
--title "Introduce pipeline builder" \
--type feature \
--pr 101

Pass flags for authors, projects, and descriptions to avoid interactive prompts, or provide the details interactively when prompted—there is no GitHub auto-detection.

These tasks cover the most common operations you’ll perform while working on pull requests and reviewing pending changes.

Run uvx tenzir-ship add while preparing pull requests to capture changes:

Terminal window
uvx tenzir-ship add \
--title "Fix authentication timeout" \
--type bugfix \
--description "Resolves session expiry issue." \
--pr 102

The CLI prompts for missing information interactively. Use one-key shortcuts for change types: 0 for breaking, 1 for feature, 2 for bugfix, 3 for change.

Use --co-author to credit additional contributors alongside the automatically inferred author:

Terminal window
uvx tenzir-ship add \
--title "Implement caching layer" \
--type feature \
--co-author claude

This is ideal for AI-assisted development, pair programming, or collaborative contributions. The CLI infers the primary author from environment variables or the GitHub CLI, then appends co-authors in the order you specify:

Terminal window
uvx tenzir-ship add \
--title "Refactor authentication" \
--type change \
--co-author claude \
--co-author copilot \
--pr 150

You can also combine --author with --co-author to set the primary author explicitly:

Terminal window
uvx tenzir-ship add \
--title "Fix race condition" \
--type bugfix \
--author alice \
--co-author bob

List all unreleased entries:

Terminal window
uvx tenzir-ship show unreleased

Show detailed information for a specific entry:

Terminal window
uvx tenzir-ship show --card 1

The card view displays detailed metadata and the full entry body:

❯ tenzir-ship show --card 1
╭─ 🐞 Normalize release note paragraphs ───────────────────────────────────╮
│ Entry ID: normalize-release-note-paragraphs │
│ Type: bugfix │
│ Created: 2025-10-27 │
│ Authors: @codex │
│ Status: Released in v0.4.1 │
│ ──────────────────────────────────────────────────────────────────────── │
│ GitHub release notes now collapse soft line breaks from entry bodies so │
│ paragraphs render as expected. │
╰──────────────────────────────────────────────────────────────────────────╯

Filter by project when working with multiple projects:

Terminal window
uvx tenzir-ship show --project core

Run validation checks to catch issues early:

Terminal window
uvx tenzir-ship validate

The validator reports missing metadata, unused entries, duplicate entry IDs, and configuration drift. It also checks changelog directory layout and flags stray items (for example an unexpected changelog/next/ directory). Add this to CI pipelines to enforce metadata completeness.

Get an overview of your project’s release history and entry distribution:

Terminal window
uvx tenzir-ship stats

Single projects show a vertical card layout with sections for project metadata, releases, entry types, and status. Multi-module projects display a compact table comparing all modules.

Export statistics as JSON for automation:

Terminal window
uvx tenzir-ship stats --json

Once you’ve accumulated unreleased entries, you can cut a release, export notes, and publish to GitHub.

Preview the release before committing changes:

Terminal window
uvx tenzir-ship release create

The command shows which entries will be included and performs a dry run. When the summary looks good, re-run with --yes to commit the changes:

Terminal window
uvx tenzir-ship release create --yes

This auto-bumps the version from the unreleased entry types, creates releases/<resolved-version>/, generates notes.md, and updates manifest.yaml.

The --patch, --minor, and --major shortcuts resolve from the latest stable release. The same stable-only rule applies to show latest, and release version. In contrast, release publish without a version targets the latest release, including release candidates.

By default, release create also updates common package-manager version files (package.json, pyproject.toml, project.toml, Cargo.toml) when present in the changelog root or, for changelog/ projects, in the parent directory. For advanced repositories with custom release scripts, disable built-in bumps in config.yaml:

release:
version_bump_mode: off

If changelog structure is invalid, release create and release publish fail fast with detailed errors. Other commands emit warnings so you can fix layout problems before cutting a release.

Use version bump shortcuts instead of typing the full version:

Terminal window
uvx tenzir-ship release create --patch --yes
uvx tenzir-ship release create --minor --yes
uvx tenzir-ship release create --major --yes

Use these manual bump flags only when the automatic detection is not the right fit for the release.

Pass an explicit stable version only as a rare exact override, for example when you need to re-cut a failed tagged release or match an externally dictated version:

Terminal window
uvx tenzir-ship release create v5.4.0 --yes

Add an inline intro summary:

Terminal window
uvx tenzir-ship release create \
--intro "Major stability improvements." \
--yes

Alternatively, provide intro content from a file:

Terminal window
uvx tenzir-ship release create \
--intro-file intro.md \
--yes

The intro file can include Markdown links, call-outs, or image references. The command embeds its content in manifest.yaml and includes it in notes.md.

Create or continue a release candidate with:

Terminal window
uvx tenzir-ship release create --rc --yes

This snapshots the current unreleased/ queue into a vX.Y.Z-rc.N release without consuming those entry files. Each new -rc.N supersedes the previous RC snapshot for that stable target, so the active candidate stays cumulative while old RC manifests do not remain in release history.

To steer the inferred base version, prefer a manual bump such as release create --rc --minor. Pass an explicit stable version only when you need an exact base:

Terminal window
uvx tenzir-ship release create v5.4.0 --rc --yes

Once release candidates exist for a stable target, keep the workflow on that series:

Terminal window
# Continue the RC series
uvx tenzir-ship release create --rc --yes
# Promote the latest release candidate automatically
uvx tenzir-ship release create --yes

The RC workflow has three outcomes only:

  • Run release create --rc to continue the current RC series.
  • Run release create without a version or bump flag to promote the active RC.
  • Run release create <new-version> or a manual bump flag to leave the RC cycle and ship a different stable release instead.

Promoting to stable closes the RC cycle and removes that cycle’s vX.Y.Z-rc.N manifests from releases/. An explicit version matching the active RC base is rejected, and manual bump flags never promote the active RC.

Export release notes for a specific version:

Terminal window
uvx tenzir-ship show v5.4.0 --release --markdown

Export as JSON for programmatic use:

Terminal window
uvx tenzir-ship show v5.4.0 --release --json

Use compact format for bullet-list layout:

Terminal window
uvx tenzir-ship show v5.4.0 --release --compact --markdown

Preview unreleased entries as if they were already released:

Terminal window
uvx tenzir-ship show unreleased --release --markdown

Export all releases in a single invocation for batch processing:

Terminal window
uvx tenzir-ship show all --release --json

This exports every release as a JSON array, useful for documentation sync scripts that need all release data at once.

To render the latest stable release without spelling out the version, use:

Terminal window
uvx tenzir-ship show latest --release --markdown

This resolves the newest stable release only. Release candidates never replace latest.

Publish directly from the changelog project using the CLI:

Terminal window
uvx tenzir-ship release publish --yes

Include tagging and pushing via the CLI:

Terminal window
uvx tenzir-ship release publish --tag --yes

If you do pass a version, tenzir-ship publishes that exact release:

Terminal window
uvx tenzir-ship release publish v5.4.0 --yes

Draft or prerelease variants:

Terminal window
uvx tenzir-ship release publish v5.4.0 --draft --yes
uvx tenzir-ship release publish v5.4.0 --prerelease --yes

When you publish vX.Y.Z-rc.N, tenzir-ship automatically creates a GitHub prerelease and prevents GitHub from marking it as the latest release. You don’t need to add --prerelease or --no-latest for RC tags. Because version-less publish now targets the latest release, the same command works after both stable releases and RCs.

Trigger the bundled GitHub Actions workflow

Section titled “Trigger the bundled GitHub Actions workflow”

If you want to cut releases from GitHub Actions, start by adding a workflow file to your repository:

.github/workflows/release.yaml
name: Release
on:
workflow_dispatch:
inputs:
bump:
description: Version bump type
required: false
default: auto
type: choice
options:
- auto
- minor
- patch
- major
version:
description: Explicit stable version override
required: false
type: string
rc:
description: Create or continue the release-candidate series
required: false
default: false
type: boolean
intro:
description: 1-2 sentence release introduction
required: true
type: string
title:
description: User-facing release title
required: false
type: string
jobs:
release:
uses: tenzir/ship/.github/workflows/reusable-release.yaml@<version>
with:
bump: ${{ inputs.bump }}
version: ${{ inputs.version }}
rc: ${{ inputs.rc }}
intro: ${{ inputs.intro }}
title: ${{ inputs.title }}
secrets: inherit

Replace <version> with the tenzir-ship release tag you want to pin to, for example v1.5.0. Add the advanced inputs from the reference page only when your repository needs them.

That release.yaml wrapper mirrors the CLI options. Use rc: true to create or continue a release-candidate series:

Terminal window
gh workflow run release.yaml \
-f intro="Preview the upcoming release." \
-f title="Release candidate" \
-f rc=true

When an RC is already outstanding, trigger the same workflow without rc, bump, or version to promote the latest candidate automatically:

Terminal window
gh workflow run release.yaml \
-f intro="Ship the latest release candidate." \
-f title="Stable release"

To leave the RC cycle and ship a different stable release instead, pass that new explicit version, such as v5.4.1 or v5.5.0.

This walkthrough shows how to initialize a repository, add entries, preview the backlog, and publish a release manifest with custom introductory content.

Initialize a new changelog project from your project root:

Terminal window
cd my-project
uvx tenzir-ship add \
--title "Add pipeline builder" \
--type feature \
--description "Introduces the new pipeline builder UI." \
--author alice \
--pr 101

The first add invocation scaffolds the project automatically, creating a changelog/ subdirectory—no manual config editing needed. After the command completes, inspect changelog/config.yaml (or update package.yaml if you’re using the package layout):

id: my-project
name: My Project

Record additional changes with authors and pull request numbers:

Terminal window
uvx tenzir-ship add \
--title "Fix ingest crash" \
--type bugfix \
--description "Resolves ingest worker crash when tokens expire." \
--author bob \
--pr 102 \
--pr 115
uvx tenzir-ship add \
--title "Improve CLI help" \
--type change \
--description "Tweaks command descriptions for clarity." \
--author carol \
--pr 103

Each invocation writes a Markdown file inside changelog/unreleased/. For example, add-pipeline-builder.md looks like:

---
title: Add pipeline builder
type: feature
author: alice
created: 2025-10-16T09:30:00Z
pr: 101
---
Introduces the new pipeline builder UI.

You can use either singular (author, pr, component) or plural (authors, prs, components) keys. The singular form is shorthand for single values.

If an entry spans multiple pull requests, repeat --pr during add. The CLI stores a prs: list in the generated frontmatter automatically.

View all entries in table format:

Terminal window
uvx tenzir-ship show

Inspect a detailed card for any entry:

Terminal window
uvx tenzir-ship show --card 1

Author an intro snippet that can include Markdown links, call-outs, or image references. Save it as intro.md:

Welcome to the first release of the Tenzir changelog!
![Release Overview](images/release-overview.png)
We cover breaking changes, highlights, upgrades, and fixes below.

Create the release with the custom intro file:

Terminal window
uvx tenzir-ship release create v0.1.0 \
--intro-file intro.md \
--yes

The tool writes release artifacts under releases/v0.1.0/:

  • manifest.yaml records the release date and intro:

    created: 2025-10-18
    intro: |-
    Welcome to the first release of the Tenzir changelog!
    ![Release Overview](images/release-overview.png)
    We cover breaking changes, highlights, upgrades, and fixes below.
  • notes.md stitches together the intro and generated sections:

    Welcome to the first release of the Tenzir changelog!
    ![Release Overview](images/release-overview.png)
    We cover breaking changes, highlights, upgrades, and fixes below.
    ## Features
    - **Add pipeline builder**: Introduces the new pipeline builder UI.
    ## Bug fixes
    - **Fix ingest crash**: Resolves ingest worker crash when tokens expire.
    ## Changes
    - **Improve CLI help**: Tweaks command descriptions for clarity.
  • entries/ contains the archived entry files moved from unreleased/.

Verify everything is correct:

Terminal window
uvx tenzir-ship validate

A clean run prints All changelog files look good!. You can remove intro.md now that its content is embedded in the release file.

Print the release notes:

Terminal window
uvx tenzir-ship show v0.1.0 --release --markdown

Export as JSON for programmatic use:

Terminal window
uvx tenzir-ship show v0.1.0 --release --json

Last updated: