7.9 KiB
stamp
A language-agnostic, changesets-style versioning and changelog tool. Works with any project type and supports monorepos.
Overview
stamp is inspired by the Changesets workflow, but without the Node.js dependency. It works by having contributors add small stamp files (.stamp/*.md) alongside their code changes. When it's time to release, stamp consumes those files, bumps versions, updates changelogs, creates git tags, and publishes releases to GitHub or Gitea.
Installation
Via Mise:
# mise.toml
[tools]
"go:github.com/thokra/stamp/cmd/stamp" = "latest"
Or with go install:
go install github.com/thokra/stamp/cmd/stamp@latest
Or build from source:
git clone https://github.com/thokra/stamp
cd stamp
go build -o bin/stamp ./cmd/stamp
Quick Start
1. Create stamp.toml at the root of your repository
[[projects]]
name = "my-app"
path = "."
version = "0.1.0"
[projects.publish]
tags = true
releases = true
artifacts = ["dist/my-app-*"]
See examples/stamp.toml for a fully annotated example.
2. Add a stamp file when making a change
# Interactive
stamp add
# Non-interactive (great for scripts and AI agents)
stamp add --project=my-app --bump=minor --message="Added new feature"
This creates a .stamp/<random-slug>.md file. Commit it alongside your code.
3. Check pending stamps
stamp status
📦 Pending stamps: 2
PROJECT CURRENT NEXT BUMP STAMPS
------- ------- ---- ---- ------
my-app 1.2.3 1.3.0 minor 2
4. Release
# Bump versions and update changelogs
stamp version
# Create git tags, GitHub/Gitea releases, and upload artifacts
STAMP_REPO=owner/repo stamp publish
Commands
stamp add
Creates a new stamp file describing a change.
| Flag | Description |
|---|---|
--project |
Project name to include (repeatable) |
--bump |
Bump type: major, minor, patch, premajor, preminor, prepatch, prerelease |
--message |
Description of the change |
--no-interactive |
Disable interactive prompts (requires --project, --bump, --message) |
--slug |
Custom filename slug (default: auto-generated, e.g. brave-river) |
stamp status
Shows all pending stamp files and the projected next version for each project.
| Flag | Description |
|---|---|
--json |
Output as JSON |
stamp version
Consumes all pending stamp files, bumps versions in stamp.toml, and prepends a new entry to each project's CHANGELOG.md. Then stages and commits the changes via git.
| Flag | Description |
|---|---|
--snapshot <id> |
Create a pre-release with the given identifier (e.g. alpha, rc) |
--no-commit |
Apply changes without creating a git commit |
stamp publish
Creates git tags and publishes releases (with optional artifact uploads) to GitHub or Gitea.
| Flag | Description |
|---|---|
--dry-run / -n |
Print what would happen without executing |
--project |
Only publish a specific project |
Requires STAMP_REPO=owner/repo to be set. Detects GitHub vs Gitea automatically via the GITEA_BASE_URL environment variable.
Tag format: <name>@v<version> (e.g. my-app@v1.3.0).
stamp comment
Posts or updates a PR comment summarising pending stamps. Useful in CI to remind contributors to add stamp files or to show reviewers what versions will change.
- No stamps found → warns the author with instructions on how to add one.
- Stamps found → shows a table of affected projects and their next versions.
| Flag | Description |
|---|---|
--pr |
Pull request number (required) |
--repo |
Repository slug owner/repo (defaults to STAMP_REPO or GITHUB_REPOSITORY) |
Stamp File Format
Stamp files live in .stamp/ and use Markdown with YAML or TOML frontmatter.
YAML (default)
---
bumps:
my-app: minor
my-lib: patch
---
Short description used as the changelog entry.
- Optional bullet points for more detail.
TOML
+++
[bumps]
my-app = "minor"
+++
Short description.
Bump types
| Type | Description |
|---|---|
major |
Breaking change — 1.2.3 → 2.0.0 |
minor |
New feature — 1.2.3 → 1.3.0 |
patch |
Bug fix — 1.2.3 → 1.2.4 |
premajor |
Pre-release major — 1.2.3 → 2.0.0-alpha.0 |
preminor |
Pre-release minor — 1.2.3 → 1.3.0-alpha.0 |
prepatch |
Pre-release patch — 1.2.3 → 1.2.4-alpha.0 |
prerelease |
Increment pre-release — 1.2.4-rc.0 → 1.2.4-rc.1 |
Configuration Reference (stamp.toml)
# Global settings (all optional)
[config]
base_branch = "main" # Base branch for PR change detection (default: main)
changeset_dir = ".stamp" # Directory for stamp files (default: .stamp)
[[projects]]
name = "my-app"
path = "apps/my-app" # Path relative to repo root
version = "1.2.3" # Current version — updated by `stamp version`
changelog = "CHANGELOG.md" # Relative to path (default: CHANGELOG.md)
[projects.publish]
tags = true
releases = true
artifacts = [
"apps/my-app/dist/my-app-linux-amd64",
"apps/my-app/dist/my-app-darwin-arm64",
]
Environment Variables
| Variable | Purpose |
|---|---|
STAMP_REPO |
Repository slug owner/repo — required for publish and comment |
GITHUB_TOKEN |
GitHub personal access token for releases and PR comments |
GITEA_TOKEN |
Gitea access token |
GITEA_BASE_URL |
Gitea instance URL (e.g. https://gitea.example.com) — also enables Gitea mode |
CI Integration
GitHub Actions — PR check
# .github/workflows/stamp-check.yml
name: stamp check
on:
pull_request:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install stamp
run: go install github.com/thokra/stamp/cmd/stamp@latest
- name: Comment on PR
run: stamp comment --pr=${{ github.event.pull_request.number }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
STAMP_REPO: ${{ github.repository }}
Gitea Actions — PR check
# .gitea/workflows/stamp-check.yml
name: stamp check
on:
pull_request:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install stamp
run: go install github.com/thokra/stamp/cmd/stamp@latest
- name: Comment on PR
run: stamp comment --pr=${{ gitea.event.pull_request.number }}
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
GITEA_BASE_URL: ${{ gitea.server_url }}
STAMP_REPO: ${{ gitea.repository }}
Development
This project uses Mise to manage the Go toolchain and common tasks.
# Build
mise run build
# Run tests
mise run test
# Lint
mise run lint
# Install locally
mise run install
Project Structure
stamp/
├── cmd/stamp/ # CLI entry point and command definitions
├── internal/
│ ├── changeset/ # Stamp file parsing, writing, and slug generation
│ ├── changelog/ # CHANGELOG.md generation and appending
│ ├── config/ # stamp.toml loading, validation, and saving
│ ├── git/ # Git operations (tag, commit, push)
│ ├── gitea/ # Gitea API client (releases, PR comments)
│ ├── github/ # GitHub API client (releases, PR comments)
│ ├── publish/ # Orchestrates tagging and release publishing
│ └── semver/ # Semantic version bumping logic
├── examples/
│ └── stamp.toml # Annotated configuration example
└── docs/
└── workflow.md # Detailed workflow guide
License
MIT