name: Prepare Release on: workflow_dispatch: inputs: version: description: Optional semantic version override, with or without leading v. When omitted, the recommended version is used. required: false workflow_call: inputs: version: description: Optional semantic version override, with or without leading v. When omitted, the recommended version is used. required: false default: '' type: string jobs: prepare: runs-on: ubuntu-latest container: docker.io/catthehacker/ubuntu:act-latest outputs: tag: ${{ steps.prepare.outputs.version }} defaults: run: shell: bash env: SUMMARY_FILE: ${{ runner.temp }}/prepare-release-summary.md steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Go uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: false cache: true cache-dependency-path: go.sum - name: Validate formatting run: test -z "$(gofmt -l .)" - name: Module hygiene run: | set -euo pipefail go mod tidy if ! go mod verify; then echo "go mod verify failed; refreshing module cache and retrying" >&2 go clean -modcache go mod download go mod verify fi - name: Restore cached gosec binary id: cache-gosec uses: actions/cache@v4 with: path: ${{ runner.temp }}/gosec-bin key: gosec-v2.22.4-${{ runner.os }}-${{ runner.arch }} - name: Install gosec binary if: steps.cache-gosec.outputs.cache-hit != 'true' run: | set -euo pipefail mkdir -p "${RUNNER_TEMP}/gosec-bin" GOBIN="${RUNNER_TEMP}/gosec-bin" go install github.com/securego/gosec/v2/cmd/gosec@v2.22.4 - name: Run gosec security analysis run: | set -euo pipefail "${RUNNER_TEMP}/gosec-bin/gosec" ./... - name: Run govulncheck uses: golang/govulncheck-action@v1.0.4 with: go-version-file: go.mod check-latest: false go-package: ./... cache: true cache-dependency-path: go.sum - name: Run tests run: | set -euo pipefail go test ./... - name: Resolve cache token id: cache-token run: echo "value=${GITHUB_SHA}" >> "$GITHUB_OUTPUT" - name: Resolve release tag id: resolve-version run: | set -euo pipefail provided_version="$(printf '%s' "${{ inputs.version }}" | sed 's/^[[:space:]]\+//; s/[[:space:]]\+$//')" if [[ -z "$provided_version" ]]; then release_tag="$(go run ./cmd/vociferate --recommend --root .)" elif [[ "$provided_version" == v* ]]; then release_tag="$provided_version" else release_tag="v${provided_version}" fi echo "tag=${release_tag}" >> "$GITHUB_OUTPUT" - name: Update agent docs action tags run: | set -euo pipefail release_tag="${{ steps.resolve-version.outputs.tag }}" for file in README.md AGENTS.md; do sed -E -i "s/@v[0-9]+\.[0-9]+\.[0-9]+/@${release_tag}/g" "$file" done - name: Prepare and tag release id: prepare uses: ./prepare env: VOCIFERATE_CACHE_TOKEN: ${{ steps.cache-token.outputs.value }} with: version: ${{ steps.resolve-version.outputs.tag }} token: ${{ secrets.RELEASE_PAT }} git-add-files: CHANGELOG.md release-version README.md AGENTS.md - name: Summarize prepared release run: | set -euo pipefail tag="${{ steps.prepare.outputs.version }}" { echo "## Release Prepared" echo echo "- Tag pushed: ${tag}" echo "- Do Release should trigger automatically from tag push for ${tag}." } >> "$SUMMARY_FILE" - name: Summary if: ${{ always() }} run: | set -euo pipefail echo 'Summary' echo if [[ -s "$SUMMARY_FILE" ]]; then cat "$SUMMARY_FILE" else echo 'No summary generated.' fi publish: needs: prepare uses: ./.gitea/workflows/do-release.yml with: tag: ${{ needs.prepare.outputs.tag }} secrets: inherit