Repository navigation
114 lines (102 loc) · 4.24 KB
/
Copy pathbinary-diff.yml
File metadata and controls
114 lines (102 loc) · 4.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
name: Binary Symbol Diff
# Dumps hook-relevant symbols (classes / RPCs / flags / methods) from a new
# decrypted Spotify IPA and diffs them against the committed rolling baseline
# (Symbols/baseline-*.txt). Reports CRITICAL findings when classes the tweak
# hooks vanish (those hooks silently stop working) and HIGH findings when
# ad/Premium-relevant RPCs change (the FetchMessage/pendragon class of
# breakage). Run this on every new Spotify release BEFORE shipping a build.
on:
workflow_dispatch:
inputs:
ipa_url:
description: "URL to a DECRYPTED Spotify IPA"
required: true
type: string
refresh_baseline:
description: "Also refresh Symbols/baseline-*.txt with the new dump (branch: diff-baseline-<version>)"
default: "false"
required: false
type: choice
options:
- "false"
- "true"
permissions:
contents: write
jobs:
diff:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download IPA
run: |
wget "${{ inputs.ipa_url }}" --no-verbose -O spotify.ipa
file_type=$(file --mime-type -b spotify.ipa)
[ "$file_type" = "application/zip" ] || {
echo "::error::Not a valid IPA: $file_type"; exit 1; }
- name: Extract Spotify version
id: ver
run: |
sudo apt-get install -y libplist-utils >/dev/null 2>&1 || true
SPOT_VERSION=$(unzip -p spotify.ipa 'Payload/Spotify.app/Info.plist' \
| plutil -extract CFBundleShortVersionString raw - 2>/dev/null \
|| echo "unknown")
echo "version=$SPOT_VERSION" >> "$GITHUB_OUTPUT"
echo "Spotify version: $SPOT_VERSION"
- name: Dump symbols
run: |
python3 Scripts/dump-spotify-symbols.py spotify.ipa -o "dump-${{ steps.ver.outputs.version }}.txt"
- name: Pick baseline
id: baseline
run: |
# Latest committed baseline by version sort; fall back to the only one.
BASE=$(ls Symbols/baseline-*.txt 2>/dev/null | sort -V | tail -1)
if [ -z "$BASE" ]; then
echo "::error::No Symbols/baseline-*.txt committed"; exit 1
fi
echo "path=$BASE" >> "$GITHUB_OUTPUT"
echo "Baseline: $BASE"
- name: Diff against baseline
id: diff
continue-on-error: true # exit 3 = CRITICAL findings; still upload the report
run: |
set +e
python3 Scripts/diff-symbol-dumps.py "${{ steps.baseline.outputs.path }}" \
"dump-${{ steps.ver.outputs.version }}.txt" \
--tweak-sources Sources/EeveeSpotify \
-o "report-${{ steps.ver.outputs.version }}.md"
code=$?
echo "exit_code=$code" >> "$GITHUB_OUTPUT"
if [ "$code" -eq 3 ]; then
echo "::error::CRITICAL: hooked classes missing from the new binary — hooks will silently stop working. Read the report artifact."
fi
exit 0
- name: Upload dump + report
uses: actions/upload-artifact@v4
with:
name: symbol-diff-${{ steps.ver.outputs.version }}
path: |
dump-${{ steps.ver.outputs.version }}.txt
report-${{ steps.ver.outputs.version }}.md
if-no-files-found: error
- name: Print report summary
run: |
{
echo "### Spotify ${{ steps.ver.outputs.version }} vs baseline"
echo '```'
head -40 "report-${{ steps.ver.outputs.version }}.md"
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
- name: Refresh baseline branch
if: ${{ inputs.refresh_baseline == 'true' }}
run: |
SPOT="${{ steps.ver.outputs.version }}"
git config user.name "eevee-baseline-bot"
git config user.email "actions@users.noreply.github.com"
git checkout -b "diff-baseline-${SPOT}"
cp "dump-${SPOT}.txt" "Symbols/baseline-${SPOT}.txt"
# keep only the newest 3 baselines to avoid unbounded growth
ls -t Symbols/baseline-*.txt 2>/dev/null | sort -V | head -n -3 | xargs -r rm -f
git add Symbols/
git commit -m "Add symbol baseline for Spotify ${SPOT}"
git push origin "diff-baseline-${SPOT}"