|
49 | 49 | - | |
50 | 50 | echo "▶️ Running shellcheck..." |
51 | 51 | set +e |
52 | | - docker run --rm -i -v "$PWD:/work" -w /work koalaman/shellcheck:stable -x -S style show-versions.sh |
| 52 | + docker run --rm -i -v "$PWD:/work" -w /work koalaman/shellcheck:stable -x -S style entrypoint.sh |
53 | 53 | rc=$? |
54 | 54 | set -e |
55 | 55 | if [ "$rc" -eq 0 ]; then |
@@ -87,6 +87,137 @@ tasks: |
87 | 87 | - git config user.name "github-actions[bot]" |
88 | 88 | - git config user.email "github-actions[bot]@users.noreply.github.com" |
89 | 89 |
|
| 90 | + packages:update: |
| 91 | + desc: Update Alpine package pins in alpine-packages.txt |
| 92 | + cmds: |
| 93 | + - | |
| 94 | + set -eu |
| 95 | + if [ ! -f Dockerfile ]; then |
| 96 | + echo "INFO: Dockerfile not found; nothing to update" |
| 97 | + exit 0 |
| 98 | + fi |
| 99 | + if [ ! -f alpine-packages.txt ]; then |
| 100 | + echo "INFO: alpine-packages.txt not found; nothing to update" |
| 101 | + exit 0 |
| 102 | + fi |
| 103 | +
|
| 104 | + base_image="$(sed -nE 's/^FROM[[:space:]]+([^[:space:]]+).*/\1/p' Dockerfile | head -1)" |
| 105 | + if [ -z "$base_image" ]; then |
| 106 | + echo "INFO: Could not resolve base image; nothing to update" |
| 107 | + exit 0 |
| 108 | + fi |
| 109 | +
|
| 110 | + case "$base_image" in |
| 111 | + alpine:*|alpine) |
| 112 | + : |
| 113 | + ;; |
| 114 | + *) |
| 115 | + echo "INFO: Base image is '$base_image', not Alpine; nothing to update" |
| 116 | + exit 0 |
| 117 | + ;; |
| 118 | + esac |
| 119 | +
|
| 120 | + alpine_line="${base_image#alpine:}" |
| 121 | + if [ "$alpine_line" = "$base_image" ] || [ -z "$alpine_line" ]; then |
| 122 | + echo "INFO: Could not parse Alpine version from '$base_image'; nothing to update" |
| 123 | + exit 0 |
| 124 | + fi |
| 125 | + alpine_minor="$(printf '%s' "$alpine_line" | awk -F. '{print $1 "." $2}')" |
| 126 | + if ! printf '%s' "$alpine_minor" | grep -Eq '^[0-9]+\.[0-9]+$'; then |
| 127 | + echo "INFO: Unsupported Alpine version '$alpine_line'; nothing to update" |
| 128 | + exit 0 |
| 129 | + fi |
| 130 | + alpine_repo="v${alpine_minor}" |
| 131 | + arch="x86_64" |
| 132 | +
|
| 133 | + normalize_minor() { |
| 134 | + version="$1" |
| 135 | + printf '%s' "$version" | sed -E 's/^([0-9]+\.[0-9]+).*/\1/' |
| 136 | + } |
| 137 | +
|
| 138 | + fetch_index() { |
| 139 | + repo="$1" |
| 140 | + out="$2" |
| 141 | + url="https://dl-cdn.alpinelinux.org/alpine/${alpine_repo}/${repo}/${arch}/APKINDEX.tar.gz" |
| 142 | + curl --fail --silent --show-error "$url" | tar -O -zx APKINDEX > "$out" |
| 143 | + } |
| 144 | +
|
| 145 | + lookup_latest() { |
| 146 | + pkg="$1" |
| 147 | + for index in "$index_main" "$index_community"; do |
| 148 | + found="$(awk -v pkg="$pkg" ' |
| 149 | + BEGIN { RS=""; FS="\n" } |
| 150 | + { |
| 151 | + p=""; v="" |
| 152 | + for (i=1; i<=NF; i++) { |
| 153 | + if ($i ~ /^P:/) p=substr($i,3) |
| 154 | + if ($i ~ /^V:/) v=substr($i,3) |
| 155 | + } |
| 156 | + if (p==pkg) { print v; exit } |
| 157 | + } |
| 158 | + ' "$index")" |
| 159 | + if [ -n "$found" ]; then |
| 160 | + printf '%s' "$found" |
| 161 | + return 0 |
| 162 | + fi |
| 163 | + done |
| 164 | + return 1 |
| 165 | + } |
| 166 | +
|
| 167 | + mkdir -p .tmp |
| 168 | + index_main=".tmp/apkindex-main-${alpine_repo}-${arch}.txt" |
| 169 | + index_community=".tmp/apkindex-community-${alpine_repo}-${arch}.txt" |
| 170 | + fetch_index main "$index_main" |
| 171 | + fetch_index community "$index_community" |
| 172 | +
|
| 173 | + if ! grep -Eq '^[a-zA-Z0-9+_.-]+(=~|~=)[0-9]+\.[0-9]+$' alpine-packages.txt; then |
| 174 | + echo "INFO: No pinned Alpine packages (~=X.Y) found in alpine-packages.txt" |
| 175 | + exit 0 |
| 176 | + fi |
| 177 | +
|
| 178 | + tmp_out=".tmp/alpine-packages.updated.txt" |
| 179 | + : > "$tmp_out" |
| 180 | + updated=0 |
| 181 | + while IFS= read -r line || [ -n "$line" ]; do |
| 182 | + if [ -z "$line" ] || printf '%s' "$line" | grep -Eq '^[[:space:]]*#'; then |
| 183 | + echo "$line" >> "$tmp_out" |
| 184 | + continue |
| 185 | + fi |
| 186 | + if ! printf '%s' "$line" | grep -Eq '^[a-zA-Z0-9+_.-]+(=~|~=)[0-9]+\.[0-9]+$'; then |
| 187 | + echo "$line" >> "$tmp_out" |
| 188 | + continue |
| 189 | + fi |
| 190 | +
|
| 191 | + pkg="$(printf '%s' "$line" | sed -E 's/^([a-zA-Z0-9+_.-]+)(=~|~=).*/\1/')" |
| 192 | + current_minor="$(printf '%s' "$line" | sed -E 's/^[a-zA-Z0-9+_.-]+(=~|~=)([0-9]+\.[0-9]+).*$/\2/')" |
| 193 | + latest_full="$(lookup_latest "$pkg" || true)" |
| 194 | + if [ -z "$latest_full" ]; then |
| 195 | + echo "WARN: Could not resolve latest version for $pkg; keeping $line" |
| 196 | + echo "$line" >> "$tmp_out" |
| 197 | + continue |
| 198 | + fi |
| 199 | +
|
| 200 | + latest_minor="$(normalize_minor "$latest_full")" |
| 201 | + if [ "$latest_minor" = "$current_minor" ]; then |
| 202 | + echo "OK: $pkg already up to date at $current_minor" |
| 203 | + echo "$pkg~=$current_minor" >> "$tmp_out" |
| 204 | + continue |
| 205 | + fi |
| 206 | + echo "UPDATE: $pkg $current_minor -> $latest_minor" |
| 207 | + echo "$pkg~=$latest_minor" >> "$tmp_out" |
| 208 | + updated=1 |
| 209 | + done < alpine-packages.txt |
| 210 | +
|
| 211 | + if ! cmp -s alpine-packages.txt "$tmp_out"; then |
| 212 | + mv "$tmp_out" alpine-packages.txt |
| 213 | + else |
| 214 | + rm -f "$tmp_out" |
| 215 | + fi |
| 216 | +
|
| 217 | + if [ "$updated" -eq 0 ]; then |
| 218 | + echo "INFO: No Alpine package updates were required" |
| 219 | + fi |
| 220 | +
|
90 | 221 | version:get: |
91 | 222 | desc: Get current version |
92 | 223 | cmds: |
|
0 commit comments