Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions .github/workflows/tag-after-merge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: Tag and Release After Merge

permissions:
contents: write

on:
push:
branches:
- main

jobs:
create-tag-and-release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
fetch-depth: 0

Comment on lines +16 to +19
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ› οΈ Refactor suggestion

Fix checkout action version and fetch tags to enable tag discovery.

actions/checkout@v5 is not a valid published version today, and tags are not fetched by default. Without tags, git describe --tags may return nothing even when tags exist, and the job will misclassify or skip releases.

Apply this diff:

-      - name: Checkout code
-        uses: actions/checkout@v5
-        with:
-          fetch-depth: 0
+      - name: Checkout code
+        uses: actions/checkout@v4
+        with:
+          fetch-depth: 0
+          fetch-tags: true
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
πŸ€– Prompt for AI Agents
In .github/workflows/tag-after-merge.yml around lines 16 to 19, the checkout
step uses an invalid action version and does not enable fetching tags; update
the uses to a published version (e.g., actions/checkout@v4) and add fetch-tags:
true alongside fetch-depth: 0 under the with block so the job fetches tags and
git describe --tags can discover them.

- name: Get new version from package.json
run: |
VERSION=$(jq -r .version package.json)
echo "version=$VERSION" >> $GITHUB_ENV

- name: Get last tag (if exists)
run: |
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
LAST_TAG_STRIPPED=${LAST_TAG#v}
echo "last_tag=$LAST_TAG_STRIPPED" >> $GITHUB_ENV

- name: Check release type (skip patch)
run: |
NEW=${{ env.version }}
OLD=${{ env.last_tag }}

NEW_MAJOR=$(echo $NEW | cut -d. -f1)
NEW_MINOR=$(echo $NEW | cut -d. -f2)
NEW_PATCH=$(echo $NEW | cut -d. -f3)

OLD_MAJOR=$(echo $OLD | cut -d. -f1)
OLD_MINOR=$(echo $OLD | cut -d. -f2)
OLD_PATCH=$(echo $OLD | cut -d. -f3)

if [ "$NEW_MAJOR" -gt "$OLD_MAJOR" ]; then
echo "release_type=major" >> $GITHUB_ENV
elif [ "$NEW_MINOR" -gt "$OLD_MINOR" ]; then
echo "release_type=minor" >> $GITHUB_ENV
else
echo "release_type=patch" >> $GITHUB_ENV
fi

- name: Skip if patch
if: env.release_type == 'patch'
run: echo "Patch release detected β†’ no tag or release will be created."

- name: Create and push git tag
if: env.release_type != 'patch'
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git tag v${{ env.version }}
git push origin v${{ env.version }}

Comment on lines +56 to +63
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ› οΈ Refactor suggestion

Avoid failures when tag already exists; create annotated tags.

Re-runs or manual tags will cause git tag vX.Y.Z to fail. Guard against existing tags and prefer annotated tags for better provenance.

Apply this diff:

       - name: Create and push git tag
         if: env.release_type != 'patch'
         run: |
-          git config user.name "github-actions[bot]"
-          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
-          git tag v${{ env.version }}
-          git push origin v${{ env.version }}
+          set -euo pipefail
+          git config user.name "github-actions[bot]"
+          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+          if git rev-parse -q --verify "refs/tags/v${{ env.version }}" >/dev/null; then
+            echo "Tag v${{ env.version }} already exists. Skipping tag creation."
+          else
+            git tag -a "v${{ env.version }}" -m "Release v${{ env.version }}"
+            git push origin "v${{ env.version }}"
+          fi
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Create and push git tag
if: env.release_type != 'patch'
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git tag v${{ env.version }}
git push origin v${{ env.version }}
- name: Create and push git tag
if: env.release_type != 'patch'
run: |
set -euo pipefail
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
if git rev-parse -q --verify "refs/tags/v${{ env.version }}" >/dev/null; then
echo "Tag v${{ env.version }} already exists. Skipping tag creation."
else
git tag -a "v${{ env.version }}" -m "Release v${{ env.version }}"
git push origin "v${{ env.version }}"
fi
πŸ€– Prompt for AI Agents
In .github/workflows/tag-after-merge.yml around lines 56 to 63, the workflow
currently runs git tag v${{ env.version }} which fails if the tag already exists
and creates lightweight tags; change it to check for an existing tag and create
an annotated tag only when missing. Add a check like git rev-parse -q --verify
"refs/tags/v${{ env.version }}" and if it returns non-zero create an annotated
tag with git tag -a v${{ env.version }} -m "Release v${{ env.version }}" and
push that tag with git push origin v${{ env.version }}, otherwise skip tagging
(echo that tag exists) so re-runs do not fail.

- name: Extract release notes from CHANGELOG
if: env.release_type != 'patch'
id: changelog
run: |
# Match lines starting with "## vX.Y.Z " until the next "## "
awk "/^## v${{ env.version }}[[:space:]]/{flag=1; next} /^## /{flag=0} flag" CHANGELOG.md > RELEASE_NOTES.md

echo "notes<<EOF" >> $GITHUB_ENV
if [ "${{ env.release_type }}" = "major" ]; then
echo "## πŸš€ Major Release" >> $GITHUB_ENV
elif [ "${{ env.release_type }}" = "minor" ]; then
echo "## ✨ Minor Release" >> $GITHUB_ENV
fi
echo "" >> $GITHUB_ENV
cat RELEASE_NOTES.md >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
Comment on lines +68 to +79
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ› οΈ Refactor suggestion

Make changelog extraction robust and fail if notes are missing; also streamline env write.

The current AWK requires a space after the version (^## vX.Y.Z[[:space:]]) and may miss headings like ## v1.2.3 or [v1.2.3] - 2025-08-19. Also, we should fail fast if no section is found to avoid empty releases.

Apply this diff:

       - name: Extract release notes from CHANGELOG
         if: env.release_type != 'patch'
         id: changelog
         run: |
-          # Match lines starting with "## vX.Y.Z " until the next "## "
-          awk "/^## v${{ env.version }}[[:space:]]/{flag=1; next} /^## /{flag=0} flag" CHANGELOG.md > RELEASE_NOTES.md
-        
-          echo "notes<<EOF" >> $GITHUB_ENV
-          if [ "${{ env.release_type }}" = "major" ]; then
-            echo "## πŸš€ Major Release" >> $GITHUB_ENV
-          elif [ "${{ env.release_type }}" = "minor" ]; then
-            echo "## ✨ Minor Release" >> $GITHUB_ENV
-          fi
-          echo "" >> $GITHUB_ENV
-          cat RELEASE_NOTES.md >> $GITHUB_ENV
-          echo "EOF" >> $GITHUB_ENV
+          # Extract lines from the "## vX.Y.Z" (or "[vX.Y.Z]") section until the next "##"
+          awk -v VER="v${{ env.version }}" '
+            $0 ~ "^##[[:space:]]*\\[?" VER "\\]?([[:space:]]|$)" {flag=1; next}
+            /^##[[:space:]]/ && flag {exit}
+            flag
+          ' CHANGELOG.md > RELEASE_NOTES.md
+
+          if [ ! -s RELEASE_NOTES.md ]; then
+            echo "No changelog section found for v${{ env.version }} in CHANGELOG.md"
+            exit 1
+          fi
+
+          {
+            echo "notes<<EOF"
+            if [ "${{ env.release_type }}" = "major" ]; then
+              echo "## πŸš€ Major Release"
+            elif [ "${{ env.release_type }}" = "minor" ]; then
+              echo "## ✨ Minor Release"
+            fi
+            echo ""
+            cat RELEASE_NOTES.md
+            echo "EOF"
+          } >> "$GITHUB_ENV"
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Match lines starting with "## vX.Y.Z " until the next "## "
awk "/^## v${{ env.version }}[[:space:]]/{flag=1; next} /^## /{flag=0} flag" CHANGELOG.md > RELEASE_NOTES.md
echo "notes<<EOF" >> $GITHUB_ENV
if [ "${{ env.release_type }}" = "major" ]; then
echo "## πŸš€ Major Release" >> $GITHUB_ENV
elif [ "${{ env.release_type }}" = "minor" ]; then
echo "## ✨ Minor Release" >> $GITHUB_ENV
fi
echo "" >> $GITHUB_ENV
cat RELEASE_NOTES.md >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
- name: Extract release notes from CHANGELOG
if: env.release_type != 'patch'
id: changelog
run: |
# Extract lines from the "## vX.Y.Z" (or "[vX.Y.Z]") section until the next "##"
awk -v VER="v${{ env.version }}" '
$0 ~ "^##[[:space:]]*\\[?" VER "\\]?([[:space:]]|$)" {flag=1; next}
/^##[[:space:]]/ && flag {exit}
flag
' CHANGELOG.md > RELEASE_NOTES.md
if [ ! -s RELEASE_NOTES.md ]; then
echo "No changelog section found for v${{ env.version }} in CHANGELOG.md"
exit 1
fi
{
echo "notes<<EOF"
if [ "${{ env.release_type }}" = "major" ]; then
echo "## πŸš€ Major Release"
elif [ "${{ env.release_type }}" = "minor" ]; then
echo "## ✨ Minor Release"
fi
echo ""
cat RELEASE_NOTES.md
echo "EOF"
} >> "$GITHUB_ENV"
🧰 Tools
πŸͺ› YAMLlint (1.37.1)

[error] 70-70: trailing spaces

(trailing-spaces)


- name: Create GitHub Release
if: env.release_type != 'patch'
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ env.version }}
name: "Release v${{ env.version }}"
body: ${{ env.notes }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}