diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 1f8bbc8..13491e0 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,7 +5,7 @@ updates: target-branch: master schedule: interval: weekly - day: saturday + day: wednesday time: "05:00" timezone: "UTC" assignees: @@ -20,7 +20,7 @@ updates: target-branch: master schedule: interval: weekly - day: saturday + day: wednesday time: "05:00" timezone: "UTC" assignees: diff --git a/Taskfile.scripts.yml b/Taskfile.scripts.yml index f609613..1d9e238 100644 --- a/Taskfile.scripts.yml +++ b/Taskfile.scripts.yml @@ -243,6 +243,81 @@ tasks: -w /work \ devopsinfra/action-container-structure-test:v1 + alpine:update: + desc: Update Alpine base image references and VERSION_ID test expectations + cmds: + - | + set -eu + if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then + echo "INFO: Not in a git repository; nothing to update" + exit 0 + fi + + mkdir -p .tmp + tracked_files=".tmp/alpine-update-files.txt" + relevant_files=".tmp/alpine-update-relevant.txt" + git ls-files > "$tracked_files" + grep -E '(^|/)(Dockerfile[^/]*|[^/]+\.sh|\.github/workflows/.*\.ya?ml|tests/.*\.ya?ml)$' "$tracked_files" > "$relevant_files" || true + + if [ ! -s "$relevant_files" ]; then + echo "INFO: No tracked Alpine-related source files found; nothing to update" + exit 0 + fi + + latest_feed="$(curl -fsSL https://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/x86_64/latest-releases.yaml)" + latest_alpine="$(printf '%s\n' "$latest_feed" | awk '/^ version:/ {print $2}' | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -1)" + if [ -z "$latest_alpine" ]; then + echo "ERROR: Could not resolve latest Alpine release" + exit 1 + fi + escaped_alpine="$(printf '%s' "$latest_alpine" | sed 's/\./\\\\./g')" + + found_refs=0 + while IFS= read -r file; do + [ -n "$file" ] || continue + if grep -Eq 'alpine:[0-9]+\.[0-9]+\.[0-9]+|expectedOutput:[[:space:]]*\[VERSION_ID=[0-9]+(\\?\.[0-9]+){2}\]' "$file"; then + found_refs=1 + break + fi + done < "$relevant_files" + + if [ "$found_refs" -eq 0 ]; then + echo "INFO: No Alpine version references found in tracked source files; nothing to update" + exit 0 + fi + + updated=0 + while IFS= read -r file; do + [ -n "$file" ] || continue + before_file=".tmp/alpine-update-before" + cp "$file" "$before_file" + perl -0pi -e 's/alpine:\d+\.\d+\.\d+/alpine:'"$latest_alpine"'/g' "$file" + if printf '%s\n' "$file" | grep -Eq '^tests/.*\.ya?ml$'; then + perl -0pi -e 's/expectedOutput:\s*\[VERSION_ID=\d+(?:\\?\.\d+){2}\]/expectedOutput: [VERSION_ID='"$escaped_alpine"']/g' "$file" + fi + if ! cmp -s "$file" "$before_file"; then + echo "UPDATE: Alpine references in $file -> $latest_alpine" + updated=1 + fi + done < "$relevant_files" + rm -f .tmp/alpine-update-before + + if xargs grep -En 'expectedOutput:[[:space:]]*\[VERSION_ID=[0-9]+\.[0-9]+\.[0-9]+\]' < "$relevant_files" >/dev/null 2>&1; then + echo "ERROR: Found unescaped VERSION_ID expectations after update" + xargs grep -En 'expectedOutput:[[:space:]]*\[VERSION_ID=[0-9]+\.[0-9]+\.[0-9]+\]' < "$relevant_files" || true + exit 1 + fi + + if xargs grep -En 'alpine:[0-9]+\\\.[0-9]+\\\.[0-9]+' < "$relevant_files" >/dev/null 2>&1; then + echo "ERROR: Found escaped Alpine image tags after update" + xargs grep -En 'alpine:[0-9]+\\\.[0-9]+\\\.[0-9]+' < "$relevant_files" || true + exit 1 + fi + + if [ "$updated" -eq 0 ]; then + echo "INFO: Alpine references already up to date" + fi + packages:update: desc: Update Alpine package pins in alpine-packages.txt cmds: