mirror of
https://github.com/unraid/api.git
synced 2026-01-03 23:19:54 -06:00
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated release notes extraction workflow to improve handling of version headers in generated release notes. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
211 lines
8.5 KiB
YAML
211 lines
8.5 KiB
YAML
name: Generate Release Notes
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
version:
|
|
description: 'Version number (e.g., 4.25.3)'
|
|
required: true
|
|
type: string
|
|
target_commitish:
|
|
description: 'Commit SHA or branch (leave empty for current HEAD)'
|
|
required: false
|
|
type: string
|
|
release_notes:
|
|
description: 'Custom release notes (leave empty to auto-generate)'
|
|
required: false
|
|
type: string
|
|
outputs:
|
|
release_notes:
|
|
description: 'Generated or provided release notes'
|
|
value: ${{ jobs.generate.outputs.release_notes }}
|
|
secrets:
|
|
UNRAID_BOT_GITHUB_ADMIN_TOKEN:
|
|
required: true
|
|
|
|
jobs:
|
|
generate:
|
|
name: Generate Release Notes
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
release_notes: ${{ steps.generate_notes.outputs.release_notes }}
|
|
steps:
|
|
- name: Checkout repo
|
|
uses: actions/checkout@v5
|
|
with:
|
|
ref: ${{ inputs.target_commitish || github.ref }}
|
|
fetch-depth: 0
|
|
token: ${{ secrets.UNRAID_BOT_GITHUB_ADMIN_TOKEN }}
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
|
|
- name: Generate Release Notes
|
|
id: generate_notes
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
TAG_NAME="v${{ inputs.version }}"
|
|
VERSION="${{ inputs.version }}"
|
|
|
|
if [ -n "${{ inputs.release_notes }}" ]; then
|
|
NOTES="${{ inputs.release_notes }}"
|
|
else
|
|
CHANGELOG_PATH="api/CHANGELOG.md"
|
|
|
|
if [ -f "$CHANGELOG_PATH" ]; then
|
|
echo "Extracting release notes from CHANGELOG.md for version ${VERSION}"
|
|
|
|
NOTES=$(awk -v ver="$VERSION" '
|
|
BEGIN {
|
|
found=0; capture=0; output="";
|
|
gsub(/\./, "\\.", ver);
|
|
}
|
|
/^## \[/ {
|
|
if (capture) exit;
|
|
if ($0 ~ "\\[" ver "\\]") {
|
|
found=1;
|
|
capture=1;
|
|
}
|
|
}
|
|
capture {
|
|
if (output != "") output = output "\n";
|
|
output = output $0;
|
|
}
|
|
END {
|
|
if (found) print output;
|
|
else exit 1;
|
|
}
|
|
' "$CHANGELOG_PATH") || EXTRACTION_STATUS=$?
|
|
|
|
if [ ${EXTRACTION_STATUS:-0} -eq 0 ] && [ -n "$NOTES" ]; then
|
|
echo "✓ Found release notes in CHANGELOG.md"
|
|
else
|
|
echo "⚠ Version ${VERSION} not found in CHANGELOG.md, generating with conventional-changelog"
|
|
|
|
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
|
|
CHANGELOG_GENERATED=false
|
|
|
|
if [ -n "$PREV_TAG" ]; then
|
|
echo "Generating changelog from ${PREV_TAG}..HEAD using conventional-changelog"
|
|
|
|
npm install -g conventional-changelog-cli
|
|
|
|
TEMP_NOTES=$(mktemp)
|
|
conventional-changelog -p conventionalcommits \
|
|
--release-count 1 \
|
|
--output-unreleased \
|
|
> "$TEMP_NOTES" 2>/dev/null || true
|
|
|
|
if [ -s "$TEMP_NOTES" ]; then
|
|
NOTES=$(cat "$TEMP_NOTES")
|
|
|
|
if [ -n "$NOTES" ]; then
|
|
echo "✓ Generated changelog with conventional-changelog"
|
|
CHANGELOG_GENERATED=true
|
|
|
|
TEMP_CHANGELOG=$(mktemp)
|
|
{
|
|
if [ -f "$CHANGELOG_PATH" ]; then
|
|
head -n 1 "$CHANGELOG_PATH"
|
|
echo ""
|
|
echo "$NOTES"
|
|
echo ""
|
|
tail -n +2 "$CHANGELOG_PATH"
|
|
else
|
|
echo "# Changelog"
|
|
echo ""
|
|
echo "$NOTES"
|
|
fi
|
|
} > "$TEMP_CHANGELOG"
|
|
|
|
mv "$TEMP_CHANGELOG" "$CHANGELOG_PATH"
|
|
echo "✓ Updated CHANGELOG.md with generated notes"
|
|
else
|
|
echo "⚠ conventional-changelog produced empty output, using GitHub auto-generation"
|
|
NOTES=$(gh api repos/${{ github.repository }}/releases/generate-notes \
|
|
-f tag_name="${TAG_NAME}" \
|
|
-f target_commitish="${{ inputs.target_commitish || github.sha }}" \
|
|
-f previous_tag_name="${PREV_TAG}" \
|
|
--jq '.body')
|
|
fi
|
|
else
|
|
echo "⚠ conventional-changelog failed, using GitHub auto-generation"
|
|
NOTES=$(gh api repos/${{ github.repository }}/releases/generate-notes \
|
|
-f tag_name="${TAG_NAME}" \
|
|
-f target_commitish="${{ inputs.target_commitish || github.sha }}" \
|
|
-f previous_tag_name="${PREV_TAG}" \
|
|
--jq '.body')
|
|
fi
|
|
|
|
rm -f "$TEMP_NOTES"
|
|
else
|
|
echo "⚠ No previous tag found, using GitHub auto-generation"
|
|
NOTES=$(gh api repos/${{ github.repository }}/releases/generate-notes \
|
|
-f tag_name="${TAG_NAME}" \
|
|
-f target_commitish="${{ inputs.target_commitish || github.sha }}" \
|
|
--jq '.body' || echo "Release ${VERSION}")
|
|
fi
|
|
|
|
if [ "$CHANGELOG_GENERATED" = true ]; then
|
|
BRANCH_OR_SHA="${{ inputs.target_commitish || github.ref }}"
|
|
|
|
if git show-ref --verify --quiet "refs/heads/${BRANCH_OR_SHA}"; then
|
|
echo ""
|
|
echo "=========================================="
|
|
echo "CHANGELOG GENERATED AND COMMITTED"
|
|
echo "=========================================="
|
|
echo ""
|
|
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
|
|
BEFORE_SHA=$(git rev-parse HEAD)
|
|
|
|
git add "$CHANGELOG_PATH"
|
|
git commit -m "chore: add changelog for version ${VERSION}"
|
|
git push origin "HEAD:${BRANCH_OR_SHA}"
|
|
|
|
AFTER_SHA=$(git rev-parse HEAD)
|
|
|
|
echo "✓ Changelog committed and pushed successfully"
|
|
echo ""
|
|
echo "Previous SHA: ${BEFORE_SHA}"
|
|
echo "New SHA: ${AFTER_SHA}"
|
|
echo ""
|
|
echo "⚠️ CRITICAL: A new commit was created, but github.sha is immutable."
|
|
echo "⚠️ github.sha = ${BEFORE_SHA} (original workflow trigger)"
|
|
echo "⚠️ The release tag must point to ${AFTER_SHA} (with changelog)"
|
|
echo ""
|
|
echo "Re-run this workflow to create the release with the correct commit."
|
|
echo ""
|
|
exit 1
|
|
else
|
|
echo "⚠ Target is a commit SHA, not a branch. Cannot push changelog updates."
|
|
echo "Changelog was generated but not committed."
|
|
fi
|
|
fi
|
|
fi
|
|
else
|
|
echo "⚠ CHANGELOG.md not found, using GitHub auto-generation"
|
|
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
|
|
|
|
if [ -n "$PREV_TAG" ]; then
|
|
NOTES=$(gh api repos/${{ github.repository }}/releases/generate-notes \
|
|
-f tag_name="${TAG_NAME}" \
|
|
-f target_commitish="${{ inputs.target_commitish || github.sha }}" \
|
|
-f previous_tag_name="${PREV_TAG}" \
|
|
--jq '.body')
|
|
else
|
|
NOTES="Release ${VERSION}"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
echo "release_notes<<EOF" >> $GITHUB_OUTPUT
|
|
echo "$NOTES" >> $GITHUB_OUTPUT
|
|
echo "EOF" >> $GITHUB_OUTPUT
|
|
|