-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsurface-kernel-update
More file actions
executable file
·140 lines (125 loc) · 6.27 KB
/
Copy pathsurface-kernel-update
File metadata and controls
executable file
·140 lines (125 loc) · 6.27 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
#!/usr/bin/env bash
# Build our own linux-cachyos-surface{,-latest} kernels into a local pacman
# repo, but only when a new version needs building. Installation itself is
# left to pacman/yay, which see the packages via the [surface-local] repo.
#
# Both packages come from repos forked from linux-surface/linux-surface (the
# only external upstream this depends on for patches) with our own CachyOS
# packaging layered on top -- see each repo's NOTICE for details/credits:
# - linux-cachyos-surface https://github.com/Steefzar/linux-cachyos-surface
# - linux-cachyos-surface-latest https://github.com/Steefzar/linux-cachyos-surface-latest
set -euo pipefail
REPODIR="${SURFACE_REPODIR:-/var/lib/surface-local}" # local pacman repo
# ^ must live OUTSIDE $HOME: pacman's sandboxed download user 'alpm' can't traverse
# a 700 home dir, so a file:// repo there fails. Dir is owned by you (repo-add
# needs no sudo) but on a path/perms the alpm user can read.
DBNAME="surface-local"
# LTO mode for the llvm-built kernel. "thin" is multithreaded and uses far
# less RAM than "full" (which can need >10 GiB just to link) — safer for most
# machines and for repeated auto-builds, with negligible real-world perf
# difference. Force full LTO with: SURFACE_LTO=full surface-kernel-update
export _use_llvm_lto="${_use_llvm_lto:-${SURFACE_LTO:-thin}}"
# One entry per package: <repo-url>|<local-clone-dir>|<pkg-subdir-in-repo>
VARIANTS=(
"https://github.com/Steefzar/linux-cachyos-surface.git|$HOME/.local/share/linux-cachyos-surface|pkg/linux-cachyos-surface"
"https://github.com/Steefzar/linux-cachyos-surface-latest.git|$HOME/.local/share/linux-cachyos-surface-latest|pkg/linux-cachyos-surface-latest"
)
mkdir -p "$REPODIR"
# ensure at least an empty db exists so pacman -Sy / -S won't error on a fresh repo
if [[ ! -e "$REPODIR/${DBNAME}.db" ]]; then
tar -czf "$REPODIR/${DBNAME}.db.tar.gz" -T /dev/null
ln -sf "${DBNAME}.db.tar.gz" "$REPODIR/${DBNAME}.db"
fi
# pacman won't run ANY -S transaction (incl. installing build deps) while a
# configured repo has no synced db. Make sure surface-local's sync db exists.
if grep -q '^\[surface-local\]' /etc/pacman.conf 2>/dev/null \
&& [[ ! -e /var/lib/pacman/sync/surface-local.db ]]; then
echo ":: surface-local sync db missing — running 'sudo pacman -Sy' once..."
sudo pacman -Sy
fi
built_any=0
failed=()
rebase_needed=()
for entry in "${VARIANTS[@]}"; do
IFS='|' read -r url repo pkgsub <<< "$entry"
v="${pkgsub##*/}"
dir="$repo/$pkgsub"
# (Re-)clone if missing, or if it's pointed at a different remote than
# expected (e.g. this machine's old pre-fork clone) -- these are just
# disposable build clones, safe to recreate from scratch.
if [[ ! -d $repo/.git ]]; then
echo ":: Cloning $url"
git clone --quiet "$url" "$repo"
elif [[ "$(git -C "$repo" remote get-url origin 2>/dev/null)" != "$url" ]]; then
echo ":: $repo points at a different remote than expected -- re-cloning from $url"
rm -rf "$repo"
git clone --quiet "$url" "$repo"
fi
git -C "$repo" fetch --quiet origin
git -C "$repo" reset --hard --quiet origin/master
[[ -d $dir ]] || { echo ":: skip $v (pkg dir not in repo)"; continue; }
# target version published in this package's PKGBUILD (offline; pkgver is static)
newver=$(cd "$dir" && makepkg --printsrcinfo \
| awk '/^\tpkgver =/{pv=$3} /^\tpkgrel =/{pr=$3} END{print pv"-"pr}')
# already built for this exact version? then nothing to do.
# NB: test compgen's OUTPUT, not its exit status — `compgen -G` returns 0 even
# with no match in some shells, which would wrongly skip building a new release.
if [[ -n $(compgen -G "$REPODIR/${v}-${newver}-*.pkg.tar.zst") ]]; then
echo ":: $v $newver already built (in $DBNAME)"
continue
fi
echo ":: Building $v -> $newver"
git -C "$repo" clean -ffdx --quiet -- "$pkgsub" # pristine tree
# 'yes ""' feeds ENTER to every kernel oldconfig prompt so unattended,
# yay-triggered rebuilds accept defaults instead of hanging. pipefail is
# disabled inside the group so 'yes' getting SIGPIPE isn't seen as a
# failure. Output is tee'd to a logfile (in addition to the terminal, same
# full build output as always) purely so we can tell a "linux-surface
# patches no longer apply, needs a manual rebase" failure apart from an
# ordinary compile failure in the summary below.
logfile=$(mktemp)
if ( cd "$dir" && { set +o pipefail; yes '' | makepkg -sf --skipinteg --noconfirm; } ) \
> >(tee "$logfile") 2>&1; then
build_ok=1
else
build_ok=0
fi
if [[ $build_ok -ne 1 ]]; then
if grep -q 'manual/Claude-assisted rebase' "$logfile"; then
echo ":: !! $v needs a manual rebase — linux-surface's patches no longer apply" \
"cleanly against this kernel version (see output above). Leaving the" \
"previous build/package untouched, continuing."
rebase_needed+=("$v")
else
echo ":: !! BUILD FAILED for $v — leaving local repo unchanged, continuing"
failed+=("$v")
fi
rm -f "$logfile"
continue
fi
rm -f "$logfile"
# publish all produced packages (kernel + headers) into the local repo
shopt -s nullglob
pkgs=("$dir"/*.pkg.tar.zst)
shopt -u nullglob
cp -f "${pkgs[@]}" "$REPODIR"/
( cd "$REPODIR" && repo-add -q "${DBNAME}.db.tar.gz" "${pkgs[@]##*/}" )
built_any=1
done
if [[ $built_any -eq 1 ]]; then
echo ":: New Surface kernel(s) added to local repo '$DBNAME'."
echo ":: Your pacman/yay upgrade will now pick them up."
# push the new build to the public [surface-cachyos] repo on GitHub
# Releases too (signed, precompiled). Never fatal: the local repo is
# already updated either way. SURFACE_NO_PUBLISH=1 skips it.
if [[ -z ${SURFACE_NO_PUBLISH:-} ]] && command -v surface-kernel-publish >/dev/null; then
surface-kernel-publish \
|| echo ":: NOTE: publish to GitHub Releases failed -- run surface-kernel-publish manually"
fi
fi
if ((${#rebase_needed[@]})); then
echo ":: NOTE: needs a manual/Claude-assisted rebase: ${rebase_needed[*]}"
fi
if ((${#failed[@]})); then
echo ":: NOTE: build failed for: ${failed[*]}"
fi