7.1 KiB
vociferate
vociferate is an aether release orchestration tool written in Go for repositories that
want changelog-driven versioning, automated release preparation, and repeatable
tag publication.
It started as release preparation glue, but it now covers the full release path:
recommend the next semantic version, promote Unreleased changelog entries,
commit and tag a release, and publish release notes/assets from the tagged
revision.
Use In Other Repositories
Vociferate ships two composite actions that together cover the full release flow.
Until release tags are created, reference @main. Once tags exist again, pin both actions to the same released tag.
prepare — update files, commit, and push tag
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
- uses: git.hrafn.xyz/aether/vociferate/prepare@main
with:
version: ${{ inputs.version }}
publish:
needs: prepare
uses: aether/vociferate/.gitea/workflows/do-release.yml@main
with:
tag: ${{ needs.prepare.outputs.version }}
secrets: inherit
Downloads a prebuilt vociferate binary, runs it to update changelog.md and
release-version, then commits those changes to the default branch and pushes
the release tag. Does not require Go on the runner.
For repositories that embed the version inside source code, pass version-file
and version-pattern:
- uses: git.hrafn.xyz/aether/vociferate/prepare@main
with:
version-file: internal/myapp/version/version.go
version-pattern: 'const Version = "([^"]+)"'
git-add-files: changelog.md internal/myapp/version/version.go
prepare uses github.token internally for authenticated fetch/push operations,
so no token input is required.
publish — create release with changelog notes
name: Do Release
on:
workflow_dispatch:
inputs:
tag:
description: Semantic version to publish (for example v1.2.3)
required: true
jobs:
release:
uses: aether/vociferate/.gitea/workflows/do-release.yml@main
with:
tag: ${{ inputs.tag }}
secrets: inherit
Reads the matching section from changelog.md and creates or updates the
Gitea/GitHub release with those notes. The version input is optional — when
omitted it is derived from the current tag ref automatically.
The publish action outputs release-id so you can upload additional release
assets after it runs:
- id: publish
uses: git.hrafn.xyz/aether/vociferate/publish@main
- name: Upload my binary
run: |
curl --fail-with-body -X POST \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: application/octet-stream" \
"${{ github.api_url }}/repos/${{ github.repository }}/releases/${{ steps.publish.outputs.release-id }}/assets?name=myapp" \
--data-binary "@dist/myapp"
Why The Name
vociferate (verb): to cry out loudly or forcefully.
Long story short: vociferating into the Æther is synonymous screaming into the void.
If updating changelogs and documenting releases has ever felt like that, this tool is for you.
Build
Build with just:
just go-build
Or directly with Go:
go build -o dist/vociferate ./cmd/vociferate
Usage
Prepare release files:
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:
go run ./cmd/vociferate --recommend --root .
Flags
--versionsemantic version to release (with or without leadingv).--daterelease date inYYYY-MM-DDformat.--recommendprint recommended next tag based on## [Unreleased].--rootrepository root directory.--version-filepath to version source file relative to--root.--version-patternregexp with exactly one capture group for version value.--changelogpath to changelog file relative to--root.
Defaults:
version-file:release-versionversion-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.
During prepare, vociferate can normalize changelog heading links when it can determine the repository URL (from CI environment variables or origin git remote). Actions automatically forward ${{ vars.VOCIFERATE_REPOSITORY_URL }} to VOCIFERATE_REPOSITORY_URL, which has highest priority for changelog link generation. This value should be the server/base URL only, for example https://git.hrafn.xyz or https://git.hrafn.xyz/git, not a full repository URL.
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
just go-test
Release Flow
Releases use two workflows:
Prepare Releaseruns on demand, updatesrelease-versionandchangelog.md, commits those changes back tomain, and pushes the release tag.Prepare Releasethen callsDo Releasedirectly via reusableworkflow_callwith the resolved tag.Do Releasereads the matching changelog section from that tagged revision, creates or updates the release, and uploads prebuilt binaries.
Calling Do Release directly avoids environments where tag pushes from workflow tokens do not emit a follow-up workflow trigger event.
Release Artifacts
The tag-driven Do Release workflow publishes prebuilt vociferate binaries for:
linux/amd64linux/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.