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.
Prerequisites
Section titled “Prerequisites”- Python 3.12 or newer
uvinstalled locally- Access to the repository that hosts the changelog files
Quick start
Section titled “Quick start”Initialize the changelog project:
uvx tenzir-ship initThe 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:
uvx tenzir-ship init --yes --id my-projectThen create your first changelog entry:
uvx tenzir-ship addThe 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:
uvx tenzir-ship showThe 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:
uvx tenzir-ship add \ --title "Introduce pipeline builder" \ --type feature \ --pr 101Pass flags for authors, projects, and descriptions to avoid interactive prompts, or provide the details interactively when prompted—there is no GitHub auto-detection.
Daily development workflow
Section titled “Daily development workflow”These tasks cover the most common operations you’ll perform while working on pull requests and reviewing pending changes.
Add entries for pull requests
Section titled “Add entries for pull requests”Run uvx tenzir-ship add while preparing pull requests to capture changes:
uvx tenzir-ship add \ --title "Fix authentication timeout" \ --type bugfix \ --description "Resolves session expiry issue." \ --pr 102The 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.
Add co-authors
Section titled “Add co-authors”Use --co-author to credit additional contributors alongside the automatically
inferred author:
uvx tenzir-ship add \ --title "Implement caching layer" \ --type feature \ --co-author claudeThis 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:
uvx tenzir-ship add \ --title "Refactor authentication" \ --type change \ --co-author claude \ --co-author copilot \ --pr 150You can also combine --author with --co-author to set the primary author
explicitly:
uvx tenzir-ship add \ --title "Fix race condition" \ --type bugfix \ --author alice \ --co-author bobView pending changes
Section titled “View pending changes”List all unreleased entries:
uvx tenzir-ship show unreleasedShow detailed information for a specific entry:
uvx tenzir-ship show --card 1The 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:
uvx tenzir-ship show --project coreValidate changelog structure
Section titled “Validate changelog structure”Run validation checks to catch issues early:
uvx tenzir-ship validateThe 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.
View project statistics
Section titled “View project statistics”Get an overview of your project’s release history and entry distribution:
uvx tenzir-ship statsSingle 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:
uvx tenzir-ship stats --jsonRelease workflow
Section titled “Release workflow”Once you’ve accumulated unreleased entries, you can cut a release, export notes, and publish to GitHub.
Create a release
Section titled “Create a release”Preview the release before committing changes:
uvx tenzir-ship release createThe 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:
uvx tenzir-ship release create --yesThis 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: offIf 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:
uvx tenzir-ship release create --patch --yesuvx tenzir-ship release create --minor --yesuvx tenzir-ship release create --major --yesUse 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:
uvx tenzir-ship release create v5.4.0 --yesAdd an inline intro summary:
uvx tenzir-ship release create \ --intro "Major stability improvements." \ --yesAlternatively, provide intro content from a file:
uvx tenzir-ship release create \ --intro-file intro.md \ --yesThe 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 a release candidate
Section titled “Create a release candidate”Create or continue a release candidate with:
uvx tenzir-ship release create --rc --yesThis 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:
uvx tenzir-ship release create v5.4.0 --rc --yesPromote an existing release candidate
Section titled “Promote an existing release candidate”Once release candidates exist for a stable target, keep the workflow on that series:
# Continue the RC seriesuvx tenzir-ship release create --rc --yes
# Promote the latest release candidate automaticallyuvx tenzir-ship release create --yesThe RC workflow has three outcomes only:
- Run
release create --rcto continue the current RC series. - Run
release createwithout 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
Section titled “Export release notes”Export release notes for a specific version:
uvx tenzir-ship show v5.4.0 --release --markdownExport as JSON for programmatic use:
uvx tenzir-ship show v5.4.0 --release --jsonUse compact format for bullet-list layout:
uvx tenzir-ship show v5.4.0 --release --compact --markdownPreview unreleased entries as if they were already released:
uvx tenzir-ship show unreleased --release --markdownExport all releases in a single invocation for batch processing:
uvx tenzir-ship show all --release --jsonThis 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:
uvx tenzir-ship show latest --release --markdownThis resolves the newest stable release only. Release candidates never replace
latest.
Publish to GitHub
Section titled “Publish to GitHub”Publish directly from the changelog project using the CLI:
uvx tenzir-ship release publish --yesInclude tagging and pushing via the CLI:
uvx tenzir-ship release publish --tag --yesIf you do pass a version, tenzir-ship publishes that exact release:
uvx tenzir-ship release publish v5.4.0 --yesDraft or prerelease variants:
uvx tenzir-ship release publish v5.4.0 --draft --yesuvx tenzir-ship release publish v5.4.0 --prerelease --yesWhen 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:
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: inheritReplace <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:
gh workflow run release.yaml \ -f intro="Preview the upcoming release." \ -f title="Release candidate" \ -f rc=trueWhen an RC is already outstanding, trigger the same workflow without rc,
bump, or version to promote the latest candidate automatically:
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.
End-to-end Walkthrough
Section titled “End-to-end Walkthrough”This walkthrough shows how to initialize a repository, add entries, preview the backlog, and publish a release manifest with custom introductory content.
Create a project
Section titled “Create a project”Initialize a new changelog project from your project root:
cd my-projectuvx tenzir-ship add \ --title "Add pipeline builder" \ --type feature \ --description "Introduces the new pipeline builder UI." \ --author alice \ --pr 101The 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-projectname: My ProjectCapture entries
Section titled “Capture entries”Record additional changes with authors and pull request numbers:
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 103Each invocation writes a Markdown file inside changelog/unreleased/. For
example, add-pipeline-builder.md looks like:
---title: Add pipeline buildertype: featureauthor: alicecreated: 2025-10-16T09:30:00Zpr: 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.
Preview the changelog
Section titled “Preview the changelog”View all entries in table format:
uvx tenzir-ship showInspect a detailed card for any entry:
uvx tenzir-ship show --card 1Prepare release notes
Section titled “Prepare release notes”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!

We cover breaking changes, highlights, upgrades, and fixes below.Cut the release
Section titled “Cut the release”Create the release with the custom intro file:
uvx tenzir-ship release create v0.1.0 \ --intro-file intro.md \ --yesThe tool writes release artifacts under releases/v0.1.0/:
-
manifest.yamlrecords the release date and intro:created: 2025-10-18intro: |-Welcome to the first release of the Tenzir changelog!We cover breaking changes, highlights, upgrades, and fixes below. -
notes.mdstitches together the intro and generated sections:Welcome to the first release of the Tenzir changelog!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 fromunreleased/.
Validate the project
Section titled “Validate the project”Verify everything is correct:
uvx tenzir-ship validateA clean run prints All changelog files look good!. You can remove intro.md
now that its content is embedded in the release file.
Export the release
Section titled “Export the release”Print the release notes:
uvx tenzir-ship show v0.1.0 --release --markdownExport as JSON for programmatic use:
uvx tenzir-ship show v0.1.0 --release --json