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
112 changes: 112 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
name: Create Release

on:
push:
tags:
- "release/*/*/v*.*.*"

jobs:
create-release:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: read

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false

- name: Extract tag information
id: tag_info
run: |
TAG=${GITHUB_REF#refs/tags/}
echo "tag=$TAG" >> $GITHUB_OUTPUT

IFS='/' read -ra PARTS <<< "$TAG"
NAMESPACE="${PARTS[1]}"
MODULE="${PARTS[2]}"
VERSION="${PARTS[3]}"

echo "namespace=$NAMESPACE" >> $GITHUB_OUTPUT
echo "module=$MODULE" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "module_path=registry/$NAMESPACE/modules/$MODULE" >> $GITHUB_OUTPUT

RELEASE_TITLE="$NAMESPACE/$MODULE $VERSION"
echo "release_title=$RELEASE_TITLE" >> $GITHUB_OUTPUT

- name: Find previous tag
id: prev_tag
env:
NAMESPACE: ${{ steps.tag_info.outputs.namespace }}
MODULE: ${{ steps.tag_info.outputs.module }}
CURRENT_TAG: ${{ steps.tag_info.outputs.tag }}
run: |
PREV_TAG=$(git tag -l "release/$NAMESPACE/$MODULE/v*" | sort -V | grep -B1 "$CURRENT_TAG" | head -1)

if [ -z "$PREV_TAG" ] || [ "$PREV_TAG" = "$CURRENT_TAG" ]; then
echo "No previous tag found, using initial commit"
PREV_TAG=$(git rev-list --max-parents=0 HEAD)
fi

echo "prev_tag=$PREV_TAG" >> $GITHUB_OUTPUT
echo "Previous tag: $PREV_TAG"

- name: Generate changelog
id: changelog
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MODULE_PATH: ${{ steps.tag_info.outputs.module_path }}
PREV_TAG: ${{ steps.prev_tag.outputs.prev_tag }}
CURRENT_TAG: ${{ steps.tag_info.outputs.tag }}
run: |
echo "Generating changelog for $MODULE_PATH between $PREV_TAG and $CURRENT_TAG"

COMMITS=$(git log --oneline --no-merges "$PREV_TAG..$CURRENT_TAG" -- "$MODULE_PATH")

if [ -z "$COMMITS" ]; then
echo "No commits found for this module"
echo "changelog=No changes found for this module." >> $GITHUB_OUTPUT
exit 0
fi

FULL_CHANGELOG=$(gh api repos/:owner/:repo/releases/generate-notes \
--field tag_name="$CURRENT_TAG" \
--field previous_tag_name="$PREV_TAG" \
--jq '.body')

MODULE_COMMIT_SHAS=$(git log --format="%H" --no-merges "$PREV_TAG..$CURRENT_TAG" -- "$MODULE_PATH")

FILTERED_CHANGELOG="## What's Changed\n\n"

for sha in $MODULE_COMMIT_SHAS; do
SHORT_SHA=${sha:0:7}

COMMIT_LINES=$(echo "$FULL_CHANGELOG" | grep -E "$SHORT_SHA|$(git log --format='%s' -n 1 $sha)" || true)

if [ -n "$COMMIT_LINES" ]; then
FILTERED_CHANGELOG="${FILTERED_CHANGELOG}${COMMIT_LINES}\n"
else
COMMIT_MSG=$(git log --format="%s" -n 1 $sha)
AUTHOR=$(gh api repos/:owner/:repo/commits/$sha --jq '.author.login // .commit.author.name')
FILTERED_CHANGELOG="${FILTERED_CHANGELOG}* $COMMIT_MSG by @$AUTHOR\n"
Comment on lines +94 to +95
Copy link

Copilot AI Aug 23, 2025

Choose a reason for hiding this comment

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

If the author is resolved to a name (not a GitHub username), prefixing it with '@' will create an invalid GitHub mention. Only prefix with '@' when .author.login is available, not when falling back to .commit.author.name.

Suggested change
AUTHOR=$(gh api repos/:owner/:repo/commits/$sha --jq '.author.login // .commit.author.name')
FILTERED_CHANGELOG="${FILTERED_CHANGELOG}* $COMMIT_MSG by @$AUTHOR\n"
AUTHOR_LOGIN=$(gh api repos/:owner/:repo/commits/$sha --jq '.author.login')
if [ -n "$AUTHOR_LOGIN" ]; then
AUTHOR_MENTION="@$AUTHOR_LOGIN"
else
AUTHOR_NAME=$(gh api repos/:owner/:repo/commits/$sha --jq '.commit.author.name')
AUTHOR_MENTION="$AUTHOR_NAME"
fi
FILTERED_CHANGELOG="${FILTERED_CHANGELOG}* $COMMIT_MSG by $AUTHOR_MENTION\n"

Copilot uses AI. Check for mistakes.

fi
done

echo "changelog<<EOF" >> $GITHUB_OUTPUT
echo -e "$FILTERED_CHANGELOG" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

- name: Create Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG_NAME: ${{ steps.tag_info.outputs.tag }}
RELEASE_TITLE: ${{ steps.tag_info.outputs.release_title }}
CHANGELOG: ${{ steps.changelog.outputs.changelog }}
run: |
gh release create "$TAG_NAME" \
--title "$RELEASE_TITLE" \
--notes "$CHANGELOG"