3 Commits

Author SHA1 Message Date
gitea-actions[bot]
b5530d0c48 release: prepare v1.0.2 2026-03-21 13:35:24 +00:00
Micheal Wilkinson
b1aaff9f3b docs: document preflight token checks
All checks were successful
Push Validation / coverage-badge (push) Successful in 35s
Push Validation / recommend-release (push) Successful in 14s
2026-03-21 13:17:39 +00:00
Micheal Wilkinson
3e03382781 chore(ci): add preflight token and API checks
All checks were successful
Push Validation / coverage-badge (push) Successful in 50s
Push Validation / recommend-release (push) Successful in 17s
2026-03-21 13:06:15 +00:00
6 changed files with 112 additions and 25 deletions

View File

@@ -52,6 +52,40 @@ jobs:
cache: true cache: true
cache-dependency-path: go.sum cache-dependency-path: go.sum
- name: Preflight release API access
env:
REQUESTED_TAG: ${{ inputs.tag }}
run: |
set -euo pipefail
if [[ -z "${RELEASE_TOKEN:-}" ]]; then
echo "No release token available. Set GITEA_TOKEN (or GITHUB_TOKEN on GitHub)." >&2
exit 1
fi
api_base="${GITHUB_API_URL:-${GITHUB_SERVER_URL%/}/api/v1}"
repo_api="${api_base}/repos/${GITHUB_REPOSITORY}"
curl --fail-with-body -sS \
-H "Authorization: token ${RELEASE_TOKEN}" \
-H "Content-Type: application/json" \
"${repo_api}" >/dev/null
curl --fail-with-body -sS \
-H "Authorization: token ${RELEASE_TOKEN}" \
-H "Content-Type: application/json" \
"${repo_api}/releases?limit=1" >/dev/null
requested_tag="$(printf '%s' "${REQUESTED_TAG:-}" | sed 's/^[[:space:]]\+//; s/[[:space:]]\+$//')"
if [[ -n "$requested_tag" ]]; then
normalized_tag="${requested_tag#v}"
tag_ref="refs/tags/v${normalized_tag}"
if ! git rev-parse --verify --quiet "$tag_ref" >/dev/null; then
echo "Requested tag ${tag_ref#refs/tags/} was not found in the checked out repository." >&2
exit 1
fi
fi
- name: Create or update release - name: Create or update release
id: publish id: publish
uses: ./publish uses: ./publish
@@ -177,7 +211,7 @@ jobs:
- name: Download released binary - name: Download released binary
env: env:
TOKEN: ${{ github.token }} TOKEN: ${{ secrets.GITHUB_TOKEN || secrets.GITEA_TOKEN }}
TAG_NAME: ${{ needs.release.outputs.tag }} TAG_NAME: ${{ needs.release.outputs.tag }}
RELEASE_VERSION: ${{ needs.release.outputs.version }} RELEASE_VERSION: ${{ needs.release.outputs.version }}
ASSET_ARCH: ${{ matrix.asset_arch }} ASSET_ARCH: ${{ matrix.asset_arch }}

View File

