diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..0355c99 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,58 @@ +name: Release + +on: + workflow_dispatch: + inputs: + version: + description: "Release version (e.g., 8.1.0)" + required: true + type: string + +permissions: {} + +jobs: + release: + name: Release + runs-on: ubuntu-latest + environment: release + permissions: + contents: write + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Validate version + env: + VERSION: ${{ inputs.version }} + run: | + if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then + echo "::error::Version must match MAJOR.MINOR.PATCH (e.g., 8.1.0)" + exit 1 + fi + + - name: Publish release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG: v${{ inputs.version }} + run: | + RELEASE_JSON=$(gh release view "$TAG" --json isDraft,targetCommitish 2>&1) || { + echo "::error::No release found for $TAG" + exit 1 + } + + IS_DRAFT=$(echo "$RELEASE_JSON" | jq -r '.isDraft') + TARGET=$(echo "$RELEASE_JSON" | jq -r '.targetCommitish') + + if [[ "$IS_DRAFT" != "true" ]]; then + echo "::error::Release $TAG already exists and is not a draft" + exit 1 + fi + + if [[ "$TARGET" != "$GITHUB_SHA" ]]; then + echo "::error::Draft release target ($TARGET) does not match current commit ($GITHUB_SHA)" + exit 1 + fi + + echo "Publishing draft release $TAG" + gh release edit "$TAG" --draft=false