diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9effe18..0bb8d9d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,12 +1,12 @@ name: Release on: - release: - types: - - published + push: + tags: + - "v*" permissions: - contents: read + contents: write id-token: write concurrency: @@ -27,5 +27,60 @@ jobs: registry-url: https://registry.npmjs.org - run: pnpm install --frozen-lockfile - run: pnpm gate - - run: pnpm publish --access public --provenance --no-git-checks + - name: Select release metadata + id: release + run: | + version="${GITHUB_REF_NAME#v}" + package_version="$(node -p "require('./packages/roller/package.json').version")" + if [[ "$version" != "$package_version" ]]; then + echo "Tag $GITHUB_REF_NAME does not match package version $package_version" >&2 + exit 1 + fi + dist_tag="${version#*-}" + if [[ "$dist_tag" == "$version" ]]; then + dist_tag=latest + prerelease=false + else + dist_tag="${dist_tag%%.*}" + prerelease=true + fi + { + printf 'version=%s\n' "$version" + printf 'dist_tag=%s\n' "$dist_tag" + printf 'prerelease=%s\n' "$prerelease" + } >> "$GITHUB_OUTPUT" + - name: Create GitHub release + env: + GH_TOKEN: ${{ github.token }} + RELEASE_VERSION: ${{ steps.release.outputs.version }} + PRERELEASE: ${{ steps.release.outputs.prerelease }} + run: | + if gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then + echo "GitHub release $GITHUB_REF_NAME already exists" + exit 0 + fi + notes="$(awk -v prefix="$RELEASE_VERSION:" ' + index($0, prefix) == 1 { + found = 1 + sub(/^[^:]+:[[:space:]]*/, "") + print + next + } + found && /^[0-9]+\.[0-9]+\.[0-9]+(-[^:]*)?:/ { exit } + found { print } + ' CHANGELOG.md)" + args=(release create "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" --verify-tag --title "$GITHUB_REF_NAME") + if [[ "$PRERELEASE" == true ]]; then + args+=(--prerelease) + fi + if [[ -n "$notes" ]]; then + printf '%s\n' "$notes" > "$RUNNER_TEMP/release-notes.md" + args+=(--notes-file "$RUNNER_TEMP/release-notes.md") + else + args+=(--generate-notes) + fi + gh "${args[@]}" + - run: pnpm publish --access public --provenance --no-git-checks --tag "$NPM_DIST_TAG" + env: + NPM_DIST_TAG: ${{ steps.release.outputs.dist_tag }} working-directory: packages/roller diff --git a/README.md b/README.md index 14fa1b1..79c32a6 100644 --- a/README.md +++ b/README.md @@ -84,5 +84,5 @@ installable previews through pkg.pr.new once its GitHub App is installed. Run `pnpm gate:docker` to execute the same containerized gate used by CI. To release, update the version and changelog on `develop`, merge it to `main`, -tag the release as `vX.Y.Z`, and publish a matching GitHub release. The release -workflow runs the full gate before publishing to npm with trusted publishing. +then push the matching `vX.Y.Z` tag. The release workflow runs the full gate, +creates the GitHub release, and publishes to npm with trusted publishing.