# 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 Vociferate ships two composite actions that together cover the full release flow. Pin both to the same released tag. ### `prepare` — update files, commit, and push tag ```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 - uses: git.hrafn.xyz/aether/vociferate/prepare@v1.0.0 with: version: ${{ inputs.version }} token: ${{ secrets.GITHUB_TOKEN }} ``` 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`: ```yaml - uses: git.hrafn.xyz/aether/vociferate/prepare@v1.0.0 with: version-file: internal/myapp/version/version.go version-pattern: 'const Version = "([^"]+)"' git-add-files: changelog.md internal/myapp/version/version.go token: ${{ secrets.GITHUB_TOKEN }} ``` ### `publish` — create release with changelog notes ```yaml name: Do Release on: push: tags: - "v*.*.*" jobs: release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: git.hrafn.xyz/aether/vociferate/publish@v1.0.0 with: token: ${{ secrets.GITHUB_TOKEN }} ``` 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: ```yaml - id: publish uses: git.hrafn.xyz/aether/vociferate/publish@v1.0.0 with: token: ${{ secrets.GITHUB_TOKEN }} - 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" ```