-
-
Notifications
You must be signed in to change notification settings - Fork 0
242 lines (222 loc) · 8.43 KB
/
Copy pathscan-ipsw.yml
File metadata and controls
242 lines (222 loc) · 8.43 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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
name: Scan IPSW
on:
workflow_dispatch:
inputs:
ipsw_url:
description: "IPSW download URL"
required: true
type: string
release_date:
description: "Release date (ISO 8601, e.g. 2025-04-02)"
required: true
type: string
beta:
description: "Is this a beta release?"
required: false
type: boolean
default: false
beta_number:
description: "Beta number (e.g. 3)"
required: false
type: string
rc:
description: "Is this a Release Candidate?"
required: false
type: boolean
default: false
rc_number:
description: "RC number (e.g. 2). Omit for just RC"
required: false
type: string
device_specific:
description: "Device-specific build (e.g. M3 launch build)"
required: false
type: boolean
default: false
defaults:
run:
shell: bash -xeuo pipefail {0}
concurrency:
group: scan
cancel-in-progress: false
permissions: {}
jobs:
scan:
name: Scan
runs-on: scanner
environment:
name: scan
deployment: false
permissions:
contents: write # required to push branches
pull-requests: write # required to create PRs
steps:
- name: Add Homebrew to PATH
run: echo "/opt/homebrew/bin" >> "${GITHUB_PATH}"
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
fetch-depth: 0
- name: Clean workspace
run: git clean -fdx data/releases/
- name: Set up commit signing
env:
SSH_SIGNING_KEY: ${{ secrets.SSH_SIGNING_KEY }}
run: |
git config user.name "fuyunohoshi"
git config user.email "165941061+fuyunohoshi@users.noreply.github.com"
eval $(ssh-agent)
echo "SSH_AUTH_SOCK=${SSH_AUTH_SOCK}" >> "${GITHUB_ENV}"
echo "SSH_AGENT_PID=${SSH_AGENT_PID}" >> "${GITHUB_ENV}"
pubkey=$(ssh-keygen -y -f /dev/stdin <<< "${SSH_SIGNING_KEY}")
ssh-add -q - <<< "${SSH_SIGNING_KEY}"
allowed_signer="$(git config get user.email) ${pubkey}"
mkdir -p ~/.ssh
echo "${allowed_signer}" >> ~/.ssh/allowed_signers
git config gpg.format ssh
git config commit.gpgsign true
git config user.signingkey "${pubkey}"
git config gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
- name: Set up authenticated remote
env:
BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
REPOSITORY: ${{ github.repository }}
run: git remote set-url origin "https://x-access-token:${BOT_TOKEN}@github.com/${REPOSITORY}.git"
- name: Resolve IPSW path
env:
IPSW_URL: ${{ inputs.ipsw_url }}
run: |
ORIG_NAME=$(basename "${IPSW_URL%%\?*}")
VERSION=$(echo "${ORIG_NAME}" | sed -E 's/UniversalMac_([0-9.]+)_.*/\1/')
BUILD=$(echo "${ORIG_NAME}" | sed -E 's/UniversalMac_[0-9.]+_([^_]+)_.*/\1/')
MAJOR=${VERSION%%.*}
IPSW_DIR="/Volumes/macOS-Archive/macOS/${MAJOR}"
mkdir -p "${IPSW_DIR}"
IPSW_FILE="${IPSW_DIR}/macOS-${VERSION}-${BUILD}.ipsw"
echo "IPSW_FILE=${IPSW_FILE}" >> "${GITHUB_ENV}"
- name: Download IPSW
env:
IPSW_URL: ${{ inputs.ipsw_url }}
run: |
set +x
if [[ -f "${IPSW_FILE}" ]]; then
echo "IPSW already cached at ${IPSW_FILE}, skipping download"
else
TOTAL=$(curl -sSLI --retry 5 --retry-connrefused "${IPSW_URL}" | grep -i content-length | tail -1 | tr -dc '0-9')
TOTAL_MB=$(( TOTAL / 1048576 ))
TOTAL_GB=$(( TOTAL_MB * 10 / 1024 ))
echo "Downloading IPSW ($(( TOTAL_GB / 10 )).$(( TOTAL_GB % 10 )) GB)..."
curl -sSL --retry 10 --retry-delay 10 --retry-connrefused --retry-all-errors -C - -o "${IPSW_FILE}.part" "${IPSW_URL}" &
CURL_PID=$!
while kill -0 "${CURL_PID}" 2>/dev/null; do
if [[ -f "${IPSW_FILE}.part" ]]; then
SIZE=$(stat -f%z "${IPSW_FILE}.part" 2>/dev/null || echo 0)
SIZE_MB=$(( SIZE / 1048576 ))
PCT=$(( SIZE_MB * 100 / TOTAL_MB ))
echo "${PCT}% (${SIZE_MB} MB / ${TOTAL_MB} MB)"
fi
sleep 30
done
wait "${CURL_PID}"
mv "${IPSW_FILE}.part" "${IPSW_FILE}"
fi
- name: Set IPSW modification time to release date
env:
RELEASE_DATE: ${{ inputs.release_date }}
run: |
TOUCH_DATE=$(echo "${RELEASE_DATE}" | tr -d '-')0000
touch -t "${TOUCH_DATE}" "${IPSW_FILE}"
- name: Restore CLI build cache
id: cache-cli
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
path: .build/release/macosdb
key: macosdb-cli-${{ hashFiles('Sources/**/*.swift', 'Package.swift', 'Package.resolved') }}
- name: Build CLI
if: steps.cache-cli.outputs.cache-hit != 'true'
run: swift build -c release --product macosdb
- name: Save CLI build cache
if: steps.cache-cli.outputs.cache-hit != 'true'
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
path: .build/release/macosdb
key: macosdb-cli-${{ hashFiles('Sources/**/*.swift', 'Package.swift', 'Package.resolved') }}
- name: Create scan branch from latest main
run: |
git fetch origin main
git checkout -f -B scan-wip origin/main
- name: Scan IPSW
env:
IPSW_URL: ${{ inputs.ipsw_url }}
RELEASE_DATE: ${{ inputs.release_date }}
IS_BETA: ${{ inputs.beta }}
BETA_NUMBER: ${{ inputs.beta_number }}
IS_RC: ${{ inputs.rc }}
RC_NUMBER: ${{ inputs.rc_number }}
IS_DEVICE_SPECIFIC: ${{ inputs.device_specific }}
run: |
SCAN_ARGS=(
"${IPSW_FILE}"
--output data/releases
--release-date "${RELEASE_DATE}"
--update-index
--verbose
--ipsw-url "${IPSW_URL}"
)
if [[ "${IS_BETA}" == "true" ]]; then
SCAN_ARGS+=(--beta)
fi
if [[ -n "${BETA_NUMBER}" ]]; then
SCAN_ARGS+=(--beta-number "${BETA_NUMBER}")
fi
if [[ "${IS_RC}" == "true" ]]; then
SCAN_ARGS+=(--rc)
fi
if [[ -n "${RC_NUMBER}" ]]; then
SCAN_ARGS+=(--rc-number "${RC_NUMBER}")
fi
if [[ "${IS_DEVICE_SPECIFIC}" == "true" ]]; then
SCAN_ARGS+=(--device-specific)
fi
.build/release/macosdb scan "${SCAN_ARGS[@]}"
- name: Commit and push
run: |
NEW_FILE=$(git ls-files --others --exclude-standard 'data/releases/')
BASENAME=$(basename "${NEW_FILE}" .json)
BRANCH="feat/data-${BASENAME}"
git branch -m "${BRANCH}"
git add data/
git commit -m "feat(data): add ${BASENAME}"
git push -u origin "${BRANCH}"
echo "SCAN_BRANCH=${BRANCH}" >> "${GITHUB_ENV}"
echo "SCAN_BASENAME=${BASENAME}" >> "${GITHUB_ENV}"
- name: Create pull request
env:
GH_TOKEN: ${{ secrets.BOT_TOKEN }}
IPSW_URL: ${{ inputs.ipsw_url }}
RELEASE_DATE: ${{ inputs.release_date }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
printf -v BODY '## Summary\n- Scanned from IPSW: `%s`\n- Release date: %s\n\nAuto-generated by the [scan workflow](%s).' \
"${IPSW_URL}" "${RELEASE_DATE}" "${RUN_URL}"
gh pr create \
--title "feat(data): add ${SCAN_BASENAME}" \
--body "${BODY}"
- name: Auto-merge pull request
timeout-minutes: 30
env:
GH_TOKEN: ${{ secrets.BOT_TOKEN }}
run: |
gh pr merge "${SCAN_BRANCH}" --squash --auto --delete-branch
echo "Waiting for PR to merge..."
while true; do
STATE=$(gh pr view "${SCAN_BRANCH}" --json state -q .state)
if [[ "${STATE}" == "MERGED" ]]; then
echo "PR merged successfully"
break
elif [[ "${STATE}" == "CLOSED" ]]; then
echo "::error::PR was closed without merging"
exit 1
fi
sleep 30
done