@@ -4,15 +4,15 @@ This guide is for agentic coding partners that need to integrate the composite a
## Source Of Truth ## Source Of Truth
Pin all action references to a released tag (for example `@v1.0.1`) and keep all vociferate references on the same tag in a workflow. Pin all action references to a released tag (for example `@v1.0.2`) and keep all vociferate references on the same tag in a workflow.
Published composite actions: Published composite actions:
- `git.hrafn.xyz/aether/vociferate@v1.0.1` (root action) - `git.hrafn.xyz/aether/vociferate@v1.0.2` (root action)
- `git.hrafn.xyz/aether/vociferate/prepare@v1.0.1` - `git.hrafn.xyz/aether/vociferate/prepare@v1.0.2`
- `git.hrafn.xyz/aether/vociferate/publish@v1.0.1` - `git.hrafn.xyz/aether/vociferate/publish@v1.0.2`
- `git.hrafn.xyz/aether/vociferate/coverage-badge@v1.0.1` - `git.hrafn.xyz/aether/vociferate/coverage-badge@v1.0.2`
- `git.hrafn.xyz/aether/vociferate/decorate-pr@v1.0.1` - `git.hrafn.xyz/aether/vociferate/decorate-pr@v1.0.2`
## Action Selection Matrix ## Action Selection Matrix
@@ -30,7 +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 valid credentials in `github.token` (or explicit token input for `publish` when needed). - Use valid credentials for release/comment API calls. On GitHub, `secrets.GITHUB_TOKEN` is used; on self-hosted Gitea, set `secrets.GITEA_TOKEN`.
- `do-release` and `decorate-pr` now 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`
@@ -93,11 +94,11 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- id: prepare - id: prepare
uses: git.hrafn.xyz/aether/vociferate/prepare@v1.0.1 uses: git.hrafn.xyz/aether/vociferate/prepare@v1.0.2
publish: publish:
needs: prepare needs: prepare
uses: aether/vociferate/.gitea/workflows/do-release.yml@v1.0.1 uses: aether/vociferate/.gitea/workflows/do-release.yml@v1.0.2
with: with:
tag: ${{ needs.prepare.outputs.version }} tag: ${{ needs.prepare.outputs.version }}
secrets: inherit secrets: inherit
@@ -114,7 +115,7 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- id: publish - id: publish
uses: git.hrafn.xyz/aether/vociferate/publish@v1.0.1 uses: git.hrafn.xyz/aether/vociferate/publish@v1.0.2
with: with:
version: v1.2.3 version: v1.2.3
``` ```
@@ -135,7 +136,7 @@ jobs:
- name: Run tests with coverage - name: Run tests with coverage
run: go test -covermode=atomic -coverprofile=coverage.out ./... run: go test -covermode=atomic -coverprofile=coverage.out ./...
- id: badge - id: badge
uses: git.hrafn.xyz/aether/vociferate/coverage-badge@v1.0.1 uses: git.hrafn.xyz/aether/vociferate/coverage-badge@v1.0.2
with: with:
artefact-bucket-name: ${{ vars.ARTEFACT_BUCKET_NAME }} artefact-bucket-name: ${{ vars.ARTEFACT_BUCKET_NAME }}
artefact-bucket-endpoint: ${{ vars.ARTEFACT_BUCKET_ENDPONT }} artefact-bucket-endpoint: ${{ vars.ARTEFACT_BUCKET_ENDPONT }}
@@ -158,12 +159,12 @@ jobs:
- name: Run tests with coverage - name: Run tests with coverage
run: go test -covermode=atomic -coverprofile=coverage.out ./... run: go test -covermode=atomic -coverprofile=coverage.out ./...
- id: badge - id: badge
uses: git.hrafn.xyz/aether/vociferate/coverage-badge@v1.0.1 uses: git.hrafn.xyz/aether/vociferate/coverage-badge@v1.0.2
with: with:
artefact-bucket-name: ${{ vars.ARTEFACT_BUCKET_NAME }} artefact-bucket-name: ${{ vars.ARTEFACT_BUCKET_NAME }}
artefact-bucket-endpoint: ${{ vars.ARTEFACT_BUCKET_ENDPONT }} artefact-bucket-endpoint: ${{ vars.ARTEFACT_BUCKET_ENDPONT }}
- name: Decorate PR - name: Decorate PR
uses: git.hrafn.xyz/aether/vociferate/decorate-pr@v1.0.1 uses: git.hrafn.xyz/aether/vociferate/decorate-pr@v1.0.2
with: with:
coverage-percentage: ${{ steps.badge.outputs.total }} coverage-percentage: ${{ steps.badge.outputs.total }}
badge-url: ${{ steps.badge.outputs.badge-url }} badge-url: ${{ steps.badge.outputs.badge-url }}
@@ -241,3 +242,4 @@ Use these rules to avoid common automation mistakes:
- Do not mix action tags in one workflow update. - Do not mix action tags in one workflow update.
- Do not assume a release workflow will run from a tag push in all environments; reusable workflow call paths are supported. - Do not assume a release workflow will run from a tag push in all environments; reusable workflow call paths are supported.
- Do not treat `VOCIFERATE_REPOSITORY_URL` as a full repository URL; it must be a base URL. - Do not treat `VOCIFERATE_REPOSITORY_URL` as a full repository URL; it must be a base URL.
- Do not bypass preflight failures with broad retry loops; fix token scope/secret wiring first.

View File

@@ -19,6 +19,20 @@ A `### Breaking` section is used in addition to Keep a Changelog's standard sect
### Fixed ### Fixed
## [1.0.2] - 2026-03-21
### Breaking
### Added
### Changed
- Documented release/PR-decoration preflight token and API-access checks, including `GITHUB_TOKEN`/`GITEA_TOKEN` behavior for self-hosted Gitea.
### Removed
### Fixed
## [1.0.1] - 2026-03-21 ## [1.0.1] - 2026-03-21
### Breaking ### Breaking
@@ -110,7 +124,8 @@ A `### Breaking` section is used in addition to Keep a Changelog's standard sect
- Project/automation rename from `releaseprep` to `vociferate` (entrypoint, package paths, outputs). - Project/automation rename from `releaseprep` to `vociferate` (entrypoint, package paths, outputs).
- README guidance focused on primary cross-repository reuse workflows. - README guidance focused on primary cross-repository reuse workflows.
[Unreleased]: https://git.hrafn.xyz/aether/vociferate/compare/v1.0.1...main [Unreleased]: https://git.hrafn.xyz/aether/vociferate/compare/v1.0.2...main
[1.0.2]: https://git.hrafn.xyz/aether/vociferate/compare/v1.0.1...v1.0.2
[1.0.1]: https://git.hrafn.xyz/aether/vociferate/compare/v1.0.0...v1.0.1 [1.0.1]: https://git.hrafn.xyz/aether/vociferate/compare/v1.0.0...v1.0.1
[1.0.0]: https://git.hrafn.xyz/aether/vociferate/compare/v0.2.0...v1.0.0 [1.0.0]: https://git.hrafn.xyz/aether/vociferate/compare/v0.2.0...v1.0.0
[0.2.0]: https://git.hrafn.xyz/aether/vociferate/compare/v0.1.0...v0.2.0 [0.2.0]: https://git.hrafn.xyz/aether/vociferate/compare/v0.1.0...v0.2.0

