1+ name : ABI Compliance Check
2+
3+ on :
4+ pull_request :
5+ branches :
6+ - develop
7+ paths :
8+ - ' projects/amdsmi/include/amd_smi/amdsmi.h'
9+ push :
10+ branches :
11+ - develop
12+ paths :
13+ - ' projects/amdsmi/include/amd_smi/amdsmi.h'
14+ workflow_dispatch :
15+
16+ permissions :
17+ contents : read
18+ pull-requests : write
19+
20+ jobs :
21+ major_abi_check :
22+ name : Major ABI Compliance Check
23+ runs-on : ubuntu-22.04
24+ steps :
25+ - name : Setup Environment
26+ run : |
27+ sudo rm -rf $GITHUB_WORKSPACE/* || true
28+ sudo rm -rf $GITHUB_WORKSPACE/.[!.]* || true
29+ sudo apt-get update -qq
30+ sudo apt-get install -y -qq perl build-essential git universal-ctags
31+ git clone https://github.com/lvc/abi-compliance-checker.git
32+ cd abi-compliance-checker
33+ sudo make install
34+ abi-compliance-checker --version
35+
36+ - name : Checkout current code (new version)
37+ uses : actions/checkout@v4
38+ with :
39+ fetch-depth : 0
40+ ref : ${{ github.event.pull_request.head.sha || github.sha }}
41+
42+ - name : Fetch base branch for PR
43+ if : github.event_name == 'pull_request'
44+ run : |
45+ echo "Fetching base branch: ${{ github.base_ref }}"
46+ git fetch origin ${{ github.base_ref }}:${{ github.base_ref }}
47+ git branch -a
48+
49+ - name : Prepare amdsmi.h files for comparison
50+ id : prepare_files
51+ run : |
52+ echo "Preparing amdsmi.h files..."
53+ echo "abi_exit_code=1" > $GITHUB_WORKSPACE/major_abi_status.txt
54+
55+ if [ -f include/amd_smi/amdsmi.h ]; then
56+ cp include/amd_smi/amdsmi.h amdsmi_new.h
57+ echo "Copied current amdsmi.h to amdsmi_new.h"
58+ else
59+ echo "::error::New amdsmi.h (include/amd_smi/amdsmi.h) not found in current checkout."
60+ touch amdsmi_new.h
61+ exit 0
62+ fi
63+
64+ OLD_VERSION_REF=""
65+ V1_NAME_SUFFIX=""
66+ if [[ "${{ github.event_name }}" == "pull_request" ]]; then
67+ OLD_VERSION_REF="${{ github.base_ref }}"
68+ V1_NAME_SUFFIX="base_${{ github.base_ref }}"
69+ echo "Event is Pull Request. Old version source is base branch: ${OLD_VERSION_REF}"
70+ elif [[ "${{ github.event_name }}" == "push" ]]; then
71+ if [[ "${{ github.event.before }}" != "0000000000000000000000000000000000000000" ]]; then
72+ OLD_VERSION_REF="${{ github.event.before }}"
73+ V1_NAME_SUFFIX="before_$(echo ${{ github.event.before }} | cut -c1-7)"
74+ echo "Event is Push. Old version source is commit before push: ${OLD_VERSION_REF}"
75+ else
76+ echo "Push event is for a new branch or forced push. Cannot determine 'old' version."
77+ touch amdsmi_old.h
78+ echo "Created dummy amdsmi_old.h. Assuming no ABI breakage as no baseline."
79+ echo "abi_exit_code=0" > $GITHUB_WORKSPACE/major_abi_status.txt
80+ echo "skip_check=true" >> $GITHUB_OUTPUT
81+ exit 0
82+ fi
83+ else
84+ echo "::warning::Unsupported event type: ${{ github.event_name }}. Cannot determine old version."
85+ touch amdsmi_old.h
86+ echo "abi_exit_code=0" > $GITHUB_WORKSPACE/major_abi_status.txt
87+ echo "skip_check=true" >> $GITHUB_OUTPUT
88+ exit 0
89+ fi
90+
91+ echo "Fetching amdsmi.h from ref: $OLD_VERSION_REF (as amdsmi_old.h)"
92+ git show $OLD_VERSION_REF:include/amd_smi/amdsmi.h > amdsmi_old.h 2>/dev/null
93+ if [ $? -ne 0 ] || [ ! -s amdsmi_old.h ]; then
94+ echo "::warning::Failed to fetch 'include/amd_smi/amdsmi.h' from ref '$OLD_VERSION_REF' or file is empty/missing."
95+ echo "Proceeding with an empty amdsmi_old.h. This may result in all symbols reported as 'added'."
96+ echo -n "" > amdsmi_old.h
97+ if [ ! -s amdsmi_new.h ]; then
98+ echo "abi_exit_code=0" > $GITHUB_WORKSPACE/major_abi_status.txt
99+ fi
100+ else
101+ echo "Successfully fetched amdsmi.h from $OLD_VERSION_REF to amdsmi_old.h"
102+ fi
103+ echo "v1_name_suffix=${V1_NAME_SUFFIX}" >> $GITHUB_OUTPUT
104+ echo "skip_check=false" >> $GITHUB_OUTPUT
105+
106+ - name : Run Major ABI Compliance Check
107+ if : steps.prepare_files.outputs.skip_check == 'false'
108+ run : |
109+ V1_NAME_SUFFIX_CLEAN=$(echo "${{ steps.prepare_files.outputs.v1_name_suffix }}" | tr '/' '-')
110+ V2_NAME_CLEAN=$(echo "${{ github.ref_name || github.head_ref }}" | tr '/' '-')
111+
112+ echo "Comparing $V1_NAME_SUFFIX_CLEAN (old) with $V2_NAME_CLEAN (new) for Major ABI Check"
113+ abi-compliance-checker -lib amdsmi -old amdsmi_old.h -new amdsmi_new.h -v1 "$V1_NAME_SUFFIX_CLEAN" -v2 "$V2_NAME_CLEAN" -report-path major-abi-report.html && echo "abi_exit_code=0" > $GITHUB_WORKSPACE/major_abi_status.txt
114+ continue-on-error : true
115+
116+ - name : Display ABI Check Logs (Major)
117+ if : always() && steps.prepare_files.outputs.skip_check == 'false'
118+ run : |
119+ echo "Displaying Major ABI compliance check logs (if any)"
120+ find logs -type f -name "*.txt" -exec echo "--- {} ---" \; -exec cat {} \; || echo "No .txt logs found in logs/ directory."
121+
122+ - name : Label PR on Major ABI Breakage
123+ if : always() && github.event_name == 'pull_request'
124+ run : |
125+ source $GITHUB_WORKSPACE/major_abi_status.txt
126+ if [ "$abi_exit_code" -ne 0 ]; then
127+ echo "Major ABI check failed, adding 'MAJOR ABI BREAKAGE' label to PR #${{ github.event.pull_request.number }}"
128+ gh pr edit ${{ github.event.pull_request.number }} --add-label "MAJOR ABI BREAKAGE"
129+ fi
130+ env :
131+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
132+
133+ - name : Upload Major ABI Report
134+ if : always()
135+ uses : actions/upload-artifact@v4
136+ with :
137+ name : major-abi-report
138+ path : major-abi-report.html
139+ if-no-files-found : ignore
140+
141+ - name : Report Major ABI Check Results
142+ if : always()
143+ run : |
144+ echo "Checking Major ABI check exit code..."
145+ source $GITHUB_WORKSPACE/major_abi_status.txt
146+ echo "Major ABI check exit code: $abi_exit_code"
147+ if [ "$abi_exit_code" -ne 0 ]; then
148+ echo "::warning::⚠️ MAJOR ABI BREAKAGE FOUND ⚠️ CHECK \"Run Major ABI Compliance Check\" LOGS OR THE major-abi-report ARTIFACT FOR DETAILS."
149+ else
150+ echo "✅ Major ABI check succeeded."
151+ fi
152+
153+ minor_abi_check :
154+ name : Minor ABI Compliance Check
155+ runs-on : ubuntu-22.04
156+ steps :
157+ - name : Setup Environment
158+ run : |
159+ sudo rm -rf $GITHUB_WORKSPACE/* || true
160+ sudo rm -rf $GITHUB_WORKSPACE/.[!.]* || true
161+ sudo apt-get update -qq
162+ sudo apt-get install -y -qq perl build-essential git universal-ctags
163+ git clone https://github.com/lvc/abi-compliance-checker.git
164+ cd abi-compliance-checker
165+ sudo make install
166+ abi-compliance-checker --version
167+
168+ - name : Checkout current code (new version)
169+ uses : actions/checkout@v4
170+ with :
171+ fetch-depth : 0
172+ ref : ${{ github.event.pull_request.head.sha || github.sha }}
173+
174+ - name : Fetch base branch for PR
175+ if : github.event_name == 'pull_request'
176+ run : |
177+ echo "Fetching base branch: ${{ github.base_ref }}"
178+ git fetch origin ${{ github.base_ref }}:${{ github.base_ref }}
179+ git branch -a
180+
181+ - name : Prepare amdsmi.h files for comparison
182+ id : prepare_files_minor
183+ run : |
184+ echo "Preparing amdsmi.h files for Minor check..."
185+ echo "abi_exit_code=1" > $GITHUB_WORKSPACE/minor_abi_status.txt
186+
187+ if [ -f include/amd_smi/amdsmi.h ]; then
188+ cp include/amd_smi/amdsmi.h amdsmi_new.h
189+ echo "Copied current amdsmi.h to amdsmi_new.h for Minor check"
190+ else
191+ echo "::error::New amdsmi.h (include/amd_smi/amdsmi.h) not found in current checkout for Minor check."
192+ touch amdsmi_new.h
193+ exit 0
194+ fi
195+
196+ OLD_VERSION_REF_MINOR=""
197+ V1_NAME_SUFFIX_MINOR=""
198+ if [[ "${{ github.event_name }}" == "pull_request" ]]; then
199+ OLD_VERSION_REF_MINOR="${{ github.base_ref }}"
200+ V1_NAME_SUFFIX_MINOR="base_${{ github.base_ref }}"
201+ elif [[ "${{ github.event_name }}" == "push" ]]; then
202+ if [[ "${{ github.event.before }}" != "0000000000000000000000000000000000000000" ]]; then
203+ OLD_VERSION_REF_MINOR="${{ github.event.before }}"
204+ V1_NAME_SUFFIX_MINOR="before_$(echo ${{ github.event.before }} | cut -c1-7)"
205+ else
206+ echo "Push event is for a new branch (Minor check). Assuming no ABI changes as no baseline."
207+ touch amdsmi_old.h
208+ echo "abi_exit_code=0" > $GITHUB_WORKSPACE/minor_abi_status.txt
209+ echo "skip_check_minor=true" >> $GITHUB_OUTPUT
210+ exit 0
211+ fi
212+ else
213+ echo "::warning::Unsupported event type for Minor ABI check: ${{ github.event_name }}."
214+ touch amdsmi_old.h
215+ echo "abi_exit_code=0" > $GITHUB_WORKSPACE/minor_abi_status.txt
216+ echo "skip_check_minor=true" >> $GITHUB_OUTPUT
217+ exit 0
218+ fi
219+
220+ echo "Fetching amdsmi.h from ref: $OLD_VERSION_REF_MINOR (as amdsmi_old.h) for Minor check"
221+ git show $OLD_VERSION_REF_MINOR:include/amd_smi/amdsmi.h > amdsmi_old.h 2>/dev/null
222+ if [ $? -ne 0 ] || [ ! -s amdsmi_old.h ]; then
223+ echo "::warning::Failed to fetch 'include/amd_smi/amdsmi.h' from ref '$OLD_VERSION_REF_MINOR' or file is empty/missing for Minor check."
224+ echo "Proceeding with an empty amdsmi_old.h for Minor check."
225+ echo -n "" > amdsmi_old.h
226+ if [ ! -s amdsmi_new.h ]; then
227+ echo "abi_exit_code=0" > $GITHUB_WORKSPACE/minor_abi_status.txt
228+ fi
229+ else
230+ echo "Successfully fetched amdsmi.h from $OLD_VERSION_REF_MINOR to amdsmi_old.h for Minor check"
231+ fi
232+ echo "v1_name_suffix_minor=${V1_NAME_SUFFIX_MINOR}" >> $GITHUB_OUTPUT
233+ echo "skip_check_minor=false" >> $GITHUB_OUTPUT
234+
235+ - name : Run Minor ABI Compliance Check (Strict)
236+ if : steps.prepare_files_minor.outputs.skip_check_minor == 'false'
237+ run : |
238+ V1_NAME_SUFFIX_CLEAN=$(echo "${{ steps.prepare_files_minor.outputs.v1_name_suffix_minor }}" | tr '/' '-')
239+ V2_NAME_CLEAN=$(echo "${{ github.ref_name || github.head_ref }}" | tr '/' '-')
240+ COMPARE_MSG="$V1_NAME_SUFFIX_CLEAN vs $V2_NAME_CLEAN"
241+
242+ echo "Comparing $COMPARE_MSG for Minor ABI Check (Strict)"
243+
244+ abi-compliance-checker -lib amdsmi -old amdsmi_old.h -new amdsmi_new.h -v1 "$V1_NAME_SUFFIX_CLEAN" -v2 "$V2_NAME_CLEAN" -report-path minor-abi-report.html -strict || {
245+ ACC_EXIT_CODE=$?
246+ echo "abi-compliance-checker -strict failed with exit code $ACC_EXIT_CODE."
247+ echo "abi_exit_code=$ACC_EXIT_CODE" > $GITHUB_WORKSPACE/minor_abi_status.txt
248+ }
249+
250+ current_abi_status=$(cat $GITHUB_WORKSPACE/minor_abi_status.txt)
251+ current_exit_code=${current_abi_status#*=}
252+
253+ if [ "$current_exit_code" -eq 0 ] && [ -f minor-abi-report.html ]; then
254+ echo "ACC strict check passed. Parsing HTML report for any changes..."
255+ CHANGED=0
256+ if grep -q "Added Symbols.*[1-9]" minor-abi-report.html; then CHANGED=1; echo "::warning::STRICT ABI: Found added symbols"; fi
257+ if grep -q "Removed Symbols.*[1-9]" minor-abi-report.html; then CHANGED=1; echo "::warning::STRICT ABI: Found removed symbols"; fi
258+ if grep -q "Problems with.*Data Types.*[1-9]" minor-abi-report.html; then CHANGED=1; echo "::warning::STRICT ABI: Found problems with data types"; fi
259+ if grep -q "Problems with.*Symbols.*[1-9]" minor-abi-report.html; then CHANGED=1; echo "::warning::STRICT ABI: Found problems with symbols"; fi
260+ if grep -q "Problems with.*Constants.*[1-9]" minor-abi-report.html; then CHANGED=1; echo "::warning::STRICT ABI: Found problems with constants"; fi
261+
262+ if [ "$CHANGED" -eq 1 ]; then
263+ echo "::error::STRICT ABI CHECK FAILED: Found changes in ABI report comparing $COMPARE_MSG"
264+ echo "abi_exit_code=1" > $GITHUB_WORKSPACE/minor_abi_status.txt
265+ else
266+ echo "No strict ABI changes found in HTML report."
267+ echo "abi_exit_code=0" > $GITHUB_WORKSPACE/minor_abi_status.txt
268+ fi
269+ elif [ ! -f minor-abi-report.html ] && [ "$current_exit_code" -eq 0 ]; then
270+ echo "::warning::Minor ABI report (minor-abi-report.html) not found, but ACC reported success. Assuming no changes."
271+ echo "abi_exit_code=0" > $GITHUB_WORKSPACE/minor_abi_status.txt
272+ elif [ "$current_exit_code" -ne 0 ]; then
273+ echo "ACC strict check already indicated failure (exit code $current_exit_code). HTML parsing for further changes skipped or confirmed failure."
274+ fi
275+ continue-on-error : true
276+
277+ - name : Display ABI Check Logs (Minor)
278+ if : always() && steps.prepare_files_minor.outputs.skip_check_minor == 'false'
279+ run : |
280+ echo "Displaying Minor ABI compliance check logs (if any)"
281+ find logs -type f -name "*.txt" -exec echo "--- {} ---" \; -exec cat {} \; || echo "No .txt logs found in logs/ directory."
282+
283+ - name : Label PR on Minor ABI Breakage
284+ if : always() && github.event_name == 'pull_request'
285+ run : |
286+ source $GITHUB_WORKSPACE/minor_abi_status.txt
287+ if [ "$abi_exit_code" -ne 0 ]; then
288+ echo "Minor ABI check failed, adding 'MINOR ABI BREAKAGE' label to PR #${{ github.event.pull_request.number }}"
289+ gh pr edit ${{ github.event.pull_request.number }} --add-label "MINOR ABI BREAKAGE"
290+ fi
291+ env :
292+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
293+
294+ - name : Upload Minor ABI Report
295+ if : always()
296+ uses : actions/upload-artifact@v4
297+ with :
298+ name : minor-abi-report
299+ path : minor-abi-report.html
300+ if-no-files-found : ignore
301+
302+ - name : Report Minor ABI Check Results
303+ if : always()
304+ run : |
305+ echo "Checking Minor ABI check exit code..."
306+ source $GITHUB_WORKSPACE/minor_abi_status.txt
307+ echo "Minor ABI check exit code: $abi_exit_code"
308+ if [ "$abi_exit_code" -ne 0 ]; then
309+ echo "::warning::⚠️ MINOR ABI CHANGES FOUND (STRICT CHECK) ⚠️ CHECK \"Run Minor ABI Compliance Check (Strict)\" LOGS OR THE minor-abi-report ARTIFACT FOR DETAILS."
310+ else
311+ echo "✅ Minor ABI check (Strict) succeeded or found no changes."
312+ fi
0 commit comments