Files
vociferate/README.md
2026-03-21 12:51:50 +00:00

247 lines
9.1 KiB
Markdown

# vociferate
[![Main Validation](https://git.hrafn.xyz/aether/vociferate/actions/workflows/push-validation.yml/badge.svg?branch=main&event=push)](https://git.hrafn.xyz/aether/vociferate/actions/runs/latest?workflow=push-validation.yml&branch=main&event=push)
[![Prepare Release](https://git.hrafn.xyz/aether/vociferate/actions/workflows/prepare-release.yml/badge.svg?event=workflow_dispatch)](https://git.hrafn.xyz/aether/vociferate/actions/runs/latest?workflow=prepare-release.yml)
[![Do Release](https://git.hrafn.xyz/aether/vociferate/actions/workflows/do-release.yml/badge.svg?event=push)](https://git.hrafn.xyz/aether/vociferate/actions/runs/latest?workflow=do-release.yml)
[![Coverage](https://s3.hrafn.xyz/aether-workflow-report-artefacts/vociferate/branch/main/coverage-badge.svg)](https://s3.hrafn.xyz/aether-workflow-report-artefacts/vociferate/branch/main/coverage.html)
`vociferate` is an `Æther` 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 composite actions covering release preparation, release publication, coverage badge publishing, and pull request decoration.
Release tags now exist; pin all action and reusable-workflow references to the same released tag (for example, `@v1.0.1`) instead of `@main`.
For agentic coding partners, see [`AGENTS.md`](AGENTS.md) for a direct integration playbook, selection matrix, and copy-paste workflow patterns.
### `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.1
with:
version: ${{ inputs.version }}
publish:
needs: prepare
uses: aether/vociferate/.gitea/workflows/do-release.yml@v1.0.1
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`:
```yaml
- uses: git.hrafn.xyz/aether/vociferate/prepare@v1.0.1
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
```yaml
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@v1.0.1
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:
```yaml
- id: publish
uses: git.hrafn.xyz/aether/vociferate/publish@v1.0.1
- 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"
```
### `coverage-badge` - publish coverage report and badge
Run your coverage tests first, then call the action to generate `coverage.html`, `coverage-badge.svg`, and `coverage-summary.json`, upload them to S3-compatible storage, and emit output URLs.
```yaml
- name: Run tests with coverage
run: go test -covermode=atomic -coverprofile=coverage.out ./...
- id: coverage
uses: git.hrafn.xyz/aether/vociferate/coverage-badge@v1.0.1
with:
artefact-bucket-name: ${{ vars.ARTEFACT_BUCKET_NAME }}
artefact-bucket-endpoint: ${{ vars.ARTEFACT_BUCKET_ENDPONT }}
- name: Print coverage links
run: |
echo "Report: ${{ steps.coverage.outputs.report-url }}"
echo "Badge: ${{ steps.coverage.outputs.badge-url }}"
```
### `decorate-pr` - annotate pull requests with coverage and changes
Decorate pull requests with coverage badges, coverage percentages, and unreleased changelog entries. The action creates a new comment or updates an existing one on each run.
```yaml
- name: Run tests with coverage
run: go test -covermode=atomic -coverprofile=coverage.out ./...
- id: coverage
uses: git.hrafn.xyz/aether/vociferate/coverage-badge@v1.0.1
with:
artefact-bucket-name: ${{ vars.ARTEFACT_BUCKET_NAME }}
artefact-bucket-endpoint: ${{ vars.ARTEFACT_BUCKET_ENDPONT }}
- name: Decorate pull request
if: github.event_name == 'pull_request'
uses: git.hrafn.xyz/aether/vociferate/decorate-pr@v1.0.1
with:
coverage-percentage: ${{ steps.coverage.outputs.total }}
badge-url: ${{ steps.coverage.outputs.badge-url }}
```
The action automatically finds existing vociferate comments by their marker and updates them instead of creating duplicates. This keeps PR timelines clean while keeping review information current.
## 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:
```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.
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
```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.
- `Prepare Release` then calls `Do Release` directly via reusable `workflow_call` with the resolved tag.
- `Do Release` reads 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/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.