release: lace-extension@2.1.0 #10
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Publish release on merge | |
| # Companion to the lace-platform publish workflow. | |
| # | |
| # When a release/<tag> PR merges (into the default branch), flip the corresponding draft | |
| # GH Release from draft → published, retargeting the tag at the merge | |
| # commit. When one closes without merging, delete the orphan draft. | |
| # | |
| # Uses the built-in GITHUB_TOKEN — no extra secrets required. | |
| on: | |
| pull_request: | |
| types: [closed] | |
| permissions: | |
| contents: write | |
| pull-requests: read | |
| jobs: | |
| # Both jobs guard on: | |
| # - base.ref == default branch — release/<tag> PRs always target it, | |
| # so a non-default-branch PR with a release/* head is unrelated. | |
| # - head.repo.fork == false — a fork PR named release/<existing-tag> | |
| # could otherwise publish or delete the corresponding draft release. | |
| # The publish workflow only ever pushes release/* to the public repo | |
| # itself (never from a fork), so this is safe to require. | |
| flip: | |
| if: > | |
| github.event.pull_request.merged == true && | |
| github.event.pull_request.head.repo.fork == false && | |
| github.event.pull_request.base.ref == github.event.repository.default_branch && | |
| startsWith(github.event.pull_request.head.ref, 'release/') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Derive tag from branch name | |
| id: tag | |
| env: | |
| HEAD_REF: ${{ github.event.pull_request.head.ref }} | |
| run: echo "value=${HEAD_REF#release/}" >> "$GITHUB_OUTPUT" | |
| - name: Publish the draft release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAG: ${{ steps.tag.outputs.value }} | |
| MERGE_SHA: ${{ github.event.pull_request.merge_commit_sha }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| run: | | |
| set -euo pipefail | |
| # Look up the draft via the LIST endpoint (which returns | |
| # drafts) rather than `gh release view <tag>` (which goes | |
| # through /releases/tags/<tag> — that endpoint only returns | |
| # published releases since drafts don't have a real git tag). | |
| release_id=$(gh api --paginate "/repos/$GITHUB_REPOSITORY/releases" \ | |
| --jq "[.[] | select(.tag_name == \"$TAG\" and .draft == true)][0].id") | |
| if [[ -z "$release_id" || "$release_id" == "null" ]]; then | |
| echo "::error::no draft release found for tag '$TAG' — merged PR #$PR_NUMBER. Existing releases:" | |
| gh api "/repos/$GITHUB_REPOSITORY/releases" \ | |
| --jq '.[] | " tag=\(.tag_name) draft=\(.draft) published_at=\(.published_at // "(draft)")"' | |
| exit 1 | |
| fi | |
| # Retarget the draft at the merge commit and publish. The tag | |
| # is created against MERGE_SHA at publish time, so squash / | |
| # rebase / merge-commit strategies all behave correctly. | |
| gh api -X PATCH "/repos/$GITHUB_REPOSITORY/releases/$release_id" \ | |
| -F draft=false -f target_commitish="$MERGE_SHA" > /dev/null | |
| echo "Published $TAG (release id $release_id) targeting merge commit $MERGE_SHA" | |
| cleanup-orphan-draft: | |
| if: > | |
| github.event.pull_request.merged == false && | |
| github.event.pull_request.head.repo.fork == false && | |
| github.event.pull_request.base.ref == github.event.repository.default_branch && | |
| startsWith(github.event.pull_request.head.ref, 'release/') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Delete orphan draft release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| HEAD_REF: ${{ github.event.pull_request.head.ref }} | |
| run: | | |
| set -euo pipefail | |
| tag="${HEAD_REF#release/}" | |
| # Same lookup mode as the flip job — list endpoint, not | |
| # /releases/tags/ (which doesn't return drafts). | |
| release_id=$(gh api --paginate "/repos/$GITHUB_REPOSITORY/releases" \ | |
| --jq "[.[] | select(.tag_name == \"$tag\" and .draft == true)][0].id") | |
| if [[ -n "$release_id" && "$release_id" != "null" ]]; then | |
| gh api -X DELETE "/repos/$GITHUB_REPOSITORY/releases/$release_id" | |
| echo "Deleted orphan draft $tag (release id $release_id)" | |
| else | |
| echo "No orphan draft for $tag; nothing to clean up." | |
| fi |