## Problem
The release workflow fails at the `validate-release` job because `gh
release view` cannot find draft releases. This is because the job only
has `contents: read` permission, but GitHub requires `contents: write`
to view draft releases.
See failed run:
https://github.com/astral-sh/setup-uv/actions/runs/24528604608
## Fix
Bump `validate-release` job permissions from `contents: read` to
`contents: write`, matching the `release` job which already has this
permission.
Uses a release workflow with environment protection for publishing
releases instead of relying on user invocation.
The `release` environment can then be protected, e.g., requiring
approval from another team member. We can add a tag ruleset to prevent
tags from being created outside of the `release` environment.
I've never used Release drafter, but the workflow here differs from our
other projects in that the release process just marks the draft release
as final and adds the tag. The draft release is required, for
simplicity.