// Ship a new dtctl release — bump version, write changelog entries, run tests, commit, tag, push, and write GitHub release notes. Use this skill whenever the user says "release", "ship it", "cut a release", "new version", "bump version", "publish", or asks about the dtctl release process. Also use when the user wants to update CHANGELOG.md for a release or write GitHub release notes.
Ship a new dtctl release — bump version, write changelog entries, run tests, commit, tag, push, and write GitHub release notes. Use this skill whenever the user says "release", "ship it", "cut a release", "new version", "bump version", "publish", or asks about the dtctl release process. Also use when the user wants to update CHANGELOG.md for a release or write GitHub release notes.
dtctl Release Process
This skill walks through shipping a new dtctl release end-to-end. The process has six phases: analyze, version, changelog, test, commit/tag/push, and GitHub release notes.
Prerequisites
You must be on the main branch with all feature branches merged
The working tree must be clean (git status shows no uncommitted changes)
If the user is on a feature branch, merge to main first (or ask them to)
Pre-flight check:
git branch --show-current # Must be "main"
git status # Must be clean
git pull origin main # Must be up to date with remote
If any check fails, stop and resolve before continuing.
Phase 1: Analyze Changes Since Last Release
Identify what changed since the last release to determine the version bump and write good release notes.
# Find the latest release tag
git tag --sort=-version:refname | head -5
# List all commits since that tag
git log <last-tag>..HEAD --oneline
# Check the current Unreleased section in CHANGELOG.md
Read the commits carefully and group them into:
Features (new commands, new flags, new integrations)
For each significant feature, explore the actual implementation files to understand what it does. Don't just rely on commit messages — read the code so you can write accurate, detailed release notes.
Edit pkg/version/version.go — change the Version variable:
var Version = "X.Y.Z"// update this
This is the only place the version is hardcoded. GoReleaser injects it at build time via -ldflags, but the fallback value here should always match the latest release.
3b. Update CHANGELOG.md
The changelog follows Keep a Changelog format. Move items from [Unreleased] into a new version section:
## [Unreleased]## [X.Y.Z] - YYYY-MM-DD### Added-**Feature name** — description with enough detail that users understand what it does and how to use it; include CLI examples where relevant
### Fixed-**Bug summary** — what was broken and how it's fixed now
### Changed-**Change summary** — what changed and why
### Security-**Security fix** — what was vulnerable and what was upgraded
### Documentation-**Doc name** — what was added or updated
Also add the comparison link at the bottom of the file:
Creates a GitHub Release with auto-generated changelog
Pushes an updated Homebrew cask to dynatrace-oss/homebrew-tap
Homebrew
No manual Homebrew update is needed. GoReleaser's homebrew_casks config in .goreleaser.yaml automatically pushes the updated cask to the tap repository using a GitHub App token. The skip_upload: auto setting prevents pre-release tags from being published.
Phase 6: Write GitHub Release Notes
After the tag is pushed, update the GitHub release with polished release notes. The auto-generated changelog from GoReleaser is a raw commit list — replace it with proper release notes.
Follow this exact structure (see previous releases for reference — gh release view vPREVIOUS):
## What's New### Feature Name
Paragraph explaining the feature with context on why it's useful.
\`\`\`bash
# Concrete usage example
dtctl some-command --some-flag
\`\`\`
Additional detail about configuration, behavior, or edge cases. Keep it practical — show users exactly how to use the feature.
### Another Feature
...repeat for each major feature...
## Bug Fixes-**Short fix title** — one-line explanation of what was broken and what's fixed.
-**Another fix** — description.
## Documentation-**Doc title** — what was added, with a link if applicable.
## Install / Upgrade
\`\`\`bash
# Homebrew
brew update && brew upgrade dtctl
# Direct install
curl -fsSL https://raw.githubusercontent.com/dynatrace-oss/dtctl/main/install.sh | bash
# Go install
go install github.com/dynatrace-oss/dtctl@vX.Y.Z
\`\`\`
**Full Changelog**: https://github.com/dynatrace-oss/dtctl/compare/vPREVIOUS...vX.Y.Z
Release notes writing style
Each major feature gets its own ### Heading with a paragraph + code example
Code examples should be copy-pasteable and realistic
Bug fixes go in a single bulleted list under ## Bug Fixes
Always end with the ## Install / Upgrade block
Always end with the **Full Changelog** comparison link
Omit sections that don't apply (e.g., no ## Security if there are no security fixes)
Study previous releases for tone and detail level: gh release view v0.23.0, gh release view v0.22.0
Checklist
Use this to track progress:
On main branch, clean working tree, up to date with remote