Compare commits

..

No commits in common. "master" and "5.22.0" have entirely different histories.

13 changed files with 411 additions and 209 deletions

View file

@ -1,75 +0,0 @@
name: release
on:
push:
tags:
- '*-coa.*' # Asc-1.1.6-coa.2, 9.1.40-coa.3, etc.
- 'v*' # v0.3.0 for repos without an upstream version
jobs:
release:
runs-on: linux-amd64
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # build_zip uses git archive HEAD; full history is fine
- name: Build per-addon zip(s)
run: bash tools/build_zip.sh
- name: Publish release (Gitea API direct; no action dependency)
env:
GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
TAG: ${{ github.ref_name }}
API: ${{ github.server_url }}/api/v1
# Gitea attachment ceiling is 200 MiB (see roles/gitea config).
# Skip anything larger so one oversized asset doesn't fail the job.
MAX_BYTES: 209715200
run: |
set -euo pipefail
# Create the release (or reuse if it already exists for this tag).
RID=$(curl -s -H "Authorization: token $GITEA_TOKEN" \
"$API/repos/$REPO/releases/tags/$TAG" 2>/dev/null \
| jq -r '.id // empty')
if [ -z "$RID" ]; then
RID=$(curl -sf -X POST -H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
"$API/repos/$REPO/releases" \
-d "$(jq -nc --arg t "$TAG" '{tag_name:$t,name:$t,draft:false,prerelease:false,hide_archive_links:true}')" \
| jq -r '.id')
fi
echo "release id: $RID"
# Gitea honors hide_archive_links only on edit, not create — PATCH it
# so the auto-generated Source Code (zip/tar.gz) links stay hidden.
curl -sf -X PATCH -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" \
"$API/repos/$REPO/releases/$RID" -d '{"hide_archive_links":true}' >/dev/null || true
# Upload every dist/*.zip. Per-asset failures don't fail the job —
# we want partial releases to still publish rather than block the
# whole pipeline on one big file.
failed=0
uploaded=0
for f in dist/*.zip; do
name=$(basename "$f")
size=$(stat -c '%s' "$f")
if [ "$size" -gt "$MAX_BYTES" ]; then
echo "::warning::skip $name (${size} B > ${MAX_BYTES} B Gitea limit; host on CDN instead)"
failed=$((failed+1))
continue
fi
echo "uploading $name ($(numfmt --to=iec "$size"))"
if curl -sf -X POST -H "Authorization: token $GITEA_TOKEN" \
-F "attachment=@$f" \
"$API/repos/$REPO/releases/$RID/assets?name=$name" \
| jq -r '" -> " + .browser_download_url'; then
uploaded=$((uploaded+1))
else
echo "::warning::upload failed for $name"
failed=$((failed+1))
fi
done
echo "release published: $uploaded uploaded, $failed skipped/failed"
# Only fail the job if NO assets uploaded — a release with zero
# attachments isn't useful to anyone.
[ "$uploaded" -gt 0 ]

14
.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1,14 @@
# These are supported funding model platforms
github: [NoM0Re] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: https://streamelements.com/nom0ree/tip

123
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View file

@ -0,0 +1,123 @@
name: "Bug Report"
description: Create a report to help us improve
labels: ['🐛 Bug']
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please [search for existing issues](https://github.com/Ascension-Addons/WeakAuras-Ascension/issues) to see if an open or closed one already exists for the bug you encountered. If a bug exists and it is closed as complete it may not yet be in a stable release.
options:
- label: I have searched the existing open and closed issues.
required: true
- type: textarea
attributes:
label: Description
description: What did you expect to happen and what happened instead?
validations:
required: true
- type: input
attributes:
label: WeakAuras Version
description: |
You can see the current version in the title bar of the options window, if the options do not open, check the `## Version:` field in the WeakAuras.toc file.
placeholder: "WeakAuras 5.0.0"
validations:
required: true
- type: dropdown
id: flavor
attributes:
label: World of Warcraft Flavor
description: What version of World of Warcraft are are you running?
options:
- WotLK 3.3.5a
validations:
required: true
- type: dropdown
id: language
attributes:
label: World of Warcraft Language
description: In which language do you play World of Warcraft?
options:
- enGB/enUS
- deDE
- frFR
- itIT
- esES
- esMX
- koKR
- ptBR
- ruRU
- zhCN
- zhTW
validations:
required: true
- type: input
id: server
attributes:
label: Server
description: On which server/realm are you playing?
placeholder: Warmane-Icecrown
validations:
required: true
- type: checkboxes
id: testing
attributes:
label: Tested with only WeakAuras
description: Sometimes, other addons can interfere with WeakAuras. We recommend testing with only WeakAuras enabled to see if the issue persists.
options:
- label: I got this issue with only WeakAuras enabled
required: true
- type: textarea
attributes:
label: Lua Error
description: |
Do you have an error log of what happened? If you don't see any errors, make sure that error reporting is enabled (`/console scriptErrors 1`) or install [BugSack](https://www.curseforge.com/wow/addons/bugsack) & [BugGrabber](https://www.curseforge.com/wow/addons/bug-grabber), yes both are needed.
Note that if the error looks like `[string "--[[ Error in ' my awesome aura' ]` then the bug is in the aura that got mentioned, not in WeakAuras itself.
render: Text
validations:
required: false
- type: textarea
attributes:
label: Reproduction Steps
description: Please list out the steps to reproduce your bug. Please verify that your reproduction steps are enough to reproduce the problem.
placeholder: |
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
validations:
required: true
- type: input
attributes:
label: Last Good Version
description: |
Was it working in a previous version? If yes, which was the last good one?
placeholder: "WeakAuras 5.0.0"
validations:
required: false
- type: textarea
attributes:
label: Screenshots
description: If applicable, add screenshots to help explain your problem.
placeholder: Click here to attach your screenshots via the editor button in the top right.
validations:
required: false
- type: textarea
attributes:
label: Export String
description: If you do not know which aura is causing issues for you, please attach a ZIP archive of your WeakAuras SavedVariables file, it's the `WeakAuras.lua` file in `World of Warcraft\_retail_\WTF\Account\YOUR_ACCOUNT\SavedVariables\`. In case you do, please export the string and paste it below.
placeholder: Paste your exported WeakAuras string here.
render: Text
validations:
required: false

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View file

@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Question
url: https://discord.gg/classlesswow
about: Please ask and answer questions here.

View file

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: "\U0001F3A8 Feature Request"
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

115
.github/workflows/autoclose.yaml vendored Normal file
View file

@ -0,0 +1,115 @@
name: Autoclose after 2 days
on:
schedule:
- cron: '0 0 * * *'
issues:
types: [labeled]
pull_request:
types: [labeled]
permissions:
issues: write
pull-requests: write
jobs:
autoclose:
runs-on: ubuntu-latest
steps:
- name: Close Issues/PRs labeled 'Auto Close' after 2 days, if label set by collaborator and no recent comments
uses: actions/github-script@v7
with:
script: |
const { owner, repo } = context.repo;
const labelName = '⏳Auto Close';
const maxAgeDays = 2;
const now = new Date();
const issues = await github.paginate(github.rest.issues.listForRepo, {
owner,
repo,
labels: labelName,
state: 'open',
per_page: 100,
});
for (const issue of issues) {
const issue_number = issue.number;
const events = await github.paginate(github.rest.issues.listEventsForTimeline, {
owner,
repo,
issue_number,
per_page: 100,
});
const labelEvent = events.find(event =>
event.event === 'labeled' &&
event.label?.name === labelName
);
if (!labelEvent) continue;
let labelDate = new Date(labelEvent.created_at);
const comments = await github.paginate(
issue.pull_request
? github.rest.pulls.listReviewComments
: github.rest.issues.listComments,
{
owner,
repo,
issue_number,
per_page: 100,
}
);
const recentCommentsAfterLabel = comments
.filter(c => new Date(c.created_at) > labelDate);
let latestDate = labelDate;
if (recentCommentsAfterLabel.length > 0) {
latestDate = new Date(Math.max(...recentCommentsAfterLabel.map(c => new Date(c.created_at).getTime())));
}
const diffDays = (now - latestDate) / (1000 * 60 * 60 * 24);
if (diffDays < maxAgeDays) continue;
const actor = labelEvent.actor?.login;
if (!actor) continue;
try {
await github.rest.repos.checkCollaborator({
owner,
repo,
username: actor,
});
} catch (error) {
if (error.status === 404) {
await github.rest.issues.removeLabel({
owner,
repo,
issue_number,
name: labelName,
});
continue;
} else {
throw error;
}
}
await github.rest.issues.update({
owner,
repo,
issue_number,
state: 'closed',
});
await github.rest.issues.removeLabel({
owner,
repo,
issue_number,
name: labelName,
});
}

62
.github/workflows/lint-pr.yml vendored Normal file
View file

@ -0,0 +1,62 @@
name: lint
on:
pull_request:
paths:
- '**.lua'
jobs:
lint:
runs-on: ubuntu-latest
env:
LUA_VERSION: 5.1.5
LUAROCKS_VERSION: 3.11.1
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Cache Lua
uses: actions/cache@v3
id: luacache
with:
path: .lua
key: ${{ runner.os }}-lua-${{ env.LUA_VERSION }}
restore-keys: |
${{ runner.os }}-lua-${{ env.LUA_VERSION }}
- name: Cache LuaRocks
uses: actions/cache@v3
id: luarockscache
with:
path: .luarocks
key: ${{ runner.os }}-luarocks-${{ env.LUAROCKS_VERSION }}
restore-keys: |
${{ runner.os }}-luarocks-${{ env.LUAROCKS_VERSION }}
- name: Install Lua
if: steps.luacache.outputs.cache-hit != 'true'
run: |
sudo apt-get install libreadline-dev libncurses-dev
wget https://www.lua.org/ftp/lua-${{ env.LUA_VERSION }}.tar.gz -O - | tar -xzf -
cd lua-${{ env.LUA_VERSION }}
make linux
make -j INSTALL_TOP=$GITHUB_WORKSPACE/.lua install
rm -rf $GITHUB_WORKSPACE/lua-${{ env.LUA_VERSION }}
- name: Install LuaRocks and Luacheck
if: steps.luarockscache.outputs.cache-hit != 'true'
run: |
wget https://luarocks.org/releases/luarocks-${{ env.LUAROCKS_VERSION }}.tar.gz -O - | tar -xzf -
cd luarocks-${{ env.LUAROCKS_VERSION }}
./configure --with-lua-bin=$GITHUB_WORKSPACE/.lua/bin --prefix=$GITHUB_WORKSPACE/.luarocks
make build
make install
PATH=$PATH:$GITHUB_WORKSPACE/.luarocks/bin
luarocks install luacheck
luarocks install lanes
rm -rf $GITHUB_WORKSPACE/luarocks-${{ env.LUAROCKS_VERSION }}
- name: Luacheck
run: .luarocks/bin/luacheck . -q

66
.github/workflows/lint.yml vendored Normal file
View file

@ -0,0 +1,66 @@
name: lint
on:
push:
paths:
- '.github/workflows/**.yml'
- '**.lua'
pull_request:
paths:
- '**.lua'
jobs:
lint:
runs-on: ubuntu-latest
env:
LUA_VERSION: 5.1.5
LUAROCKS_VERSION: 3.11.1
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Cache Lua
uses: actions/cache@v3
id: luacache
with:
path: .lua
key: ${{ runner.os }}-lua-${{ env.LUA_VERSION }}
restore-keys: |
${{ runner.os }}-lua-${{ env.LUA_VERSION }}
- name: Cache LuaRocks
uses: actions/cache@v3
id: luarockscache
with:
path: .luarocks
key: ${{ runner.os }}-luarocks-${{ env.LUAROCKS_VERSION }}
restore-keys: |
${{ runner.os }}-luarocks-${{ env.LUAROCKS_VERSION }}
- name: Install Lua
if: steps.luacache.outputs.cache-hit != 'true'
run: |
sudo apt-get install libreadline-dev libncurses-dev
wget https://www.lua.org/ftp/lua-${{ env.LUA_VERSION }}.tar.gz -O - | tar -xzf -
cd lua-${{ env.LUA_VERSION }}
make linux
make -j INSTALL_TOP=$GITHUB_WORKSPACE/.lua install
rm -rf $GITHUB_WORKSPACE/lua-${{ env.LUA_VERSION }}
- name: Install LuaRocks and Luacheck
if: steps.luarockscache.outputs.cache-hit != 'true'
run: |
wget https://luarocks.org/releases/luarocks-${{ env.LUAROCKS_VERSION }}.tar.gz -O - | tar -xzf -
cd luarocks-${{ env.LUAROCKS_VERSION }}
./configure --with-lua-bin=$GITHUB_WORKSPACE/.lua/bin --prefix=$GITHUB_WORKSPACE/.luarocks
make build
make install
PATH=$PATH:$GITHUB_WORKSPACE/.luarocks/bin
luarocks install luacheck
luarocks install lanes
rm -rf $GITHUB_WORKSPACE/luarocks-${{ env.LUAROCKS_VERSION }}
- name: Luacheck
run: .luarocks/bin/luacheck .

3
.gitignore vendored
View file

@ -1,4 +1 @@
.idea
.idea
dist/

View file

@ -9,7 +9,7 @@ WeakAuras.halfWidth = WeakAuras.normalWidth / 2
WeakAuras.doubleWidth = WeakAuras.normalWidth * 2
local versionStringFromToc = GetAddOnMetadata("WeakAuras", "Version")
local versionString = "5.22.0 Beta"
local versionString = "5.21.2 Beta"
-- Year, Month, Day, Hour, Minute, Seconds
local buildTime = "2025".."11".."29".."04".."45".."00"
local isTTSEnabled = C_VoiceChat and C_VoiceChat.SpeakText and true or false

View file

@ -1187,16 +1187,6 @@ WeakAuras.class_types = {}
for i, class in ipairs(CLASS_SORT_ORDER) do
WeakAuras.class_types[class] = WrapTextInColorCode(LOCALIZED_CLASS_NAMES_MALE[class], WA_GetClassColor(class))
end
-- CoA: CLASS_SORT_ORDER only contains the 11 vanilla classes, missing the 21
-- custom CoA classes. Fall back to LOCALIZED_CLASS_NAMES_MALE for anything not
-- yet registered. Same pattern used by the spec builder further down this file.
if LOCALIZED_CLASS_NAMES_MALE then
for class in pairs(LOCALIZED_CLASS_NAMES_MALE) do
if not WeakAuras.class_types[class] then
WeakAuras.class_types[class] = WrapTextInColorCode(LOCALIZED_CLASS_NAMES_MALE[class], WA_GetClassColor(class))
end
end
end
if WeakAuras.IsClassicPlus() then
WeakAuras.class_types["DEATHKNIGHT"] = nil
end
@ -3842,28 +3832,6 @@ do
end
table.sort(classOrder)
end
else
-- CoA: CLASS_SORT_ORDER only contains the 11 vanilla classes. Append any
-- keys present in LOCALIZED_CLASS_NAMES_MALE that are not already in the
-- list (custom classes such as Witchdoctor, Templar, etc.). Build a fresh
-- local copy — do NOT mutate the global CLASS_SORT_ORDER.
if LOCALIZED_CLASS_NAMES_MALE then
local inOrder = {}
for _, class in ipairs(classOrder) do
inOrder[class] = true
end
classOrder = {unpack(classOrder)}
local extra = {}
for class in pairs(LOCALIZED_CLASS_NAMES_MALE) do
if not inOrder[class] then
extra[#extra + 1] = class
end
end
table.sort(extra)
for _, class in ipairs(extra) do
classOrder[#classOrder + 1] = class
end
end
end
if C_ClassInfo and C_ClassInfo.GetAllSpecs and C_ClassInfo.GetSpecInfo then
@ -3871,10 +3839,7 @@ do
local specs = C_ClassInfo.GetAllSpecs(class)
if specs then
for _, spec in ipairs(specs) do
local ok, info = pcall(C_ClassInfo.GetSpecInfo, class, spec)
if ok and info then
addSpec(class, info)
end
addSpec(class, C_ClassInfo.GetSpecInfo(class, spec))
end
end
end

View file

@ -1304,16 +1304,8 @@ loadedFrame:SetScript("OnEvent", function(self, event, ...)
if dbIsValid then
Private.Login(takeNewSnapshots)
else
-- db isn't valid. Request permission to run repair tool before logging in.
-- CoA: defer the StaticPopup_Show by one frame so it fires after the
-- PLAYER_LOGIN event-frame stack has unwound. On the CoA reworked
-- StaticPopup system, firing this synchronously during PLAYER_LOGIN
-- silently fails to show the popup, which means Private.Login() is
-- never invoked, no auras load, and the next logout writes an empty
-- WeakAurasSaved over the user's profile.
C_Timer.After(0, function()
StaticPopup_Show("WEAKAURAS_CONFIRM_REPAIR", nil, nil, {reason = "downgrade"})
end)
-- db isn't valid. Request permission to run repair tool before logging in
StaticPopup_Show("WEAKAURAS_CONFIRM_REPAIR", nil, nil, {reason = "downgrade"})
end
elseif event == "PLAYER_LOGOUT" then
for id in pairs(db.displays) do
@ -2272,25 +2264,14 @@ StaticPopupDialogs["WEAKAURAS_CONFIRM_REPAIR"] = {
local AutomaticRepairText = L["WeakAuras has detected that it has been downgraded.\nYour saved auras may no longer work properly.\nWould you like to run the |cffff0000EXPERIMENTAL|r repair tool? This will overwrite any changes you have made since the last database upgrade.\nLast upgrade: %s\n\n|cffff0000You should BACKUP your WTF folder BEFORE pressing this button.|r"]
local ManualRepairText = L["Are you sure you want to run the |cffff0000EXPERIMENTAL|r repair tool?\nThis will overwrite any changes you have made since the last database upgrade.\nLast upgrade: %s"]
-- CoA: guard against malformed data; default reason to "unknown" so the
-- popup can't error out and block Private.Login() from ever running.
local reason = "unknown"
if self.data then
reason = self.data.reason or "unknown"
end
if reason == "user" then
if self.data.reason == "user" then
self.text:SetText(ManualRepairText:format(LastUpgrade()))
else
self.text:SetText(AutomaticRepairText:format(LastUpgrade()))
end
end,
OnCancel = function(self)
local reason = "unknown"
if self.data then
reason = self.data.reason or "unknown"
end
if reason ~= "user" then
if self.data.reason ~= "user" then
Private.Login()
end
end,

View file

@ -1,71 +0,0 @@
#!/usr/bin/env bash
# Build per-addon zip artefacts from HEAD via git-archive.
#
# - Discovers top-level addon folders (Foo/Foo.toc).
# - Re-creates dist/ each run.
# - Always archives HEAD, so the working tree state is irrelevant.
# - If more than one addon folder is present, also emits <repo>-all.zip
# with every addon folder side-by-side at the zip root.
# - When run inside Gitea Actions the working tree lives under a
# per-job dir like /var/lib/act_runner/work/.../hostexecutor, so the
# repo name comes from $GITHUB_REPOSITORY (set by the runner) and
# only falls back to the toplevel basename for local invocations.
set -euo pipefail
root=$(git rev-parse --show-toplevel)
cd "$root"
# Gitea Actions sets GITHUB_REPOSITORY=owner/repo. The basename of
# `git rev-parse --show-toplevel` inside the runner is the worker dir
# (e.g. `hostexecutor`), which would name the bundle wrong.
if [ -n "${GITHUB_REPOSITORY:-}" ]; then
repo_name="${GITHUB_REPOSITORY##*/}"
else
repo_name=$(basename "$root")
fi
dist="$root/dist"
# Find Foo/Foo.toc pairs at depth 1; ignore libs nested deeper.
addons=()
while IFS= read -r toc; do
dir=$(dirname "$toc")
folder=$(basename "$dir")
base=$(basename "$toc" .toc)
# Accept Foo.toc and Foo_Wrath.toc style flavour variants; folder must match
# at least one toc basename prefix (Foo).
case "$base" in
"$folder"|"$folder"_*) addons+=("$folder") ;;
esac
done < <(command find . -mindepth 2 -maxdepth 2 -type f -name '*.toc' | sed 's|^\./||' | sort)
# Dedupe (a folder with Foo.toc + Foo_Wrath.toc shows up twice).
if [ ${#addons[@]} -gt 0 ]; then
mapfile -t addons < <(printf '%s\n' "${addons[@]}" | awk '!seen[$0]++')
fi
if [ ${#addons[@]} -eq 0 ]; then
echo "no addon folders found (looking for */Foo.toc with matching folder name)" >&2
exit 1
fi
rm -rf "$dist"
mkdir -p "$dist"
for folder in "${addons[@]}"; do
out="$dist/$folder.zip"
# No --prefix: the folder already sits at the repo root, so git-archive
# emits entries as <folder>/... which is exactly what
# Interface/AddOns/ expects after extraction.
git archive HEAD --format=zip -o "$out" -- "$folder"
echo "built dist/$folder.zip"
done
# Combined bundle only makes sense when there are multiple addons.
if [ ${#addons[@]} -gt 1 ]; then
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT
git archive HEAD --format=tar -- "${addons[@]}" | tar -x -C "$tmp"
out="$dist/$repo_name-all.zip"
( cd "$tmp" && zip -qr "$out" "${addons[@]}" )
echo "built dist/$repo_name-all.zip"
fi