-
Notifications
You must be signed in to change notification settings - Fork 13
517 lines (454 loc) · 20.4 KB
/
Copy pathrelease.yml
File metadata and controls
517 lines (454 loc) · 20.4 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
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
# SPDX-License-Identifier: BSD-3-Clause
name: Release
on:
workflow_dispatch:
inputs:
linux_version:
description: >
Linux driver version to release (e.g. 1.0.6.5).
Leave empty to skip the Linux release.
required: false
type: string
default: ''
windows_version:
description: >
Windows driver version to release (e.g. 1.00.94.6).
Leave empty to skip the Windows release.
required: false
type: string
default: ''
filter_version:
description: >
Filter driver sub-version (e.g. 1.0.1.6).
Leave empty to keep the current value in qcversion.h.
required: false
type: string
default: ''
net_version:
description: >
NDIS/net driver sub-version (e.g. 5.0.1.2).
Leave empty to keep the current value in qcversion.h.
required: false
type: string
default: ''
wdfserial_version:
description: >
WDF serial driver sub-version (e.g. 1.0.3.7).
Leave empty to keep the current value in qcversion.h.
required: false
type: string
default: ''
qdss_version:
description: >
QDSS driver sub-version (e.g. 1.0.4.2).
Leave empty to keep the current value in qcversion.h.
required: false
type: string
default: ''
adb_version:
description: >
ADB driver sub-version (e.g. 1.0.1.7).
Leave empty to keep the current value in qcversion.h.
required: false
type: string
default: ''
base_branch:
description: 'Base branch to cut the release from'
required: false
type: string
default: 'main'
release_notes:
description: 'Release notes (Markdown). Defaults to auto-generated notes.'
required: false
type: string
default: ''
draft:
description: 'Create as draft release (publish manually afterwards)'
required: false
type: boolean
default: false
# ─────────────────────────────────────────────────────────────────────────────
# Shared helpers
# ─────────────────────────────────────────────────────────────────────────────
env:
GIT_AUTHOR_NAME: github-actions[bot]
GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
jobs:
# ───────────────────────────────────────────────────────────────────────────
# Validate inputs before doing any real work
# ───────────────────────────────────────────────────────────────────────────
validate:
name: Validate inputs
runs-on: ubuntu-latest
outputs:
do_linux: ${{ steps.check.outputs.do_linux }}
do_windows: ${{ steps.check.outputs.do_windows }}
steps:
- name: Check actor is a maintainer
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ACTOR: ${{ github.actor }}
REPO: ${{ github.repository }}
run: |
PERMISSION=$(gh api "repos/${REPO}/collaborators/${ACTOR}/permission" \
--jq '.permission' 2>/dev/null || echo "none")
echo "Actor '${ACTOR}' permission: ${PERMISSION}"
case "$PERMISSION" in
admin|maintain|write)
echo "✅ Authorized — proceeding with release."
;;
*)
echo "ERROR: Only maintainers (write/maintain/admin) may trigger this workflow."
echo "Actor '${ACTOR}' has permission '${PERMISSION}'."
exit 1
;;
esac
- name: Check that at least one version was supplied
id: check
env:
LNX: ${{ inputs.linux_version }}
WIN: ${{ inputs.windows_version }}
run: |
if [ -z "$LNX" ] && [ -z "$WIN" ]; then
echo "ERROR: At least one of linux_version or windows_version must be provided."
exit 1
fi
# Validate Linux version format X.X.X.X
if [ -n "$LNX" ]; then
if ! echo "$LNX" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "ERROR: linux_version '$LNX' does not match expected format X.X.X.X"
exit 1
fi
echo "do_linux=true" >> "$GITHUB_OUTPUT"
else
echo "do_linux=false" >> "$GITHUB_OUTPUT"
fi
# Validate Windows version format X.XX.XX.X
if [ -n "$WIN" ]; then
if ! echo "$WIN" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "ERROR: windows_version '$WIN' does not match expected format X.XX.XX.X"
exit 1
fi
echo "do_windows=true" >> "$GITHUB_OUTPUT"
else
echo "do_windows=false" >> "$GITHUB_OUTPUT"
fi
# ───────────────────────────────────────────────────────────────────────────
# Linux release
# ───────────────────────────────────────────────────────────────────────────
release-linux:
name: Linux release ${{ inputs.linux_version }}
needs: validate
if: needs.validate.outputs.do_linux == 'true'
runs-on: ubuntu-latest
environment: release
permissions:
contents: write
steps:
- name: Checkout base branch
uses: actions/checkout@v7
with:
ref: ${{ inputs.base_branch }}
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure git identity
run: |
git config user.name "$GIT_AUTHOR_NAME"
git config user.email "$GIT_AUTHOR_EMAIL"
# ── 1. Create release branch ──────────────────────────────────────────
- name: Create release branch
id: branch
env:
VERSION: ${{ inputs.linux_version }}
run: |
BRANCH="release-lnx-${VERSION}"
if git ls-remote --exit-code --heads origin "refs/heads/${BRANCH}" >/dev/null 2>&1; then
echo "ERROR: Branch '${BRANCH}' already exists on remote."
exit 1
fi
git checkout -b "$BRANCH"
echo "branch=$BRANCH" >> "$GITHUB_OUTPUT"
# ── 2. Bump version in version.h ──────────────────────────────────────
- name: Update src/linux/version.h
env:
VERSION: ${{ inputs.linux_version }}
run: |
FILE="src/linux/version.h"
sed -i "s/#define DRIVER_VERSION \".*\"/#define DRIVER_VERSION \"${VERSION}\"/" "$FILE"
echo "Updated $FILE:"
cat "$FILE"
# Verify the change landed
grep -q "\"${VERSION}\"" "$FILE" || \
{ echo "ERROR: version.h was not updated correctly"; exit 1; }
# ── 3. Commit & push release branch ───────────────────────────────────
- name: Commit version bump
env:
VERSION: ${{ inputs.linux_version }}
run: |
git add src/linux/version.h
git commit -m "Update Linux driver version to ${VERSION}"
- name: Push release branch
env:
BRANCH: ${{ steps.branch.outputs.branch }}
run: |
git push origin "$BRANCH"
# ── 4. Build .deb package ─────────────────────────────────────────────
- name: Install build dependencies
run: |
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends dpkg-dev
- name: Build deb package
id: build
run: |
cd src/linux
set -o pipefail
bash build-deb.sh 2>&1 | tee /tmp/build.log
echo "Build output:"
ls -lh build/
- name: Job summary
if: always()
env:
VERSION: ${{ inputs.linux_version }}
BRANCH: ${{ steps.branch.outputs.branch }}
BUILD_RESULT: ${{ steps.build.outcome }}
run: |
{
echo "## Linux Release Summary — v${VERSION}"
echo ""
echo "| Step | Result |"
echo "|------|--------|"
echo "| Release branch | \`${BRANCH}\` |"
if [ "$BUILD_RESULT" = "success" ]; then
echo "| Build .deb | ✅ Success |"
else
echo "| Build .deb | ❌ **Failed** |"
echo ""
echo "### Build log"
echo "\`\`\`"
tail -50 /tmp/build.log 2>/dev/null || echo "(no log captured)"
echo "\`\`\`"
echo ""
echo "> **Action required:** Fix the build error, then re-run the workflow."
echo "> The release branch \`${BRANCH}\` has been pushed — delete it before re-running."
fi
} >> "$GITHUB_STEP_SUMMARY"
# ── 5. Package release artifact ───────────────────────────────────────
- name: Create release zip
id: zip
env:
VERSION: ${{ inputs.linux_version }}
run: |
DIR_NAME="qud_${VERSION}_all"
ZIP_NAME="${DIR_NAME}.zip"
DEB_FILE="src/linux/build/qud_${VERSION}_all.deb"
if [ ! -f "$DEB_FILE" ]; then
echo "ERROR: Expected deb not found: $DEB_FILE"
ls src/linux/build/ || true
exit 1
fi
mkdir -p "release_staging/${DIR_NAME}"
cp "$DEB_FILE" "release_staging/${DIR_NAME}/"
cp "src/linux/RELEASES.md" "release_staging/${DIR_NAME}/"
# Prefer src/linux/README.md, fall back to repo root README.md
if [ -f "src/linux/README.md" ]; then
cp "src/linux/README.md" "release_staging/${DIR_NAME}/"
elif [ -f "README.md" ]; then
cp "README.md" "release_staging/${DIR_NAME}/"
fi
(cd release_staging && zip -r "../${ZIP_NAME}" "${DIR_NAME}/")
echo "zip_name=$ZIP_NAME" >> "$GITHUB_OUTPUT"
echo "zip_path=${ZIP_NAME}" >> "$GITHUB_OUTPUT"
echo "Release zip contents:"
unzip -l "$ZIP_NAME"
# ── 6. Create tag ─────────────────────────────────────────────────────
- name: Create and push tag
id: tag
env:
VERSION: ${{ inputs.linux_version }}
run: |
TAG="release-lnx-v${VERSION}"
if git ls-remote --exit-code --tags origin "refs/tags/${TAG}" >/dev/null 2>&1; then
echo "ERROR: Tag '${TAG}' already exists on remote."
exit 1
fi
git tag -a "$TAG" -m "Linux release v${VERSION}"
git push origin "$TAG"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
# ── 7. Create GitHub release ──────────────────────────────────────────
- name: Create GitHub release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ inputs.linux_version }}
TAG: ${{ steps.tag.outputs.tag }}
BRANCH: ${{ steps.branch.outputs.branch }}
RELEASE_NOTES: ${{ inputs.release_notes }}
IS_DRAFT: ${{ inputs.draft }}
ZIP_PATH: ${{ steps.zip.outputs.zip_path }}
run: |
NOTES="$RELEASE_NOTES"
if [ -z "$NOTES" ]; then
NOTES="## Linux driver release v${VERSION}
Built from branch \`${BRANCH}\`.
### Installation
\`\`\`bash
sudo dpkg -i qud_${VERSION}_all.deb
\`\`\`
### Uninstall
\`\`\`bash
sudo dpkg -r qud
\`\`\`"
fi
DRAFT_FLAG=""
if [ "$IS_DRAFT" = "true" ]; then
DRAFT_FLAG="--draft"
fi
gh release create "$TAG" \
"$ZIP_PATH" \
--title "$TAG" \
--notes "$NOTES" \
$DRAFT_FLAG
echo "✅ Linux release created: $TAG"
# ───────────────────────────────────────────────────────────────────────────
# Windows release
#
# NOTE: Building signed Windows kernel drivers requires Visual Studio +
# Windows Driver Kit (WDK) and a code-signing certificate — tooling that is
# not available on standard GitHub-hosted runners.
#
# This job therefore:
# 1. Creates the release branch and bumps the version.
# 2. Creates the annotated tag.
# 3. Opens a DRAFT GitHub release so that the signed build artifacts
# (produced by your internal Windows build pipeline) can be attached
# before the release is published.
#
# To build locally: .\build\build_drivers.ps1 (requires VS + WDK)
# ───────────────────────────────────────────────────────────────────────────
release-windows:
name: Windows release ${{ inputs.windows_version }}
needs: validate
if: needs.validate.outputs.do_windows == 'true'
runs-on: ubuntu-latest # branch/tag/release work; no WDK needed here
environment: release
permissions:
contents: write
steps:
- name: Checkout base branch
uses: actions/checkout@v7
with:
ref: ${{ inputs.base_branch }}
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure git identity
run: |
git config user.name "$GIT_AUTHOR_NAME"
git config user.email "$GIT_AUTHOR_EMAIL"
# ── 1. Create release branch ──────────────────────────────────────────
- name: Create release branch
id: branch
env:
VERSION: ${{ inputs.windows_version }}
run: |
BRANCH="release-win-${VERSION}"
if git ls-remote --exit-code --heads origin "refs/heads/${BRANCH}" >/dev/null 2>&1; then
echo "ERROR: Branch '${BRANCH}' already exists on remote."
exit 1
fi
git checkout -b "$BRANCH"
echo "branch=$BRANCH" >> "$GITHUB_OUTPUT"
# ── 2. Bump version in qcversion.h ────────────────────────────────────
- name: Update src/windows/qcversion.h
env:
VERSION: ${{ inputs.windows_version }}
FILTER_VER: ${{ inputs.filter_version }}
NET_VER: ${{ inputs.net_version }}
WDFSERIAL_VER: ${{ inputs.wdfserial_version }}
QDSS_VER: ${{ inputs.qdss_version }}
ADB_VER: ${{ inputs.adb_version }}
run: |
FILE="src/windows/qcversion.h"
# Helper: update a VERSION + optional FILE_VERSION pair
update_driver_ver() {
local ver_macro="$1"
local file_macro="$2" # pass "" to skip FILE_VERSION
local ver="$3"
[ -z "$ver" ] && return 0 # skip if not provided
local ver_comma="${ver//./ }"; ver_comma="${ver_comma// /,}"
sed -i "s/\(#define ${ver_macro}[[:space:]]\+\)[^[:space:]]*/\1${ver}/" "$FILE"
[ -n "$file_macro" ] && \
sed -i "s/\(#define ${file_macro}[[:space:]]\+\)[^[:space:]]*/\1${ver_comma}/" "$FILE"
echo " ${ver_macro} -> ${ver}"
}
echo "Updating $FILE:"
# Package-level version (always updated)
VERSION_COMMA="${VERSION//./ }"; VERSION_COMMA="${VERSION_COMMA// /,}"
sed -i "s/\(#define QCOM_USB_DRIVERS_PRODUCT_VERSION[[:space:]]\+\)[^ ]*/\1${VERSION}/" "$FILE"
sed -i "s/\(#define QCOM_USB_DRIVERS_FILE_VERSION[[:space:]]\+\)[^[:space:]]*/\1${VERSION_COMMA}/" "$FILE"
echo " QCOM_USB_DRIVERS_PRODUCT_VERSION -> ${VERSION}"
# Individual driver sub-versions (updated only when input is non-empty)
update_driver_ver "QCOM_FILTER_VERSION" "QCOM_FILTER_FILE_VERSION" "$FILTER_VER"
update_driver_ver "QCOM_NET_VERSION" "QCOM_NET_FILE_VERSION" "$NET_VER"
update_driver_ver "QCOM_WDFSERIAL_VERSION" "QCOM_WDFSERIAL_FILE_VERSION" "$WDFSERIAL_VER"
update_driver_ver "QCOM_QDSS_VERSION" "QCOM_QDSS_FILE_VERSION" "$QDSS_VER"
update_driver_ver "QCOM_ADB_VERSION" "" "$ADB_VER"
echo ""
echo "Final version lines in $FILE:"
grep -E "_VERSION\b" "$FILE"
# Verify package version was applied
grep -q "QCOM_USB_DRIVERS_PRODUCT_VERSION ${VERSION}" "$FILE" || \
{ echo "ERROR: PRODUCT_VERSION was not updated correctly"; exit 1; }
# ── 3. Commit & push release branch ───────────────────────────────────
- name: Commit version bump
env:
VERSION: ${{ inputs.windows_version }}
run: |
git add src/windows/qcversion.h
git commit -m "Update Windows driver version to ${VERSION}"
- name: Push release branch
env:
BRANCH: ${{ steps.branch.outputs.branch }}
run: |
git push origin "$BRANCH"
# ── 4. Create tag ─────────────────────────────────────────────────────
- name: Create and push tag
id: tag
env:
VERSION: ${{ inputs.windows_version }}
run: |
TAG="release-win-v${VERSION}"
if git ls-remote --exit-code --tags origin "refs/tags/${TAG}" >/dev/null 2>&1; then
echo "ERROR: Tag '${TAG}' already exists on remote."
exit 1
fi
git tag -a "$TAG" -m "Windows release v${VERSION}"
git push origin "$TAG"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
# ── 5. Create draft GitHub release ────────────────────────────────────
- name: Create draft GitHub release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ inputs.windows_version }}
TAG: ${{ steps.tag.outputs.tag }}
BRANCH: ${{ steps.branch.outputs.branch }}
RELEASE_NOTES: ${{ inputs.release_notes }}
run: |
NOTES="$RELEASE_NOTES"
if [ -z "$NOTES" ]; then
NOTES="## Windows driver release v${VERSION}
Built from branch \`${BRANCH}\`.
> **Note:** Attach the signed build artifacts produced by the internal
> Windows build pipeline before publishing this release.
>
> Build locally with: \`.\build\build_drivers.ps1\` (requires Visual Studio + WDK)"
fi
# Windows releases always start as draft because signed artifacts
# must be attached by the internal build pipeline before publishing.
gh release create "$TAG" \
--title "$TAG" \
--notes "$NOTES" \
--draft
echo "✅ Windows draft release created: $TAG"
echo " Attach signed build artifacts and publish when ready."