From b871c0b545040a763a36c015bd6aac5a9ab64207 Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Fri, 4 Sep 2026 02:35:29 +0700 Subject: [PATCH] ci(release): create the GitHub Release, not just the tag The release workflow tagged and published but never touched the Releases page, so what shipped was invisible where people actually look for it: v1.5.0 had to be written by hand, and v1.5.1 and v1.6.0 were missing from the list entirely while being live on npm. The tags were always there - a tag and a Release are different objects, and only the tag was being created. The notes come from core's own CHANGELOG section for the version being released, so there is one source of truth and nothing to keep in sync by hand, preceded by the four package versions that shipped. An existing release is left alone rather than failing the step, so re-running the workflow after a partial failure stays safe. `contents: write` was already granted for the version commit and the tag push, so this needs no new permission. --- .github/workflows/release.yml | 38 +++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c1600fc..200e161 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -131,6 +131,44 @@ jobs: env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + # The tag alone is not what people look at. Tagging and publishing left + # the Releases page untouched, so v1.5.0 had to be written by hand, and + # v1.5.1 and v1.6.0 were missing from it entirely while being live on + # npm - the tags existed, the Releases did not. + # + # The notes are core's own CHANGELOG section for this version, so there + # is one source of truth and nothing to keep in sync by hand. An existing + # release is left alone, which makes re-running this workflow safe rather + # than a hard failure at the last step. + - name: Create the GitHub Release + if: ${{ !inputs.dry_run }} + run: | + version=$(node -p "require('./packages/core/package.json').version") + + if gh release view "v$version" >/dev/null 2>&1; then + echo "Release v$version already exists - leaving it alone." + exit 0 + fi + + { + echo 'All four packages ship at this version with npm provenance:' + echo + for pkg in core react vue angular; do + echo "- \`@dynamic-field-kit/$pkg@$(node -p "require('./packages/$pkg/package.json').version")\`" + done + echo + awk -v heading="## $version" \ + '$0 == heading { found = 1; next } /^## / { if (found) exit } found' \ + packages/core/CHANGELOG.md + } > "$RUNNER_TEMP/release-notes.md" + + gh release create "v$version" \ + --title "v$version" \ + --notes-file "$RUNNER_TEMP/release-notes.md" \ + --verify-tag \ + --latest + env: + GH_TOKEN: ${{ github.token }} - name: Dry run summary if: ${{ inputs.dry_run }}