Files
vociferate/README.md
Micheal Wilkinson 4ae6f34931
All checks were successful
Push Validation / validate (push) Successful in 54s
docs: update action and README to reflect changelog-based versioning default
- action.yml: clarify that version-file triggers version-file-based
  resolution and that omitting it causes the version to be derived from
  the changelog; note version-pattern is only required when version-file
  is set.
- README: replace stale reference to the plain-text release-version file
  as the default with an accurate description of changelog-based
  versioning as the default, directing users to set version-file and
  version-pattern only for repos with source-embedded versioning.
2026-03-20 20:12:38 +00:00

191 lines
5.2 KiB
Markdown

# vociferate
A reusable release preparation tool for Go repositories.
## Build
Build with just:
```bash
just go-build
```
Or directly with Go:
```bash
go build -o dist/vociferate ./cmd/vociferate
```
## Usage
Prepare release files:
```bash
go run ./cmd/vociferate --version v1.2.3 --date 2026-03-20 --root .
```
In the provided workflow and composite action, `version` is optional. When it is omitted, vociferate computes and uses the recommended next version automatically.
Recommend next release tag from changelog content:
```bash
go run ./cmd/vociferate --recommend --root .
```
### Flags
- `--version` semantic version to release (with or without leading `v`).
- `--date` release date in `YYYY-MM-DD` format.
- `--recommend` print recommended next tag based on `## [Unreleased]`.
- `--root` repository root directory.
- `--version-file` path to version source file relative to `--root`.
- `--version-pattern` regexp with exactly one capture group for version value.
- `--changelog` path to changelog file relative to `--root`.
Defaults:
- `version-file`: `release-version`
- `version-pattern`: `^\s*([^\r\n]+)\s*$`
- `changelog`: `changelog.md`
When no `--version-file` flag is provided, `vociferate` derives the current version from the most recent released section heading in the changelog (`## [x.y.z] - ...`). If no prior releases exist, it defaults to `0.0.0` and recommends `v1.0.0` as the first tag.
When running `--version`, the `release-version` file is created automatically if it does not exist, so new repositories do not need to pre-seed it.
Repositories that keep the version inside source code should pass explicit `--version-file` and `--version-pattern` values; in that case the version file is used directly instead of the changelog.
## Testing
```bash
just go-test
```
## Release Flow
Releases use two workflows:
- `Prepare Release` runs on demand, updates `release-version` and `changelog.md`, commits those changes back to `main`, and pushes the release tag.
- `Do Release` runs from the pushed tag, reads the matching changelog section from that tagged revision, creates or updates the release, and uploads prebuilt binaries.
This split matters because release notes must be generated from the tagged commit that already contains the promoted changelog section.
## Release Artifacts
The tag-driven `Do Release` workflow publishes prebuilt `vociferate` binaries for:
- `linux/amd64`
- `linux/arm64`
It also uploads `checksums.txt` for integrity verification.
If a release already exists for the same tag, the workflow updates its release notes and replaces matching asset filenames so reruns stay in sync.
## Reuse In Other Repositories
You can reuse vociferate in two ways.
Use the composite action directly in your prepare workflow:
```yaml
- name: Prepare release files
uses: git.hrafn.xyz/aether/vociferate@v1.0.0
with:
version-file: internal/myapp/version/version.go
version-pattern: 'const Version = "([^"]+)"'
changelog: changelog.md
```
Set `version` only when you want to override the recommended version.
Pin the composite action to a released tag. It downloads a prebuilt Linux binary from vociferate releases and caches it on the runner, so it does not require installing Go.
For repositories using changelog-based versioning (the default), omit `version-file` and `version-pattern` entirely. Only set them for repositories that embed the version inside source code.
A complete release setup should also split preparation from publication. For example:
```yaml
name: Prepare Release
on:
workflow_dispatch:
inputs:
version:
description: Optional semantic version override.
required: false
jobs:
prepare:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Prepare release files
id: prepare
uses: git.hrafn.xyz/aether/vociferate@v1.0.0
with:
version: ${{ inputs.version }}
- name: Commit and push prepared release
run: |
set -euo pipefail
tag="${{ steps.prepare.outputs.version }}"
git config user.name "gitea-actions[bot]"
git config user.email "gitea-actions[bot]@users.noreply.local"
git add changelog.md release-version
git commit -m "release: prepare ${tag}"
git tag "$tag"
git push origin HEAD
git push origin "$tag"
```
Then use a separate tag workflow to publish the release from the tagged revision:
```yaml
name: Do Release
on:
push:
tags:
- "v*.*.*"
jobs:
release:
uses: aether/vociferate/.gitea/workflows/do-release.yml@main
secrets: inherit
```
Call the reusable prepare workflow:
```yaml
name: Prepare Release
on:
workflow_dispatch:
inputs:
version:
description: Optional semantic version override.
required: false
jobs:
release:
uses: aether/vociferate/.gitea/workflows/prepare-release.yml@main
with:
version: ${{ inputs.version }}
secrets: inherit
```
And publish from tags with:
```yaml
name: Do Release
on:
push:
tags:
- "v*.*.*"
jobs:
release:
uses: aether/vociferate/.gitea/workflows/do-release.yml@main
secrets: inherit
```