yeet

module
v0.4.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 27, 2026 License: MIT

README

yeet

Automate releases based on conventional commits. Analyzes commit history, calculates the next version, generates changelogs, creates release PRs/MRs, and finalizes merged releases on GitHub or GitLab.

Inspired by release-please.

Install

brew install monkescience/tap/yeet

Or with Go:

go install github.com/monkescience/yeet/cmd/[email protected] # x-yeet-version

Or use the published container image:

docker run --rm ghcr.io/monkescience/yeet:v0.4.6 --help # x-yeet-version

Quick start

# Initialize config in your repo
yeet init

# Preview what the next release would look like
yeet release --dry-run

# Create a release PR/MR
yeet release

# Auto-merge and finalize in the same run
yeet release --auto-merge

Run yeet --help for the full list of commands and flags.

How it works

yeet release does slightly different work depending on repository state:

  1. Before a release PR/MR exists, it scans conventional commits, calculates the next version, updates the changelog/version files, and opens a release PR/MR labeled autorelease: pending.
  2. While that PR/MR is open, rerunning yeet release updates the same release branch instead of creating a second pending release.
  3. After the release PR/MR is merged, the next yeet release run on the base branch creates the tag/provider release from the latest changelog entry and flips the label to autorelease: tagged.

That label lifecycle is operational, not decorative: yeet uses autorelease: pending to discover merged releases that still need tagging, and it expects only one open pending release PR/MR per base branch. If multiple pending PRs/MRs exist, yeet release fails and prints the conflicting URLs so you can close or relabel stale entries.

When auto-merge is enabled (--auto-merge or release.auto_merge in config), yeet merges the release PR/MR and finalizes the release in the same run. Force mode (--auto-merge-force) skips yeet's own readiness gates but does not bypass provider branch protections, required checks, approvals, or missing permissions.

Configuration

yeet reads the nearest ancestor .yeet.yaml by default. Run yeet init to generate one with sensible defaults, or pass --config to write to a custom path. The generated file includes a YAML language server schema modeline for editor validation and autocomplete.

All available options, defaults, and descriptions are defined in the JSON schema. YAML-aware editors that support # yaml-language-server: $schema=... modelines will provide validation and autocomplete automatically. You can pin the schema URL to a release tag for stricter reproducibility.

Repository targeting

yeet resolves the target repository from these sources, highest priority first:

  1. CLI flags (--provider, --host, --owner, --repo, --project)
  2. explicit .yeet.yaml values under repository:
  3. the configured repository.remote
  4. the origin remote

When yeet cannot classify a remote host automatically, set the provider and repository explicitly:

# GitHub Enterprise
provider: github

repository:
  host: github.company.com
  owner: platform
  repo: yeet
# GitLab subgroup
provider: gitlab

repository:
  host: gitlab.company.com
  project: group/subgroup/service
Monorepo targets

yeet plans releases per target and creates one combined release PR/MR per base branch. PR workflow settings remain top-level under release: and apply to the combined PR/MR, not individual targets.

targets:
  api:
    type: path
    path: services/api
    tag_prefix: api-v

  web:
    type: path
    path: apps/web
    tag_prefix: web-v

  root:
    type: derived
    includes:
      - api
      - web
    tag_prefix: v
Version file markers

yeet release updates only files listed in version_files. Each file must contain yeet markers.

# inline markers
VERSION = "0.4.6" # x-yeet-version
MAJOR = 0 # x-yeet-major
MINOR = 4 # x-yeet-minor
PATCH = 6 # x-yeet-patch

# block markers
# x-yeet-start-version
image: ghcr.io/acme/app:0.4.6
appVersion: "0.4.6"
# x-yeet-end

For calver repositories, yeet also supports aliases:

  • x-yeet-year (alias of x-yeet-major)
  • x-yeet-month (alias of x-yeet-minor)
  • x-yeet-micro (alias of x-yeet-patch)
  • x-yeet-start-year|month|micro for calver block markers
  • x-yeet-end closes the block
Changelog references

yeet can link issue tracker references in generated changelogs. References are extracted from two sources: inline patterns matched in commit descriptions, and conventional commit footers.

changelog:
  references:
    patterns:
      - pattern: "JIRA-\\d+"
        url: "https://jira.example.com/browse/{value}"
      - pattern: "#\\d+"
        url: ""  # plain text, GitHub auto-links these
    footers:
      Refs: "https://jira.example.com/browse/{value}"
      Closes: ""

Inline patterns match against the commit description using regex and replace matches with links. A commit like feat: add OAuth2 support JIRA-123 produces:

