## Overview
-The release workflow generates release notes **specific to each channel** by only including commits since the last release of that same channel. It uses your **Release Drafter configuration** (`.github/release-drafter.yml`) for label-based categorization.
+The release workflow generates release notes **specific to each channel** by leveraging Release Drafter's `filter-by-commitish` feature. This ensures that:
+
+- **Stable** releases only show commits from the `stable` branch
+- **Beta** releases only show commits from the `dev` branch since the last beta
+- **Nightly** releases only show commits from the `dev` branch since the last nightly
+
+The workflow uses your **Release Drafter configuration** (`.github/release-drafter.yml`) for label-based categorization and formatting.
## How It Works
-### 1. Previous Release Detection
+### 1. Filter by Branch (commitish)
+
+The `.github/release-drafter.yml` file includes:
+
+```yaml
+filter-by-commitish: true
+```
+
+This tells Release Drafter to only consider releases that have the same `target_commitish` (branch) when calculating the commit range. Combined with setting the `commitish` parameter to the appropriate branch:
+
+- **Stable releases**: Use `commitish: stable` → Only sees releases created from `stable` branch
+- **Beta releases**: Use `commitish: dev` → Only sees releases created from `dev` branch
+- **Nightly releases**: Use `commitish: dev` → Only sees releases created from `dev` branch
-The workflow identifies the previous release for each channel using tag patterns:
+### 2. Previous Release Detection
+
+The workflow also manually identifies the previous release for context headers using tag patterns:
#### Stable Channel
- **Pattern**: `^[0-9]+\.[0-9]+\.[0-9]+$` (e.g., `2.1.0`, `2.0.5`)
- **Branch**: `dev`
- **Finds**: Latest nightly release (`.devYYYYMMDD` suffix)
-### 2. Release Notes Generation
+### 3. Release Notes Generation
-The workflow generates notes in three steps:
+Release Drafter automatically:
-1. **Find PRs in commit range**: Extracts PR numbers from merge commits between the previous tag and HEAD
-2. **Categorize by labels**: Applies the category rules from `.github/release-drafter.yml`:
+1. **Finds commit range**: Determines commits between the previous release (same branch) and HEAD
+2. **Extracts PRs**: Identifies all merged pull requests in that range
+3. **Categorizes by labels**: Applies the category rules from `.github/release-drafter.yml`:
- ⚠ Breaking Changes (`breaking-change` label)
- 🚀 New Providers (`new-provider` label)
- 🚀 Features and enhancements (`feature`, `enhancement`, `new-feature` labels)
- 🐛 Bugfixes (`bugfix` label)
- 🧰 Maintenance (`ci`, `documentation`, `maintenance`, `dependencies` labels)
-3. **Add contributors**: Lists all unique contributors from the PRs
+4. **Lists contributors**: Adds all unique contributors from the PRs
+
+The workflow then enhances these notes by:
+- Adding a context header showing the previous release
+- Extracting and appending frontend changes from frontend update PRs
+- Merging and deduplicating contributors from both server and frontend
-### 3. What This Means
+### 4. What This Means
#### ✅ Stable Release Notes
- Include **only commits since the last stable release**
## Release Drafter Configuration
-✅ The workflow **uses your `.github/release-drafter.yml` configuration** for:
+✅ The workflow **uses Release Drafter natively** with the following key configuration:
+
+```yaml
+# .github/release-drafter.yml
+filter-by-commitish: true # Only consider releases from the same branch
+```
+
+This configuration, combined with setting the appropriate `commitish` parameter when calling Release Drafter, ensures:
+- **No temporary hiding of releases** (avoids updating publish dates)
+- **Native Release Drafter filtering** (robust and reliable)
+- **Branch-based separation** (stable vs dev commits are naturally separated)
+
+The workflow also uses your existing configuration for:
- Category definitions (labels → section headers)
- Category titles and emoji
- Excluded contributors (bots)
- PR title format
-The workflow manually implements the categorization logic to ensure channel-specific commit ranges while preserving your custom formatting.
-
## Example Release Notes Format
```markdown
name: release-dists
path: dist/
- - name: Determine previous version tag and temporarily hide other channels
+ - name: Determine previous version tag
id: prev_version
run: |
CHANNEL="${{ inputs.channel }}"
- # Define patterns for each channel
- case "$CHANNEL" in
- stable)
- KEEP_PATTERN='^[0-9]+\.[0-9]+\.[0-9]+$'
- HIDE_PATTERN='\.(b|dev)[0-9]+'
- ;;
- beta)
- KEEP_PATTERN='^[0-9]+\.[0-9]+\.[0-9]+\.b[0-9]+$'
- HIDE_PATTERN='(^[0-9]+\.[0-9]+\.[0-9]+$|\.dev[0-9]+$)'
- ;;
- nightly)
- KEEP_PATTERN='^[0-9]+\.[0-9]+\.[0-9]+\.dev[0-9]+$'
- HIDE_PATTERN='(^[0-9]+\.[0-9]+\.[0-9]+$|\.b[0-9]+$)'
- ;;
- esac
-
- echo "📋 Hiding releases from other channels for Release Drafter..."
-
- # Get all releases and temporarily convert other channels to draft
- gh release list --limit 100 --json tagName,isDraft,isPrerelease | jq -c '.[]' | while read -r release; do
- TAG=$(echo "$release" | jq -r '.tagName')
- IS_DRAFT=$(echo "$release" | jq -r '.isDraft')
-
- # Skip if already a draft
- if [ "$IS_DRAFT" = "true" ]; then
- continue
- fi
-
- # Check if this release should be hidden (not matching current channel pattern)
- if echo "$TAG" | grep -vE "$KEEP_PATTERN" > /dev/null 2>&1; then
- echo " Temporarily hiding: $TAG"
- # Store this tag so we can restore it later
- echo "$TAG" >> /tmp/hidden_releases.txt
- # Mark as draft (makes it invisible to Release Drafter)
- gh release edit "$TAG" --draft=true
- fi
- done
-
- # Now find the previous tag of this channel
+ # Find the previous tag of this channel
case "$CHANNEL" in
stable)
PREV_TAG=$(git tag --sort=-version:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1)
echo "prev_tag=$PREV_TAG" >> $GITHUB_OUTPUT
echo "has_prev_tag=true" >> $GITHUB_OUTPUT
fi
- env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create Release with Release Drafter
id: create_release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - name: Restore hidden releases
- if: always()
- run: |
- if [ -f /tmp/hidden_releases.txt ]; then
- echo "📋 Restoring hidden releases..."
- while read -r TAG; do
- if [ -n "$TAG" ]; then
- echo " Restoring: $TAG"
- gh release edit "$TAG" --draft=false
- fi
- done < /tmp/hidden_releases.txt
- echo "✅ All releases restored"
- else
- echo "No releases to restore"
- fi
- env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- name: Add channel context to release notes
if: steps.prev_version.outputs.has_prev_tag == 'true'
run: |