@@ -26,6 +26,168 @@ jobs:
2626 with :
2727 do-test : ${{ github.base_ref == github.event.repository.default_branch || github.ref_name == github.event.repository.default_branch }}
2828
29+ spec-test-selection :
30+ runs-on : ubuntu-22.04
31+ if : github.base_ref == github.event.repository.default_branch || github.ref_name == github.event.repository.default_branch
32+ outputs :
33+ spec-matrix : ${{ steps.select.outputs.spec-matrix }}
34+ steps :
35+ - uses : actions/checkout@v6
36+ with :
37+ fetch-depth : 2
38+
39+ - name : Select Specs From Changed Files
40+ id : select
41+ shell : bash
42+ run : |
43+ set -euo pipefail
44+
45+ ALL_SPECS=(
46+ deathknight_blood
47+ deathknight_unholy
48+ deathknight_frost
49+ demonhunter_devourer
50+ demonhunter_havoc
51+ demonhunter_vengeance
52+ druid_balance
53+ druid_feral
54+ druid_guardian
55+ druid_restoration
56+ evoker_devastation
57+ evoker_augmentation
58+ hunter_beast_mastery
59+ hunter_marksmanship
60+ hunter_survival
61+ mage_arcane
62+ mage_fire
63+ mage_frost
64+ monk_brewmaster
65+ monk_windwalker
66+ paladin_protection
67+ paladin_retribution
68+ priest_shadow
69+ rogue_assassination
70+ rogue_outlaw
71+ rogue_subtlety
72+ shaman_elemental
73+ shaman_enhancement
74+ warlock_affliction
75+ warlock_demonology
76+ warlock_destruction
77+ warrior_arms
78+ warrior_fury
79+ warrior_protection
80+ )
81+
82+ if [[ "${GITHUB_EVENT_NAME}" == "pull_request" ]]; then
83+ BASE_SHA="${{ github.event.pull_request.base.sha }}"
84+ HEAD_SHA="${{ github.event.pull_request.head.sha }}"
85+ else
86+ BASE_SHA="${{ github.event.before }}"
87+ HEAD_SHA="${{ github.sha }}"
88+ fi
89+
90+ mapfile -t CHANGED_FILES < <(git diff --name-only "$BASE_SHA" "$HEAD_SHA")
91+
92+ echo "Changed files:"
93+ printf ' - %s\n' "${CHANGED_FILES[@]}"
94+
95+ declare -A CLASS_CHANGED
96+ CLASS_CHANGED_COUNT=0
97+ RUN_ALL=0
98+
99+ mark_class_changed() {
100+ local class_key="$1"
101+ if [[ -z "${CLASS_CHANGED[$class_key]:-}" ]]; then
102+ CLASS_CHANGED[$class_key]=1
103+ CLASS_CHANGED_COUNT=$((CLASS_CHANGED_COUNT + 1))
104+ fi
105+ }
106+
107+ add_class_from_file() {
108+ local file="$1"
109+
110+ case "$file" in
111+ engine/class_modules/sc_death_knight.cpp|engine/class_modules/apl/apl_death_knight.*)
112+ mark_class_changed deathknight
113+ ;;
114+ engine/class_modules/sc_demon_hunter.cpp|engine/class_modules/apl/apl_demon_hunter.*|engine/class_modules/apl/demon_hunter/*)
115+ mark_class_changed demonhunter
116+ ;;
117+ engine/class_modules/sc_druid.cpp|engine/class_modules/apl/druid/*)
118+ mark_class_changed druid
119+ ;;
120+ engine/class_modules/sc_evoker.cpp|engine/class_modules/apl/apl_evoker.*)
121+ mark_class_changed evoker
122+ ;;
123+ engine/class_modules/sc_hunter.cpp|engine/class_modules/apl/apl_hunter.*)
124+ mark_class_changed hunter
125+ ;;
126+ engine/class_modules/sc_mage.cpp|engine/class_modules/apl/mage.*)
127+ mark_class_changed mage
128+ ;;
129+ engine/class_modules/monk/*|engine/class_modules/apl/apl_monk.*)
130+ mark_class_changed monk
131+ ;;
132+ engine/class_modules/paladin/*|engine/class_modules/apl/apl_paladin.*)
133+ mark_class_changed paladin
134+ ;;
135+ engine/class_modules/priest/*|engine/class_modules/apl/apl_priest.*)
136+ mark_class_changed priest
137+ ;;
138+ engine/class_modules/sc_rogue.cpp|engine/class_modules/apl/apl_rogue.*)
139+ mark_class_changed rogue
140+ ;;
141+ engine/class_modules/sc_shaman.cpp|engine/class_modules/apl/apl_shaman.*|engine/class_modules/apl/shaman/*)
142+ mark_class_changed shaman
143+ ;;
144+ engine/class_modules/warlock/*|engine/class_modules/apl/warlock.*)
145+ mark_class_changed warlock
146+ ;;
147+ engine/class_modules/sc_warrior.cpp|engine/class_modules/apl/apl_warrior.*)
148+ mark_class_changed warrior
149+ ;;
150+ *)
151+ RUN_ALL=1
152+ ;;
153+ esac
154+ }
155+
156+ if (( ${#CHANGED_FILES[@]} == 0 )); then
157+ RUN_ALL=1
158+ elif (( RUN_ALL == 0 )); then
159+ for file in "${CHANGED_FILES[@]}"; do
160+ add_class_from_file "$file"
161+ if (( RUN_ALL == 1 )); then
162+ break
163+ fi
164+ done
165+ fi
166+
167+ if (( RUN_ALL == 1 || CLASS_CHANGED_COUNT == 0 )); then
168+ SELECTED_SPECS=("${ALL_SPECS[@]}")
169+ else
170+ SELECTED_SPECS=()
171+ for spec in "${ALL_SPECS[@]}"; do
172+ class_key="${spec%%_*}"
173+ if [[ -n "${CLASS_CHANGED[$class_key]:-}" ]]; then
174+ SELECTED_SPECS+=("$spec")
175+ fi
176+ done
177+ fi
178+
179+ SPEC_JSON="["
180+ for spec in "${SELECTED_SPECS[@]}"; do
181+ if [[ "$SPEC_JSON" != "[" ]]; then
182+ SPEC_JSON+=","
183+ fi
184+ SPEC_JSON+="\"$spec\""
185+ done
186+ SPEC_JSON+="]"
187+
188+ echo "spec-matrix=$SPEC_JSON" >> "$GITHUB_OUTPUT"
189+ echo "Selected spec matrix: $SPEC_JSON"
190+
29191 environment-configuration-info :
30192 runs-on : ubuntu-22.04
31193 steps :
@@ -34,20 +196,22 @@ jobs:
34196 echo "${{github.event.repository.default_branch}} ${{github.ref}} ${{github.ref_name}} ${{github.base_ref}} ${{github.head_ref}} ${{github.sha}}"
35197
36198 spec-test :
37- needs : [build]
199+ needs : [build, spec-test-selection ]
38200 if : github.base_ref == github.event.repository.default_branch || github.ref_name == github.event.repository.default_branch
39201 uses : ./.github/workflows/spec_test.yml
40202 with :
41203 cache-key : ubuntu-clang++-15-for_run-${{ github.sha }}-cpp-17
42204 is-ptr : false
205+ spec-matrix : ${{ needs.spec-test-selection.outputs.spec-matrix }}
43206
44207 spec-test-ptr :
45- needs : [build]
208+ needs : [build, spec-test-selection ]
46209 if : github.base_ref == github.event.repository.default_branch || github.ref_name == github.event.repository.default_branch
47210 uses : ./.github/workflows/spec_test.yml
48211 with :
49212 cache-key : ubuntu-clang++-15-for_run-${{ github.sha }}-cpp-17
50213 is-ptr : true
214+ spec-matrix : ${{ needs.spec-test-selection.outputs.spec-matrix }}
51215
52216 ubuntu-test :
53217 needs : [build]
0 commit comments