refactor(release): rename workflows and align update-release path
All checks were successful
Push Validation / coverage-badge (push) Successful in 1m30s
Push Validation / recommend-release (push) Successful in 23s

Rename the reusable workflows to release.yml and update-release.yml,
add UPX compression for release binaries, and sync the standalone
update-release workflow with the active release pipeline fixes.
Update README, AGENTS, compliance notes, and changelog references to
match the new workflow names and usage patterns.
This commit is contained in:
Micheal Wilkinson
2026-03-21 20:25:03 +00:00
parent f82dace4b2
commit a3e2b4e44e
6 changed files with 111 additions and 71 deletions

View File

@@ -1,4 +1,4 @@
name: Prepare Release name: Release
on: on:
workflow_dispatch: workflow_dispatch:
@@ -24,7 +24,7 @@ jobs:
run: run:
shell: bash shell: bash
env: env:
SUMMARY_FILE: ${{ runner.temp }}/prepare-release-summary.md SUMMARY_FILE: ${{ runner.temp }}/release-prepare-summary.md
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -39,6 +39,12 @@ jobs:
cache: true cache: true
cache-dependency-path: go.sum cache-dependency-path: go.sum
- name: Install release build tools
run: |
set -euo pipefail
apt-get update
apt-get install -y upx-ucl || apt-get install -y upx
- name: Validate formatting - name: Validate formatting
run: test -z "$(gofmt -l .)" run: test -z "$(gofmt -l .)"
@@ -242,6 +248,15 @@ jobs:
run: | run: |
set -euo pipefail set -euo pipefail
if command -v upx >/dev/null 2>&1; then
upx_cmd=upx
elif command -v upx-ucl >/dev/null 2>&1; then
upx_cmd=upx-ucl
else
echo "UPX is not available on PATH after installation." >&2
exit 1
fi
mkdir -p dist mkdir -p dist
for target in linux/amd64 linux/arm64; do for target in linux/amd64 linux/arm64; do
@@ -250,6 +265,7 @@ jobs:
bin="vociferate_${RELEASE_VERSION}_${os}_${arch}" bin="vociferate_${RELEASE_VERSION}_${os}_${arch}"
GOOS="$os" GOARCH="$arch" go build -trimpath -ldflags="-s -w" -o "dist/${bin}" ./cmd/vociferate GOOS="$os" GOARCH="$arch" go build -trimpath -ldflags="-s -w" -o "dist/${bin}" ./cmd/vociferate
"${upx_cmd}" --best --lzma "dist/${bin}"
done done
( (
@@ -329,6 +345,7 @@ jobs:
echo "- Tag: ${TAG_NAME}" echo "- Tag: ${TAG_NAME}"
echo "- Release notes sourced from changelog entry ${RELEASE_VERSION}." echo "- Release notes sourced from changelog entry ${RELEASE_VERSION}."
echo "- Published assets: vociferate_${RELEASE_VERSION}_linux_amd64, vociferate_${RELEASE_VERSION}_linux_arm64, checksums.txt" echo "- Published assets: vociferate_${RELEASE_VERSION}_linux_amd64, vociferate_${RELEASE_VERSION}_linux_arm64, checksums.txt"
echo "- Release binaries were compressed with UPX before upload."
} >> "$SUMMARY_FILE" } >> "$SUMMARY_FILE"
else else
{ {

View File

@@ -1,4 +1,4 @@
name: Do Release name: Update Release
on: on:
push: push:
@@ -29,7 +29,7 @@ jobs:
shell: bash shell: bash
env: env:
RELEASE_TOKEN: ${{ secrets.RELEASE_PAT }} RELEASE_TOKEN: ${{ secrets.RELEASE_PAT }}
SUMMARY_FILE: ${{ runner.temp }}/do-release-summary.md SUMMARY_FILE: ${{ runner.temp }}/update-release-summary.md
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -59,7 +59,6 @@ jobs:
id: resolve-version id: resolve-version
env: env:
INPUT_TAG: ${{ inputs.tag }} INPUT_TAG: ${{ inputs.tag }}
CALLER_TAG: ${{ needs.prepare.outputs.tag }}
DETECTED_TAG: ${{ steps.detect-tag.outputs.detected_tag }} DETECTED_TAG: ${{ steps.detect-tag.outputs.detected_tag }}
run: | run: |
set -euo pipefail set -euo pipefail
@@ -79,17 +78,11 @@ jobs:
} }
input_tag="$(normalize_candidate "${INPUT_TAG}")" input_tag="$(normalize_candidate "${INPUT_TAG}")"
caller_tag="$(normalize_candidate "${CALLER_TAG}")"
detected_tag="$(normalize_candidate "${DETECTED_TAG}")" detected_tag="$(normalize_candidate "${DETECTED_TAG}")"
# Try explicit input first. # Try explicit input first.
requested_tag="$input_tag" requested_tag="$input_tag"
# Fall back to caller workflow output when workflow_call input forwarding is unreliable.
if [[ -z "$requested_tag" && -n "$caller_tag" ]]; then
requested_tag="$caller_tag"
fi
# Fall back to detected tag if neither input nor caller tag is available. # Fall back to detected tag if neither input nor caller tag is available.
if [[ -z "$requested_tag" && -n "$detected_tag" ]]; then if [[ -z "$requested_tag" && -n "$detected_tag" ]]; then
requested_tag="$detected_tag" requested_tag="$detected_tag"
@@ -107,7 +100,6 @@ jobs:
else else
echo "Error: Could not resolve release version" >&2 echo "Error: Could not resolve release version" >&2
echo " - inputs.tag(raw): '$INPUT_TAG'" >&2 echo " - inputs.tag(raw): '$INPUT_TAG'" >&2
echo " - needs.prepare.outputs.tag(raw): '$CALLER_TAG'" >&2
echo " - detected_tag(raw): '${DETECTED_TAG}'" >&2 echo " - detected_tag(raw): '${DETECTED_TAG}'" >&2
echo " - GITHUB_REF: '$GITHUB_REF'" >&2 echo " - GITHUB_REF: '$GITHUB_REF'" >&2
exit 1 exit 1
@@ -130,6 +122,12 @@ jobs:
cache: true cache: true
cache-dependency-path: go.sum cache-dependency-path: go.sum
- name: Install release build tools
run: |
set -euo pipefail
apt-get update
apt-get install -y upx-ucl || apt-get install -y upx
- name: Preflight release API access - name: Preflight release API access
env: env:
TAG_NAME: ${{ steps.resolve-version.outputs.tag }} TAG_NAME: ${{ steps.resolve-version.outputs.tag }}
@@ -172,6 +170,15 @@ jobs:
run: | run: |
set -euo pipefail set -euo pipefail
if command -v upx >/dev/null 2>&1; then
upx_cmd=upx
elif command -v upx-ucl >/dev/null 2>&1; then
upx_cmd=upx-ucl
else
echo "UPX is not available on PATH after installation." >&2
exit 1
fi
mkdir -p dist mkdir -p dist
for target in linux/amd64 linux/arm64; do for target in linux/amd64 linux/arm64; do
@@ -180,6 +187,7 @@ jobs:
bin="vociferate_${RELEASE_VERSION}_${os}_${arch}" bin="vociferate_${RELEASE_VERSION}_${os}_${arch}"
GOOS="$os" GOARCH="$arch" go build -trimpath -ldflags="-s -w" -o "dist/${bin}" ./cmd/vociferate GOOS="$os" GOARCH="$arch" go build -trimpath -ldflags="-s -w" -o "dist/${bin}" ./cmd/vociferate
"${upx_cmd}" --best --lzma "dist/${bin}"
done done
( (
@@ -194,7 +202,27 @@ jobs:
run: | run: |
set -euo pipefail set -euo pipefail
release_api="${GITHUB_API_URL:-${GITHUB_SERVER_URL%/}/api/v1}/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets" raw_release_id="$(printf '%s' "${RELEASE_ID:-}" | sed 's/^[[:space:]]\+//; s/[[:space:]]\+$//')"
if [[ "$raw_release_id" =~ ^%\!t\(string=(.*)\)$ ]]; then
raw_release_id="${BASH_REMATCH[1]}"
fi
release_id="$(printf '%s' "$raw_release_id" | sed 's/^[[:space:]]\+//; s/[[:space:]]\+$//')"
if ! [[ "$release_id" =~ ^[0-9]+$ ]]; then
echo "Invalid release id from publish step: '${RELEASE_ID}'" >&2
exit 1
fi
release_detail_api="${GITHUB_API_URL:-${GITHUB_SERVER_URL%/}/api/v1}/repos/${GITHUB_REPOSITORY}/releases/${release_id}"
if ! curl --fail-with-body -sS \
-H "Authorization: token ${RELEASE_TOKEN}" \
-H "Content-Type: application/json" \
"$release_detail_api" >/dev/null; then
echo "Resolved release endpoint is not accessible: ${release_detail_api}" >&2
exit 1
fi
release_api="${GITHUB_API_URL:-${GITHUB_SERVER_URL%/}/api/v1}/repos/${GITHUB_REPOSITORY}/releases/${release_id}/assets"
for asset in dist/*; do for asset in dist/*; do
name="$(basename "$asset")" name="$(basename "$asset")"
@@ -223,25 +251,32 @@ jobs:
--data-binary "@${asset}" --data-binary "@${asset}"
done done
- name: Summarize published release - name: Summary
if: ${{ always() }}
env: env:
TAG_NAME: ${{ steps.publish.outputs.tag }} TAG_NAME: ${{ steps.publish.outputs.tag }}
RELEASE_VERSION: ${{ steps.publish.outputs.version }} RELEASE_VERSION: ${{ steps.publish.outputs.version }}
PUBLISH_OUTCOME: ${{ steps.publish.outcome }}
run: | run: |
set -euo pipefail set -euo pipefail
if [[ "${PUBLISH_OUTCOME}" == "success" ]]; then
{ {
echo "## Release Published" echo "## Release Published"
echo echo
echo "- Tag: ${TAG_NAME}" echo "- Tag: ${TAG_NAME}"
echo "- Release notes sourced from changelog entry ${RELEASE_VERSION}." echo "- Release notes sourced from changelog entry ${RELEASE_VERSION}."
echo "- Published assets: vociferate_${RELEASE_VERSION}_linux_amd64, vociferate_${RELEASE_VERSION}_linux_arm64, checksums.txt" echo "- Published assets: vociferate_${RELEASE_VERSION}_linux_amd64, vociferate_${RELEASE_VERSION}_linux_arm64, checksums.txt"
echo "- Release binaries were compressed with UPX before upload."
} >> "$SUMMARY_FILE" } >> "$SUMMARY_FILE"
else
- name: Summary {
if: ${{ always() }} echo "## Release Failed"
run: | echo
set -euo pipefail echo "- Tag: ${TAG_NAME:-unknown}"
echo "- Create or update release step did not complete successfully."
} >> "$SUMMARY_FILE"
fi
echo 'Summary' echo 'Summary'
echo echo
@@ -268,7 +303,7 @@ jobs:
run: run:
shell: bash shell: bash
env: env:
SUMMARY_FILE: ${{ runner.temp }}/do-release-validate-summary.md SUMMARY_FILE: ${{ runner.temp }}/update-release-validate-summary.md
steps: steps:
- name: Checkout tagged revision - name: Checkout tagged revision
uses: actions/checkout@v4 uses: actions/checkout@v4

View File

@@ -30,8 +30,8 @@ Apply these checks before invoking actions:
- Checkout repository first. - Checkout repository first.
- For prepare/publish flows that depend on tags/history, use full history checkout (`fetch-depth: 0`). - For prepare/publish flows that depend on tags/history, use full history checkout (`fetch-depth: 0`).
- Use `secrets.RELEASE_PAT` for release/tag/update operations (prepare/publish/do-release) so tag pushes trigger downstream workflows reliably. - Use `secrets.RELEASE_PAT` for release/tag/update operations (`prepare`, `publish`, `release`, `update-release`) so authenticated release changes can be pushed and published reliably.
- `do-release` and `decorate-pr` now run preflight API checks and fail fast when token credentials are missing or insufficient. - `release`, `update-release`, and `decorate-pr` run preflight API checks and fail fast when token credentials are missing or insufficient.
- Set required vars/secrets for coverage uploads: - Set required vars/secrets for coverage uploads:
- `vars.ARTEFACT_BUCKET_NAME` - `vars.ARTEFACT_BUCKET_NAME`
- `vars.ARTEFACT_BUCKET_ENDPONT` - `vars.ARTEFACT_BUCKET_ENDPONT`
@@ -83,41 +83,26 @@ Minimal template:
## Minimal Integration Patterns ## Minimal Integration Patterns
### 1. Prepare Then Publish ### 1. Full Release Workflow
```yaml
jobs:
prepare:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- id: prepare
uses: https://git.hrafn.xyz/aether/vociferate/prepare@v1.1.0
publish:
needs: prepare
uses: https://git.hrafn.xyz/aether/vociferate/.gitea/workflows/do-release.yml@v1.1.0
with:
tag: ${{ needs.prepare.outputs.version }}
secrets: inherit
```
### 2. Publish Existing Tag
```yaml ```yaml
jobs: jobs:
release: release:
runs-on: ubuntu-latest uses: https://git.hrafn.xyz/aether/vociferate/.gitea/workflows/release.yml@v1.1.0
steps:
- uses: actions/checkout@v4
with: with:
fetch-depth: 0 version: ${{ inputs.version }}
- id: publish secrets: inherit
uses: https://git.hrafn.xyz/aether/vociferate/publish@v1.1.0 ```
### 2. Update Existing Release Tag
```yaml
jobs:
release:
uses: https://git.hrafn.xyz/aether/vociferate/.gitea/workflows/update-release.yml@v1.1.0
with: with:
version: v1.2.3 tag: v1.2.3
secrets: inherit
``` ```
### 3. Coverage Badge Publication ### 3. Coverage Badge Publication

View File

@@ -43,6 +43,8 @@ A `### Breaking` section is used in addition to Keep a Changelog's standard sect
- Composite actions now share a centralized `run-vociferate` orchestration flow, with binary-versus-source execution delegated through shared composite actions and single-use runtime/download logic folded back into `run-vociferate.binary`. - Composite actions now share a centralized `run-vociferate` orchestration flow, with binary-versus-source execution delegated through shared composite actions and single-use runtime/download logic folded back into `run-vociferate.binary`.
- `run-vociferate` now contains both binary and source execution flows directly in a single action implementation, removing nested local action wrappers for better runner compatibility. - `run-vociferate` now contains both binary and source execution flows directly in a single action implementation, removing nested local action wrappers for better runner compatibility.
- Release automation now requires `secrets.RELEASE_PAT` for prepare/publish/do-release operations instead of defaulting to `GITHUB_TOKEN`/`GITEA_TOKEN`. - Release automation now requires `secrets.RELEASE_PAT` for prepare/publish/do-release operations instead of defaulting to `GITHUB_TOKEN`/`GITEA_TOKEN`.
- Renamed the reusable Gitea workflows to `release.yml` and `update-release.yml`, and inlined release publication into the main `release` workflow for clearer per-step job output.
- Release binary builds now compress published linux artifacts with UPX before checksum generation and upload.
### Removed ### Removed
@@ -62,6 +64,7 @@ A `### Breaking` section is used in addition to Keep a Changelog's standard sect
- Fixed nested local composite-action references to use repository-local `./run-vociferate` paths so strict runners do not misparse parent-directory (`../`) action references as malformed remote coordinates. - Fixed nested local composite-action references to use repository-local `./run-vociferate` paths so strict runners do not misparse parent-directory (`../`) action references as malformed remote coordinates.
- Consolidated `run-vociferate` binary and source execution flows directly into the main `run-vociferate` action to avoid nested local-action path resolution issues on strict runners. - Consolidated `run-vociferate` binary and source execution flows directly into the main `run-vociferate` action to avoid nested local-action path resolution issues on strict runners.
- Hardened workflow module hygiene by retrying `go mod verify` after a module-cache refresh (`go clean -modcache` + `go mod download`) when runners report modified cached dependency directories. - Hardened workflow module hygiene by retrying `go mod verify` after a module-cache refresh (`go clean -modcache` + `go mod download`) when runners report modified cached dependency directories.
- Synced `update-release.yml` with the active release pipeline fixes for Teacup-wrapped outputs, release-id normalization, upload endpoint validation, and accurate success or failure summaries.
## [1.0.2] - 2026-03-21 ## [1.0.2] - 2026-03-21

View File

@@ -154,8 +154,8 @@ if err != nil {
**Workflows analyzed:** **Workflows analyzed:**
- [push-validation.yml](.gitea/workflows/push-validation.yml) - [push-validation.yml](.gitea/workflows/push-validation.yml)
- [prepare-release.yml](.gitea/workflows/prepare-release.yml) - [release.yml](.gitea/workflows/release.yml)
- [do-release.yml](.gitea/workflows/do-release.yml) - [update-release.yml](.gitea/workflows/update-release.yml)
#### What's Implemented #### What's Implemented
@@ -171,7 +171,7 @@ if err != nil {
- ✅ Coverage badge publication - ✅ Coverage badge publication
- ✅ Release tag recommendation on `main` branch - ✅ Release tag recommendation on `main` branch
**prepare-release.yml:** **release.yml:**
- ✅ Go setup and caching - ✅ Go setup and caching
- ✅ Tests run before release preparation - ✅ Tests run before release preparation
@@ -361,7 +361,7 @@ validate
**Effort Invested:** **Effort Invested:**
- CI/CD improvements: workflow hardening in `push-validation.yml` and `prepare-release.yml` - CI/CD improvements: workflow hardening in `push-validation.yml` and `release.yml`
- Code organization: injected service boundaries for filesystem, environment, and git access - Code organization: injected service boundaries for filesystem, environment, and git access
- Local automation: `justfile` validation parity for format, modules, tests, and security - Local automation: `justfile` validation parity for format, modules, tests, and security
- **Primary commits:** 7cb7b05, 383aad4, 5c903c9 - **Primary commits:** 7cb7b05, 383aad4, 5c903c9

View File

@@ -1,8 +1,8 @@
# vociferate # 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) [![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) [![Release](https://git.hrafn.xyz/aether/vociferate/actions/workflows/release.yml/badge.svg?event=workflow_dispatch)](https://git.hrafn.xyz/aether/vociferate/actions/runs/latest?workflow=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) [![Update Release](https://git.hrafn.xyz/aether/vociferate/actions/workflows/update-release.yml/badge.svg?event=workflow_dispatch)](https://git.hrafn.xyz/aether/vociferate/actions/runs/latest?workflow=update-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) [![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 `vociferate` is an `Æther` release orchestration tool written in Go for repositories that
@@ -24,7 +24,7 @@ For agentic coding partners, see [`AGENTS.md`](AGENTS.md) for a direct integrati
### `prepare` — update files, commit, and push tag ### `prepare` — update files, commit, and push tag
```yaml ```yaml
name: Prepare Release name: Release
on: on:
workflow_dispatch: workflow_dispatch:
@@ -47,7 +47,7 @@ jobs:
publish: publish:
needs: prepare needs: prepare
uses: https://git.hrafn.xyz/aether/vociferate/.gitea/workflows/do-release.yml@v1.1.0 uses: https://git.hrafn.xyz/aether/vociferate/.gitea/workflows/update-release.yml@v1.1.0
with: with:
tag: ${{ needs.prepare.outputs.version }} tag: ${{ needs.prepare.outputs.version }}
secrets: inherit secrets: inherit
@@ -75,7 +75,7 @@ Pass `token: ${{ secrets.RELEASE_PAT }}` when invoking the action.
### `publish` — create release with changelog notes ### `publish` — create release with changelog notes
```yaml ```yaml
name: Do Release name: Update Release
on: on:
workflow_dispatch: workflow_dispatch:
@@ -86,7 +86,7 @@ on:
jobs: jobs:
release: release:
uses: https://git.hrafn.xyz/aether/vociferate/.gitea/workflows/do-release.yml@v1.1.0 uses: https://git.hrafn.xyz/aether/vociferate/.gitea/workflows/update-release.yml@v1.1.0
with: with:
tag: ${{ inputs.tag }} tag: ${{ inputs.tag }}
secrets: inherit secrets: inherit
@@ -96,7 +96,7 @@ Reads the matching section from `CHANGELOG.md` and creates or updates the
Gitea/GitHub release with those notes. The `version` input is optional — when Gitea/GitHub release with those notes. The `version` input is optional — when
omitted it is derived from the current tag ref automatically. omitted it is derived from the current tag ref automatically.
The reusable `Do Release` workflow now runs preflight checks before publish to The reusable `Update Release` workflow now runs preflight checks before publish to
fail fast when the release token is missing or lacks API access. Set fail fast when the release token is missing or lacks API access. Set
`secrets.RELEASE_PAT` and use it for prepare/publish release operations. `secrets.RELEASE_PAT` and use it for prepare/publish release operations.