From c46c3032366cc7b3e2352483bafd9b4c53c3dc12 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Mon, 11 May 2026 10:07:39 -0700 Subject: [PATCH] release.yaml: authenticate the version-resolution API calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The /releases/latest and /releases/tags/X reads were unauthenticated. On private repos Forgejo returns 404 to unauth'd callers, so the workflow silently fell back to v0.0.0 as the "previous version" and let a BUMP_PATCH on top of v1.x.y produce v0.0.1. The duplicate-tag guard had the same blind spot — it could not detect existing releases at all. Both reads now send the Authorization header and treat any non-200 / non-404 response as a hard failure instead of swallowing it. --- .forgejo/workflows/release.yaml | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/.forgejo/workflows/release.yaml b/.forgejo/workflows/release.yaml index f3df47b..9f0940e 100644 --- a/.forgejo/workflows/release.yaml +++ b/.forgejo/workflows/release.yaml @@ -41,19 +41,33 @@ jobs: steps: - name: Resolve version id: version + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | + set -euo pipefail VERSION_TYPE="${{ inputs.version_type }}" SPECIFIC_VERSION="${{ inputs.specific_version }}" FORGE_URL="${{ github.server_url }}/api/v1/repos/${{ github.repository }}" echo "Fetching latest release..." - LATEST=$(curl -s "${FORGE_URL}/releases/latest" | jq -r '.tag_name // empty' || true) + # Private repos return 404 to unauthenticated callers, so the auth + # header is required even though "latest release" reads like public + # info. Without it the curl 404s, falls back to v0.0.0, and a + # BUMP_PATCH on top of v1.x.y silently produces v0.0.1. + LATEST_STATUS=$(curl -s -o /tmp/latest.json -w "%{http_code}" \ + -H "Authorization: token $GITHUB_TOKEN" \ + "${FORGE_URL}/releases/latest") - if [ -z "$LATEST" ]; then + if [ "$LATEST_STATUS" = "200" ]; then + LATEST=$(jq -r '.tag_name' < /tmp/latest.json) + echo "Latest release: $LATEST" + elif [ "$LATEST_STATUS" = "404" ]; then LATEST="v0.0.0" echo "No previous releases found, using base version: $LATEST" else - echo "Latest release: $LATEST" + echo "Error: unexpected HTTP $LATEST_STATUS fetching latest release" + cat /tmp/latest.json + exit 1 fi CURRENT="${LATEST#v}" @@ -92,9 +106,18 @@ jobs: ;; esac - if curl -sf "${FORGE_URL}/releases/tags/$VERSION" > /dev/null 2>&1; then + # Same auth requirement: on a private repo, an unauthenticated + # curl always 404s here, which would silently disable the + # "release already exists" guard. + EXISTS_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \ + -H "Authorization: token $GITHUB_TOKEN" \ + "${FORGE_URL}/releases/tags/$VERSION") + if [ "$EXISTS_STATUS" = "200" ]; then echo "Error: Release $VERSION already exists" exit 1 + elif [ "$EXISTS_STATUS" != "404" ]; then + echo "Error: unexpected HTTP $EXISTS_STATUS checking for existing release" + exit 1 fi echo "version=$VERSION" >> "$GITHUB_OUTPUT"