Skip to content

Set version to v4.1.3-alpha.5 #149

Set version to v4.1.3-alpha.5

Set version to v4.1.3-alpha.5 #149

Workflow file for this run

name: Package and Release
on:
push:
branches: [main]
tags: ['v*']
workflow_dispatch:
inputs:
tag:
description: 'Tag to build (e.g. v1.0.0-beta.1). Leave empty for alpha build.'
required: false
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.tag || github.ref }}
fetch-depth: 0
- name: Check if build is needed
id: guard
run: |
# Tags and workflow_dispatch always build
if [[ "$GITHUB_REF" == refs/tags/* ]] || [[ -n "${{ inputs.tag }}" ]] || [[ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]]; then
echo "skip=false" >> $GITHUB_OUTPUT
exit 0
fi
# Branch pushes: skip if only docs/CI files changed
DOMINATED=true
for f in $(git diff --name-only HEAD~1..HEAD 2>/dev/null); do
case "$f" in
*.md|*.sh|.github/*|.gitignore|.pkgmeta|Changelog.lua) ;;
*) DOMINATED=false; break ;;
esac
done
echo "skip=$DOMINATED" >> $GITHUB_OUTPUT
- name: Generate Changelog.lua
if: steps.guard.outputs.skip != 'true'
id: changelog
run: |
chmod +x generate_changelog.sh
if [[ "$GITHUB_REF" == refs/heads/* ]] && [[ -z "${{ inputs.tag }}" ]]; then
export FORCE_ALPHA=true
fi
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
export OVERRIDE_TAG="${GITHUB_REF#refs/tags/}"
elif [[ -n "${{ inputs.tag }}" ]]; then
export OVERRIDE_TAG="${{ inputs.tag }}"
fi
./generate_changelog.sh
VERSION=$(grep '^## Version:' DandersFrames.toc | sed 's/^## Version: //')
CHANNEL=$(grep 'DF.RELEASE_CHANNEL' Changelog.lua | sed 's/.*= "\(.*\)"/\1/')
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "channel=$CHANNEL" >> $GITHUB_OUTPUT
NOTES=$(awk '/^## / { count++; if (count > 1) exit } count >= 1 { print }' CHANGELOG.md | sed -e :a -e '/^[[:space:]-]*$/{ $d; N; ba; }')
{
echo "notes<<NOTES_EOF"
echo "$NOTES"
echo "NOTES_EOF"
} >> $GITHUB_OUTPUT
- name: Create local tag for clean zip naming
if: steps.guard.outputs.skip != 'true'
run: |
VERSION="${{ steps.changelog.outputs.version }}"
# Create a local-only tag so the packager uses a clean name
# e.g. v4.0.5-alpha.3 -> zip becomes DandersFrames-v4.0.5-alpha.3
if ! git tag --list | grep -qx "$VERSION"; then
git tag "$VERSION"
fi
- name: Package and Release
if: steps.guard.outputs.skip != 'true'
uses: BigWigsMods/packager@v2
env:
CF_API_KEY: ${{ secrets.CF_API_KEY }}
GITHUB_OAUTH: ${{ secrets.GITHUB_TOKEN }}
- name: Notify Discord (dev channel — alpha/beta)
if: steps.guard.outputs.skip != 'true' && success() && steps.changelog.outputs.channel != 'release'
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_DEV }}
VERSION: ${{ steps.changelog.outputs.version }}
CHANNEL: ${{ steps.changelog.outputs.channel }}
NOTES: ${{ steps.changelog.outputs.notes }}
run: |
if [ -z "$DISCORD_WEBHOOK_URL" ]; then
echo "No dev Discord webhook configured, skipping."
exit 0
fi
CHANNEL_UPPER=$(echo "$CHANNEL" | sed 's/.*/\u&/')
case "$CHANNEL" in
beta) EMOJI="🧪"; LABEL="Beta ${VERSION} Available for Testing!" ;;
*) EMOJI="🧪"; LABEL="Alpha ${VERSION} Available for Testing!" ;;
esac
BODY=$(echo "$NOTES" | sed '1{/^## /d}' | sed '/^[[:space:]]*$/d')
HEADER="### ${EMOJI} ${LABEL}
**Download:** [CurseForge](<https://www.curseforge.com/wow/addons/danders-frames>) *(select \"${CHANNEL_UPPER}\" from the dropdown)* • [GitHub Releases](<https://github.com/DanderBot/DandersFrames/releases>)
**Support Development:** [PayPal](<https://paypal.me/dandersframesaddon>)"
HEADER=$(echo "$HEADER" | sed 's/^ //')
FOOTER="*${CHANNEL_UPPER} builds are available on CurseForge by selecting \"${CHANNEL_UPPER}\" in the file dropdown, or from [GitHub Releases](<https://github.com/DanderBot/DandersFrames/releases>).*"
# Split body into chunks that fit Discord's 2000 char limit
# Reserve space for header/footer text in first/last messages
HEADER_LEN=${#HEADER}
FOOTER_LEN=${#FOOTER}
FIRST_BUDGET=$((1900 - HEADER_LEN))
MIDDLE_BUDGET=1900
LAST_BUDGET=$((1900 - FOOTER_LEN))
MESSAGES=()
CURRENT=""
FIRST=true
while IFS= read -r line; do
BUDGET=$MIDDLE_BUDGET
if [ "$FIRST" = true ]; then
BUDGET=$FIRST_BUDGET
fi
CANDIDATE="${CURRENT:+$CURRENT
}${line}"
if [ ${#CANDIDATE} -gt "$BUDGET" ] && [ -n "$CURRENT" ]; then
MESSAGES+=("$CURRENT")
CURRENT="$line"
FIRST=false
else
CURRENT="$CANDIDATE"
fi
done <<< "$BODY"
[ -n "$CURRENT" ] && MESSAGES+=("$CURRENT")
TOTAL=${#MESSAGES[@]}
for i in "${!MESSAGES[@]}"; do
MSG=""
if [ "$i" -eq 0 ]; then
MSG="${HEADER}
${MESSAGES[$i]}"
else
MSG="${MESSAGES[$i]}"
fi
if [ "$i" -eq $((TOTAL - 1)) ]; then
MSG="${MSG}
${FOOTER}"
fi
MSG=$(echo "$MSG" | sed 's/^ //')
PAYLOAD=$(jq -n --arg content "$MSG" '{ content: $content }')
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
"$DISCORD_WEBHOOK_URL")
echo "Message $((i+1))/${TOTAL}: HTTP ${HTTP_CODE}"
# Small delay between messages to preserve ordering
if [ "$i" -lt $((TOTAL - 1)) ]; then
sleep 1
fi
done
- name: Notify Discord (release channel — stable only)
if: steps.guard.outputs.skip != 'true' && success() && steps.changelog.outputs.channel == 'release'
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_RELEASE }}
VERSION: ${{ steps.changelog.outputs.version }}
NOTES: ${{ steps.changelog.outputs.notes }}
ROLE_MENTION: "<@&1444387824005808128>"
run: |
if [ -z "$DISCORD_WEBHOOK_URL" ]; then
echo "No release Discord webhook configured, skipping."
exit 0
fi
BODY=$(echo "$NOTES" | sed '1{/^## /d}' | sed '/^[[:space:]]*$/d')
HEADER="${ROLE_MENTION}
### 🔔 Update ${VERSION} is Live!
**Download:** [CurseForge](<https://www.curseforge.com/wow/addons/danders-frames>) • [Wago](<https://addons.wago.io/addons/danders-frames>) • [GitHub Releases](<https://github.com/DanderBot/DandersFrames/releases>)
**Support Development:** [PayPal](<https://paypal.me/dandersframesaddon>)"
HEADER=$(echo "$HEADER" | sed 's/^ //')
FOOTER="*Note: It may take 15-30 minutes to appear on the CurseForge client.*"
HEADER_LEN=${#HEADER}
FOOTER_LEN=${#FOOTER}
ROLE_LEN=${#ROLE_MENTION}
FIRST_BUDGET=$((1900 - HEADER_LEN))
MIDDLE_BUDGET=$((1900 - ROLE_LEN - 1))
LAST_BUDGET=$((1900 - FOOTER_LEN - ROLE_LEN - 1))
MESSAGES=()
CURRENT=""
FIRST=true
while IFS= read -r line; do
BUDGET=$MIDDLE_BUDGET
if [ "$FIRST" = true ]; then
BUDGET=$FIRST_BUDGET
fi
CANDIDATE="${CURRENT:+$CURRENT
}${line}"
if [ ${#CANDIDATE} -gt "$BUDGET" ] && [ -n "$CURRENT" ]; then
MESSAGES+=("$CURRENT")
CURRENT="$line"
FIRST=false
else
CURRENT="$CANDIDATE"
fi
done <<< "$BODY"
[ -n "$CURRENT" ] && MESSAGES+=("$CURRENT")
TOTAL=${#MESSAGES[@]}
for i in "${!MESSAGES[@]}"; do
MSG=""
if [ "$i" -eq 0 ]; then
MSG="${HEADER}
${MESSAGES[$i]}"
else
MSG="${ROLE_MENTION}
${MESSAGES[$i]}"
fi
if [ "$i" -eq $((TOTAL - 1)) ]; then
MSG="${MSG}
${FOOTER}"
fi
MSG=$(echo "$MSG" | sed 's/^ //')
PAYLOAD=$(jq -n --arg content "$MSG" '{ content: $content }')
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
"$DISCORD_WEBHOOK_URL")
echo "Message $((i+1))/${TOTAL}: HTTP ${HTTP_CODE}"
if [ "$i" -lt $((TOTAL - 1)) ]; then
sleep 1
fi
done