Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/workflows/check-version-updates.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Check for Go and Kubernetes version updates

on:
schedule:
- cron: '0 1 * * *'
workflow_dispatch:

jobs:
check-updates:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write

strategy:
matrix:
branch:
- go1.24-k8s1.32
fail-fast: false

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ matrix.branch }}

- name: Install yq
uses: mikefarah/yq@master

- name: Check for version updates
id: check-updates
run: |
output=$(hack/check-version-updates.sh -f images/calico-go-build/versions.yaml)
echo "$output"

# Extract the updates summary if present
if echo "$output" | grep -q "UPDATES_SUMMARY_START"; then
summary=$(echo "$output" | sed -n '/UPDATES_SUMMARY_START/,/UPDATES_SUMMARY_END/{/UPDATES_SUMMARY_START/d;/UPDATES_SUMMARY_END/d;p;}')
{
echo "summary<<EOF"
echo "$summary"
echo "EOF"
} >> $GITHUB_OUTPUT
fi

- name: Create Pull Request
if: steps.check-updates.outputs.summary != ''
uses: peter-evans/create-pull-request@v7
with:
commit-message: |
Update versions in calico-go-build

${{ steps.check-updates.outputs.summary }}
branch: auto-update-versions-${{ matrix.branch }}
base: ${{ matrix.branch }}
title: "[${{ matrix.branch }}] Auto-update Go/Kubernetes versions"
body: |
Automated version update for `${{ matrix.branch }}`:

${{ steps.check-updates.outputs.summary }}
110 changes: 110 additions & 0 deletions hack/check-version-updates.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#!/bin/bash

set -eu

ver_file=""

while getopts ":f:" opt; do
case $opt in
f)
ver_file="$OPTARG"
;;
:)
echo "option: -$OPTARG requires an argument" >&2
exit 1
;;
*)
echo "invalid argument -$OPTARG" >&2
exit 1
;;
esac
done

if [[ -z "$ver_file" ]]; then
echo "usage: $0 -f <versions.yaml>" >&2
exit 1
fi

updates=""

# --- Go update ---

current_go_ver=$(yq -r .golang.version "$ver_file")
go_minor="${current_go_ver%.*}"

echo "Checking Go updates for ${go_minor}.x series (current: ${current_go_ver})..."

go_api_response=$(curl -sf "https://go.dev/dl/?mode=json&include=all")

# Find latest stable release in the current minor series (sort numerically by patch version)
latest_go_ver=$(echo "$go_api_response" | jq -r --arg minor "go${go_minor}" \
'[.[] | select(.stable == true) | select(.version | startswith($minor + "."))]
| sort_by(.version | ltrimstr("go") | split(".") | map(tonumber))
| last | .version // empty' \
)

if [[ -z "$latest_go_ver" ]]; then
echo "No stable Go release found for ${go_minor}.x series"
else
# Strip "go" prefix: go1.24.14 -> 1.24.14
latest_go_ver="${latest_go_ver#go}"

if [[ "$latest_go_ver" != "$current_go_ver" ]]; then
echo "Go update available: ${current_go_ver} -> ${latest_go_ver}"

# Update version
yq -i ".golang.version = \"${latest_go_ver}\"" "$ver_file"

# Update checksums for each architecture
for arch in amd64 arm64 ppc64le s390x; do
sha256=$(echo "$go_api_response" | jq -r --arg ver "go${latest_go_ver}" --arg arch "$arch" \
'.[] | select(.version == $ver) | .files[] | select(.os == "linux" and .arch == $arch and .kind == "archive") | .sha256' \
)
if [[ -z "$sha256" ]]; then
echo "ERROR: Could not find SHA256 for go${latest_go_ver} linux/${arch}" >&2
exit 1
fi
yq -i ".golang.checksum.sha256.${arch} = \"${sha256}\"" "$ver_file"
echo " ${arch}: ${sha256}"
done

updates="${updates}Go: ${current_go_ver} -> ${latest_go_ver}\n"
else
echo "Go is up to date (${current_go_ver})"
fi
fi

# --- Kubernetes update ---

current_k8s_ver=$(yq -r .kubernetes.version "$ver_file")
k8s_minor="${current_k8s_ver%.*}"

echo "Checking Kubernetes updates for ${k8s_minor}.x series (current: ${current_k8s_ver})..."

latest_k8s_ver=$(curl -sf "https://dl.k8s.io/release/stable-${k8s_minor}.txt")

if [[ -z "$latest_k8s_ver" ]]; then
echo "Could not fetch latest Kubernetes ${k8s_minor}.x version"
else
# Strip "v" prefix: v1.33.9 -> 1.33.9
latest_k8s_ver="${latest_k8s_ver#v}"

if [[ "$latest_k8s_ver" != "$current_k8s_ver" ]]; then
echo "Kubernetes update available: ${current_k8s_ver} -> ${latest_k8s_ver}"

yq -i ".kubernetes.version = \"${latest_k8s_ver}\"" "$ver_file"

updates="${updates}Kubernetes: ${current_k8s_ver} -> ${latest_k8s_ver}\n"
else
echo "Kubernetes is up to date (${current_k8s_ver})"
fi
fi

# --- Summary ---

if [[ -n "$updates" ]]; then
echo ""
echo "UPDATES_SUMMARY_START"
echo -e "$updates"
echo "UPDATES_SUMMARY_END"
fi