View File

@@ -17,7 +17,7 @@ revision.
## Use In Other Repositories ## Use In Other Repositories
Vociferate ships composite actions covering release preparation, release publication, coverage badge publishing, and pull request decoration. 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`. Release tags now exist; pin all action and reusable-workflow references to the same released tag (for example, `@v1.0.2`) instead of `@main`.
For agentic coding partners, see [`AGENTS.md`](AGENTS.md) for a direct integration playbook, selection matrix, and copy-paste workflow patterns. For agentic coding partners, see [`AGENTS.md`](AGENTS.md) for a direct integration playbook, selection matrix, and copy-paste workflow patterns.
@@ -41,13 +41,13 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: git.hrafn.xyz/aether/vociferate/prepare@v1.0.1 - uses: git.hrafn.xyz/aether/vociferate/prepare@v1.0.2
with: with:
version: ${{ inputs.version }} version: ${{ inputs.version }}
publish: publish:
needs: prepare needs: prepare
uses: aether/vociferate/.gitea/workflows/do-release.yml@v1.0.1 uses: aether/vociferate/.gitea/workflows/do-release.yml@v1.0.2
with: with:
tag: ${{ needs.prepare.outputs.version }} tag: ${{ needs.prepare.outputs.version }}
secrets: inherit secrets: inherit
@@ -61,7 +61,7 @@ For repositories that embed the version inside source code, pass `version-file`
and `version-pattern`: and `version-pattern`:
```yaml ```yaml
- uses: git.hrafn.xyz/aether/vociferate/prepare@v1.0.1 - uses: git.hrafn.xyz/aether/vociferate/prepare@v1.0.2
with: with:
version-file: internal/myapp/version/version.go version-file: internal/myapp/version/version.go
version-pattern: 'const Version = "([^"]+)"' version-pattern: 'const Version = "([^"]+)"'
@@ -85,7 +85,7 @@ on:
jobs: jobs:
release: release:
uses: aether/vociferate/.gitea/workflows/do-release.yml@v1.0.1 uses: aether/vociferate/.gitea/workflows/do-release.yml@v1.0.2
with: with:
tag: ${{ inputs.tag }} tag: ${{ inputs.tag }}
secrets: inherit secrets: inherit
@@ -95,12 +95,17 @@ 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
fail fast when the release token is missing or lacks API access. On
self-hosted Gitea, set `secrets.GITEA_TOKEN`; on GitHub, `secrets.GITHUB_TOKEN`
is used automatically.
The `publish` action outputs `release-id` so you can upload additional release The `publish` action outputs `release-id` so you can upload additional release
assets after it runs: assets after it runs:
```yaml ```yaml
- id: publish - id: publish
uses: git.hrafn.xyz/aether/vociferate/publish@v1.0.1 uses: git.hrafn.xyz/aether/vociferate/publish@v1.0.2
- name: Upload my binary - name: Upload my binary
run: | run: |
@@ -120,7 +125,7 @@ Run your coverage tests first, then call the action to generate `coverage.html`,
run: go test -covermode=atomic -coverprofile=coverage.out ./... run: go test -covermode=atomic -coverprofile=coverage.out ./...
- id: coverage - id: coverage
uses: git.hrafn.xyz/aether/vociferate/coverage-badge@v1.0.1 uses: git.hrafn.xyz/aether/vociferate/coverage-badge@v1.0.2
with: with:
artefact-bucket-name: ${{ vars.ARTEFACT_BUCKET_NAME }} artefact-bucket-name: ${{ vars.ARTEFACT_BUCKET_NAME }}
artefact-bucket-endpoint: ${{ vars.ARTEFACT_BUCKET_ENDPONT }} artefact-bucket-endpoint: ${{ vars.ARTEFACT_BUCKET_ENDPONT }}
@@ -135,19 +140,22 @@ Run your coverage tests first, then call the action to generate `coverage.html`,
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. 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.
`decorate-pr` also runs a preflight comment API check so workflows fail early
with a clear message when token permissions are insufficient.
```yaml ```yaml
- name: Run tests with coverage - name: Run tests with coverage
run: go test -covermode=atomic -coverprofile=coverage.out ./... run: go test -covermode=atomic -coverprofile=coverage.out ./...
- id: coverage - id: coverage
uses: git.hrafn.xyz/aether/vociferate/coverage-badge@v1.0.1 uses: git.hrafn.xyz/aether/vociferate/coverage-badge@v1.0.2
with: with:
artefact-bucket-name: ${{ vars.ARTEFACT_BUCKET_NAME }} artefact-bucket-name: ${{ vars.ARTEFACT_BUCKET_NAME }}
artefact-bucket-endpoint: ${{ vars.ARTEFACT_BUCKET_ENDPONT }} artefact-bucket-endpoint: ${{ vars.ARTEFACT_BUCKET_ENDPONT }}
- name: Decorate pull request - name: Decorate pull request
if: github.event_name == 'pull_request' if: github.event_name == 'pull_request'
uses: git.hrafn.xyz/aether/vociferate/decorate-pr@v1.0.1 uses: git.hrafn.xyz/aether/vociferate/decorate-pr@v1.0.2
with: with:
coverage-percentage: ${{ steps.coverage.outputs.total }} coverage-percentage: ${{ steps.coverage.outputs.total }}
badge-url: ${{ steps.coverage.outputs.badge-url }} badge-url: ${{ steps.coverage.outputs.badge-url }}

View File

@@ -64,6 +64,34 @@ runs:
printf 'pr_number=%s\n' "$PR_NUMBER" >> "$GITHUB_OUTPUT" printf 'pr_number=%s\n' "$PR_NUMBER" >> "$GITHUB_OUTPUT"
- name: Preflight comment API access
id: preflight
shell: bash
env:
AUTH_TOKEN: ${{ inputs.token != '' && inputs.token || github.token }}
PR_NUMBER: ${{ steps.validate.outputs.pr_number }}
SERVER_URL: ${{ github.server_url }}
REPOSITORY: ${{ github.repository }}
run: |
set -euo pipefail
if [[ -z "$AUTH_TOKEN" ]]; then
echo "No token available for PR comment API calls. Set input token or provide workflow token." >&2
exit 1
fi
api_url="${SERVER_URL}/api/v1"
if [[ "$SERVER_URL" == *"github.com"* ]]; then
api_url="https://api.github.com"
fi
comments_url="${api_url}/repos/${REPOSITORY}/issues/${PR_NUMBER}/comments"
curl --fail-with-body -sS \
-H "Authorization: Bearer ${AUTH_TOKEN}" \
-H "Content-Type: application/json" \
"$comments_url" >/dev/null
- name: Extract changelog unreleased entries - name: Extract changelog unreleased entries
id: extract-changelog id: extract-changelog
shell: bash shell: bash

View File

@@ -1 +1 @@
1.0.1 1.0.2