- add OAuth2 support [JIRA-123](https://jira.example.com/browse/JIRA-123) (abc1234)

Footer references extract values from conventional commit footers and append them after the commit hash. A commit with a Refs: JIRA-456 footer produces:

- add OAuth2 support (abc1234) ([JIRA-456](https://jira.example.com/browse/JIRA-456))

Use {value} as the placeholder in URL templates. An empty URL string renders the reference as plain text without linking. Both patterns and footers can be configured per target in monorepo setups.

Versioning strategies

Semantic Versioning (semver)

Follows semver with configurable pre-1.0 behavior.

For versions >= 1.0.0:

  • feat -> minor
  • fix, perf -> patch
  • Breaking changes (! or BREAKING CHANGE footer) -> major

For versions < 1.0.0 (default behavior with pre_major_breaking_bumps_minor: true and pre_major_features_bump_patch: true):

  • feat -> patch
  • fix, perf -> patch
  • Breaking changes (! or BREAKING CHANGE footer) -> minor

This keeps pre-1.0 breaking changes from automatically jumping to 1.0.0.

Set pre_major_breaking_bumps_minor: false to let breaking changes bump major (triggering 1.0.0), or pre_major_features_bump_patch: false to let features bump minor as they do post-1.0. These options can also be overridden per target in monorepo configurations.

Release-As commit footers (for example Release-As: 1.0.0) override automatic semver bumping. The value must be a stable semver version greater than the current version. Release-As is case-insensitive and applies only to semver repositories; calver repositories ignore it.

Calendar Versioning (calver)

Uses YYYY.0M.MICRO format (e.g., 2026.02.1). The micro counter resets when the year/month changes.

Authentication

yeet needs a provider API token whenever it creates or updates PRs/MRs, applies release labels, or publishes releases.

GitHub

Export either GITHUB_TOKEN or GH_TOKEN:

export GITHUB_TOKEN=ghp_xxx
yeet release --dry-run

For GitHub Enterprise, also set GITHUB_URL to the API base URL or let yeet derive it from the configured repository host:

export GITHUB_TOKEN=ghp_xxx
export GITHUB_URL=https://github.example.com/api/v3/
yeet release

The token needs contents: write, pull-requests: write, and issues: write permissions.

GitLab

Export either GITLAB_TOKEN or GL_TOKEN:

export GITLAB_TOKEN=glpat-xxx
yeet release --dry-run

For self-hosted GitLab, also set GITLAB_URL:

export GITLAB_TOKEN=glpat-xxx
export GITLAB_URL=https://gitlab.example.com/api/v4
yeet release

The token must be able to create merge requests, manage labels, and publish releases.

CI examples

GitHub Actions with a GitHub App

This example uses a GitHub App installation token instead of the default GITHUB_TOKEN. The app needs contents: write, pull-requests: write, and issues: write repository permissions. Store the app ID as a repository variable and the private key as a repository secret.

name: Release

on:
  push:
    branches:
      - main
  workflow_dispatch:

permissions:
  contents: write
  pull-requests: write
  issues: write

concurrency:
  group: yeet-release-${{ github.ref }}
  cancel-in-progress: true

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Set up Go
        uses: actions/setup-go@v6
        with:
          go-version: stable

      - name: Generate GitHub App token
        id: generate-token
        uses: actions/create-github-app-token@v2
        with:
          app-id: ${{ vars.RELEASE_PLEASE_APP_ID }}
          private-key: ${{ secrets.RELEASE_PLEASE_APP_PRIVATE_KEY }}
          owner: ${{ github.repository_owner }}

      - name: Run yeet release
        run: |
          go install github.com/monkescience/yeet/cmd/[email protected] # x-yeet-version
          yeet release
        env:
          GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
GitLab CI

Set GITLAB_TOKEN as a masked CI/CD variable. The entrypoint: [""] override is required so GitLab runs the job script with sh instead of the image's default yeet entrypoint.

release:
  stage: release
  image:
    name: ghcr.io/monkescience/yeet:v0.4.6 # x-yeet-version
    entrypoint: [""]
  variables:
    GIT_STRATEGY: fetch
    GIT_DEPTH: "0"
  script:
    - yeet release
  rules:
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'

Troubleshooting

yeet release keeps wrapped errors for debugging, but the top-level message points at the failure category so you can pick the next fix quickly:

  • configuration file not found: create .yeet.yaml with yeet init at the repo root or pass --config.
  • invalid configuration: fix invalid values in .yeet.yaml before rerunning.
  • repository resolution failed: set provider and/or repository explicitly when the remote host is unsupported or auto-detection cannot classify it.
  • provider setup failed: export the required token (GITHUB_TOKEN/GH_TOKEN or GITLAB_TOKEN/GL_TOKEN) and, for self-hosted providers, verify GITHUB_URL or GITLAB_URL.
  • release execution failed: merge blocked: the release PR/MR is still draft, has conflicts, lacks required approvals/checks, or requests a merge method the provider settings do not allow.
  • release execution failed: multiple pending release PRs/MRs found: close or relabel stale autorelease: pending entries until only one open release PR/MR remains for the base branch.

License

MIT

Directories

Path Synopsis
cmd
yeet command
Package main is the entry point for the yeet CLI.
Package main is the entry point for the yeet CLI.
internal
changelog
Package changelog generates markdown changelogs from conventional commits.
Package changelog generates markdown changelogs from conventional commits.
cli
Package cli defines the command-line interface for yeet.
Package cli defines the command-line interface for yeet.
commit
Package commit provides conventional commit message parsing.
Package commit provides conventional commit message parsing.
config
Package config handles parsing and validation of .yeet.yaml configuration files.
Package config handles parsing and validation of .yeet.yaml configuration files.
provider
Package provider defines the VCS provider interface and implementations for interacting with GitHub and GitLab APIs.
Package provider defines the VCS provider interface and implementations for interacting with GitHub and GitLab APIs.
release
Package release orchestrates the release process by coordinating commit parsing, version calculation, changelog generation, and VCS provider interactions.
Package release orchestrates the release process by coordinating commit parsing, version calculation, changelog generation, and VCS provider interactions.
version
Package version provides versioning strategies for calculating release versions.
Package version provides versioning strategies for calculating release versions.
versionfile
Package versionfile updates version references in configured files.
Package versionfile updates version references in configured files.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL