This document describes the complete automated release workflow for SuaviUI. The entire process is handled by AI assistant commands - no manual steps required.
- Ensure all code changes are tested and ready
- Version number should be updated in
SuaviUI.toc(line 9:## Version: X.X.X) - Review changes with
git statusto verify what will be committed
The AI assistant performs the following steps in order:
git add .
git commit -m "Release vX.X.X: [brief description of changes]"git tag -a vX.X.X -m "Release vX.X.X"git push origin master
git push origin vX.X.X- Location: Parent folder of addon (
e:\Games\World of Warcraft\_retail_\Interface\AddOns\) - Filename:
SuaviUI-vX.X.X.zip - Size: ~2 MB (clean package without dev files, .venv, docs, spec)
Files EXCLUDED from ZIP:
docs/- All development documentationdev/- All development scripts, debug files, and backups (package.ps1,DEBUG_*.lua,TEST_*.lua,*_backup.lua,ACE3_UPDATE_REPORT.txt,error.log, etc.)spec/- Test specs (andspec/mocks/).git/,.github/- Git metadata.venv/- Python virtual environment (development tooling).vscode/- VS Code workspace settings.claude/- Claude AI context files.previews/- Screenshot previews.gitignore,.pkgmeta,.wowup_ignore- Packaging/CI config files.copilot-instructions.md- AI instructions.busted- Busted test runner configSuaviUI.code-workspace- VS Code workspace file.DS_Store,DS_Store- macOS metadata*_BACKUP*- Backup folders (e.g.,LibOpenRaid_BACKUP_v173_MODIFIED/)SUAVIUI_PATCHES.md- Internal documentation
Files INCLUDED in ZIP:
- All Lua files (
utils/,imports/,libs/,skinning/) - All XML files (
load.xml,Bindings.xml, embeds, etc.) - All assets (
assets/textures/,assets/fonts/,assets/cursor/, etc.) - Localization files (
Locales/) SuaviUI.toc(addon metadata)
IMPORTANT: Run from the AddOns folder where the ZIP file is located!
cd "E:\Games\World of Warcraft\_retail_\Interface\AddOns"
# Delete any existing release (to handle re-releases):
gh release delete vX.X.X --repo alesys/SuaviUI --yes 2>/dev/null
# Create new release with ZIP file attached:
gh release create vX.X.X "SuaviUI-vX.X.X.zip" \
--title "SuaviUI vX.X.X - [Edition Name]" \
--notes "[Release notes markdown]" \
--repo alesys/SuaviUIKey Points:
- ✅ ZIP file MUST be specified as argument to upload it to the release
- ✅ ZIP file path is RELATIVE to current directory (must be in AddOns folder)
- ✅ Without the ZIP file path, only auto-generated source archives are created (NO addon package!)
- ✅
--clobberoptional flag if you need to replace an existing asset
Release Notes Template:
## 🎮 SuaviUI vX.X.X - [Edition Name]
### ✨ Major Features
- **Feature 1**: Description
- **Feature 2**: Description
### 🔧 Fixes & Improvements
- Fixed issue with [component]
- Improved [functionality]
- Added [enhavisible in release assets (not just "Source code" auto-archives)
- ✅ ZIP file size appropriate (~2 MB, without docs/, dev/, .venv/, spec/, and backup folders)
- ✅ Tag pushed to GitHub: `git tag --list | grep vX.X.X`
- ✅ Commit pushed to master branch: `git log --oneline -1`
**Common Issues:**
- ❌ "Release has no assets" or only "Source code" archives → ZIP file path was wrong in Step 5
- ❌ ZIP file too large (>5 MB) → Backup folders or docs/ were included
- ❌ "release not found" error → Release was created as tag-only, not proper release
- Excludes development documentation (docs/ folder)
- Clean release with only runtime files
- Compatible with The War Within (Interface 120000-120001)
### 🙏 Credits
Special thanks to our testers: Vela, Pataz, and Ñora for their feedback and testing!After publishing the GitHub release, generate a Markdown changelog for CurseForge. CurseForge renders Markdown in the project description and changelog fields, so this format is preferred over plain text. Keep it player-facing — no technical jargon, no code references.
CurseForge Changelog Template (Markdown):
## vX.X.X — [Edition Name]
### [Section Name]
- **Feature name** — what it does in plain English
- Another change
### Fixes
- Fixed thing that was broken
- Another fix
### [Another Section]
- More changesRules:
- Use Markdown:
##for the version heading,###for sections,-for bullets - Use bold sparingly to highlight feature names
- Section titles in Title Case, no emoji
- Keep descriptions short and player-friendly (what changed, not how)
- Group by feature area (e.g., New Feature, Fixes, Unit Frames, Action Bars, Options Panel)
- Present it to the user inside a fenced code block so the raw Markdown is easy to copy-paste to CurseForge
After release, verify:
- ✅ GitHub release published:
https://github.com/alesys/SuaviUI/releases/tag/vX.X.X - ✅ ZIP file created in parent folder with correct size (~2 MB)
- ✅ Tag pushed to GitHub
- ✅ Commit pushed to master branch
package-as: SuaviUI
enable-nolib-creation: no
ignore:
- .git
- .github
- .gitignore
- .copilot-instructions.md
- .busted
- .venv
- .vscode
- .claude
- .previews
- docs
- dev
- spec
- README.md
- .pkgmeta
- .wowup_ignore
- SuaviUI.code-workspace
- SUAVIUI_PATCHES.md.git/
.github/
.venv/
.vscode/
.claude/
.previews/
docs/
dev/
spec/
README.md
.copilot-instructions.md
.gitignore
.wowup_ignore
.busted
SuaviUI.code-workspace
SUAVIUI_PATCHES.md
# VS Code workspace
SuaviUI.code-workspace
# Release artifacts
SuaviUI.zip
# macOS metadata files
.DS_Store
**/.DS_Store
IMPORTANT: Do NOT use Compress-Archive -Path $files.FullName — it flattens the
directory structure, losing the SuaviUI/ root folder and duplicating files at the
top level. Use robocopy staging instead:
cd "e:\Games\World of Warcraft\_retail_\Interface\AddOns"
# Remove old ZIP if exists
if (Test-Path "SuaviUI-vX.X.X.zip") { Remove-Item "SuaviUI-vX.X.X.zip" }
# Stage a clean copy via robocopy (preserves folder structure)
$staging = "$env:TEMP\SuaviUI-release"
if (Test-Path $staging) { Remove-Item $staging -Recurse -Force }
# /E = recursive, /XD = exclude dirs, /XF = exclude files
robocopy "SuaviUI" "$staging\SuaviUI" /E /NFL /NDL /NJH /NJS /NC /NS `
/XD docs dev .git .github .previews .claude spec .venv .vscode "*_BACKUP*" `
/XF .gitignore .pkgmeta .wowup_ignore .copilot-instructions.md `
SuaviUI.code-workspace .DS_Store DS_Store .busted SUAVIUI_PATCHES.md
# Create ZIP from staging (SuaviUI/ is the root folder inside the archive)
Compress-Archive -Path "$staging\SuaviUI" -DestinationPath "SuaviUI-vX.X.X.zip" -Force
# Cleanup staging
Remove-Item $staging -Recurse -Force
# Verify
if (Test-Path "SuaviUI-vX.X.X.zip") {
Write-Host "✓ Release ZIP created successfully" -ForegroundColor Green
Write-Host "Size: $([math]::Round((Get-Item 'SuaviUI-vX.X.X.zip').Length / 1MB, 2)) MB"
}- CDM taint fix: replaced all HookScript on CDM viewers with hooksecurefunc (taint-safe)
- CDM taint fix: removed HookScript("OnUpdate/OnShow/OnSizeChanged") from buff bar/icon viewers
- CDM taint fix: separate addon-owned polling frame for legacy skinning (50ms interval)
- CDM taint fix: restored SetSize with InCombatLockdown + Edit Mode guards
- Fixed pcall multi-return bug: GetBuffBarFrames only returned first child (all bars after first unskinned)
- Same pcall fix applied to cooldownmanager.lua ViewerAdapters and CooldownManagerCentered
- Combat lockdown guards: EnableMouse, SetFrameLevel, SetFrameStrata, extraActionButton Hide
- Deferred pending table for extraActionButton combat hide (processed on PLAYER_REGEN_ENABLED)
- Added automated release script (dev/release.sh)
- Size: ~2 MB
- Character flyout ilvl overlay: item level on Alt-hover equipment flyout buttons
- Rewrote flyout ilvl lookup (hook UpdateItems, GetContainerItemInfo hyperlink) — no more cache misses
- Buffbar combat taint fix: guard EnableMouse calls with InCombatLockdown()
- GUI form widget labels: SetJustifyH("LEFT") across all widget types
- Character stats: showTooltips default (off)
- Size: ~2.06 MB
- Settings migrated from Options GUI to Edit Mode panels (CDM, Action Bars, Minimap, Unit Frames)
- GUI builder pattern refactor (WrapBuilder, lazy page builders)
- New Pill/Circle UI widgets, character panel accent pips and section backgrounds
- Size: ~2 MB
- Tracked bars: legacy path (USE_CUSTOM_BARS=false), skin Blizzard viewers in place
- Tracked icons: legacy path (USE_CUSTOM_ICONS=false), remove ForcePopulate taint, show stack counts
- Size: ~2 MB
- CDM frame-field taint purge complete
- Action bars re-enabled after full weak-table migration
- C API data pipeline for tracked bars
- Size: 2.05 MB (after correcting .venv/.vscode/dev/ exclusions)
- Edit Mode Integration with LibEQOLEditMode
- Castbar Mixin System for in-place updates
- Action Bar improvements (EAB/Zone Ability)
- Size: 5.79 MB
When user requests a release:
- Check git status
- Add all changes
- Commit with descriptive message
- Create annotated tag
- Push commit + tag to origin
- Create ZIP in parent folder with exclusions
- Publish GitHub release with formatted notes
- Verify all steps completed successfully
Do not ask for confirmation - execute the full workflow automatically.
- Ensure parent directory exists
- Check PowerShell execution policy
- Verify file permissions
- Check GitHub authentication
- Verify remote repository URL:
git remote -v - Ensure network connectivity
Symptoms: Release page shows only "Source code (zip)" and "Source code (tar.gz)", no SuaviUI-vX.X.X.zip asset
Cause: ZIP file path was missing or wrong in Step 5 command
Solution:
cd "E:\Games\World of Warcraft\_retail_\Interface\AddOns"
gh release delete vX.X.X --repo alesys/SuaviUI --yes
gh release create vX.X.X "SuaviUI-vX.X.X.zip" --title "..." --notes "..." --repo alesys/SuaviUI- Delete existing release first:
gh release delete vX.X.X --repo alesys/SuaviUI --yes - Then create new release with Step 5 command
- Or increment version number and retry
- Automated changelog generation from git commits
- CurseForge CLI integration
- WowUp automatic upload
- Version bump automation in .toc file