#!/bin/bash # ============================================================================= # scripts/update-versions.sh # # Re-pins one (or all) upstream components in versions.env to their current # latest release, recomputing the SHA256 checksum against the freshly # downloaded source tarball. This is the ONLY supported way to change a # version/checksum pair in versions.env — never hand-edit a checksum, since # that defeats the entire point of pinning it (see the header comment in # versions.env). # # Usage: # scripts/update-versions.sh # check/update all components # scripts/update-versions.sh podman crun # only these components # # This script only rewrites versions.env. It does not build anything, and it # does not commit — review the diff (`git diff versions.env`) before # committing, ideally by also running a build to confirm the new source # still compiles (scripts/build-packages.sh ). # ============================================================================= set -eu REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" VERSIONS_FILE="$REPO_ROOT/versions.env" # Maps our internal component name -> GitHub "owner/repo", for every # component that actually has GitHub-tagged releases. passt is handled # separately below (see versions.env for why). declare -A GITHUB_REPO=( [podman]="containers/podman" [conmon]="containers/conmon" [crun]="containers/crun" [netavark]="containers/netavark" [aardvark-dns]="containers/aardvark-dns" [fuse-overlayfs]="containers/fuse-overlayfs" ) # Maps our internal component name -> the *_VERSION variable prefix used in # versions.env (uppercased, hyphens -> underscores). env_prefix() { echo "$1" | tr '[:lower:]-' '[:upper:]_' } update_github_component() { local name="$1" local repo="${GITHUB_REPO[$name]}" local prefix prefix=$(env_prefix "$name") echo "==> [$name] checking latest release for $repo" local api_response api_response=$(curl -sL --max-time 15 "https://api.github.com/repos/$repo/releases/latest") local tag tag=$(echo "$api_response" | grep -m1 '"tag_name"' | sed -E 's/.*"tag_name":[[:space:]]*"([^"]+)".*/\1/') if [ -z "$tag" ]; then echo "!! [$name] could not determine latest tag (rate-limited or repo has no releases?)" >&2 return 1 fi # Strip a leading "v" for the version we store, but keep it for the URL # since GitHub tags for these projects are inconsistent about it (crun # tags plain "1.28", others tag "v1.28"). local version="${tag#v}" local url="https://github.com/$repo/archive/refs/tags/$tag.tar.gz" echo "==> [$name] latest = $version, downloading to verify + checksum" local tmpfile tmpfile=$(mktemp) curl -fL --max-time 120 -o "$tmpfile" "$url" local sha256 sha256=$(sha256sum "$tmpfile" | awk '{print $1}') rm -f "$tmpfile" echo "==> [$name] sha256=$sha256" apply_update "$prefix" "$version" "$url" "$sha256" } apply_update() { local prefix="$1" version="$2" url="$3" sha256="$4" # In-place rewrite of the three lines for this component. Using distinct # sed expressions per variable (rather than one blanket substitution) # keeps this safe even if variable order in versions.env changes. sed -i \ -e "s|^${prefix}_VERSION=.*|${prefix}_VERSION=\"${version}\"|" \ -e "s|^${prefix}_SRC_SHA256=.*|${prefix}_SRC_SHA256=\"${sha256}\"|" \ "$VERSIONS_FILE" # The *_SRC_URL line is templated against *_VERSION (e.g. # ".../v${PODMAN_VERSION}.tar.gz") in most cases, so it doesn't need # rewriting — only touch it if it isn't already parameterized. if ! grep -q "^${prefix}_SRC_URL=.*\${${prefix}_VERSION}" "$VERSIONS_FILE" \ && ! grep -q "^${prefix}_SRC_URL=.*\$${prefix}_VERSION" "$VERSIONS_FILE"; then sed -i -e "s|^${prefix}_SRC_URL=.*|${prefix}_SRC_URL=\"${url}\"|" "$VERSIONS_FILE" fi echo "==> updated ${prefix}_VERSION / ${prefix}_SRC_SHA256 in $VERSIONS_FILE" } update_passt() { echo "==> [passt] checking latest master commit at https://passt.top/passt/" local atom atom=$(curl -sL --max-time 15 "https://passt.top/passt/atom/?h=master") local commit commit=$(echo "$atom" | grep -m1 -oE '[a-f0-9]{40}' | sed -E 's/<\/?id>//g') if [ -z "$commit" ]; then echo "!! [passt] could not determine latest commit" >&2 return 1 fi local url="https://passt.top/passt/snapshot/passt-${commit}.tar.gz" echo "==> [passt] latest commit = $commit, downloading to verify + checksum" local tmpfile tmpfile=$(mktemp) curl -fL --max-time 120 -o "$tmpfile" "$url" local sha256 sha256=$(sha256sum "$tmpfile" | awk '{print $1}') rm -f "$tmpfile" sed -i \ -e "s|^PASST_COMMIT=.*|PASST_COMMIT=\"${commit}\"|" \ -e "s|^PASST_VERSION=.*|PASST_VERSION=\"git${commit:0:7}\"|" \ -e "s|^PASST_SRC_SHA256=.*|PASST_SRC_SHA256=\"${sha256}\"|" \ "$VERSIONS_FILE" echo "==> updated PASST_COMMIT / PASST_VERSION / PASST_SRC_SHA256 in $VERSIONS_FILE" } requested=("$@") if [ "${#requested[@]}" -eq 0 ]; then requested=("${!GITHUB_REPO[@]}" passt) fi for name in "${requested[@]}"; do if [ "$name" = "passt" ]; then update_passt elif [ -n "${GITHUB_REPO[$name]:-}" ]; then update_github_component "$name" else echo "!! Unknown component: $name" >&2 exit 1 fi done echo echo "==> Done. Review the diff before committing:" echo " git -C \"$REPO_ROOT\" diff versions.env"