Compare commits

..

1 Commits

Author SHA1 Message Date
Paulo Santos 38a1da19ee add image version check script 2025-12-12 16:57:07 +00:00
2 changed files with 325 additions and 26 deletions
+294
View File
@@ -0,0 +1,294 @@
#!/usr/bin/env bash
################################################################################
## File: diff-image-versions.sh
## Desc: Compare software versions between two runner image releases
## Usage: ./diff-image-versions.sh <os-name> <version1> <version2>
##
## Example:
## ./diff-image-versions.sh ubuntu22 20251102.127 20251125.163
## ./diff-image-versions.sh win25 20251102.77 20251125.122
## ./diff-image-versions.sh macos-14 20251102.0024 20251125.0031
################################################################################
set -euo pipefail
usage() {
cat <<EOF
Usage: $(basename "${0}") <os-name> <version1> <version2>
Compare runner image versions and display software changes.
Arguments:
os-name OS identifier (ubuntu22, ubuntu24, win19, win22, win25,
macos-13, macos-14, macos-15, or arm64 variants)
version1 Earlier version (YYYYMMDD.NNN)
version2 Later version (YYYYMMDD.NNN)
Examples:
$(basename "${0}") ubuntu22 20251102.127 20251125.163
$(basename "${0}") win25 20251102.77 20251125.122
EOF
}
get_readme_path() {
local os_name="${1}"
local os_folder=""
local pattern=""
# Determine OS folder and readme filename pattern
case "${os_name}" in
ubuntu*)
os_folder="ubuntu"
local version="${os_name#ubuntu}"
pattern="Ubuntu${version}04-Readme.md"
;;
win*)
os_folder="windows"
local version="${os_name#win}"
pattern="Windows20${version}-Readme.md"
;;
macos*)
os_folder="macos"
pattern="${os_name}-Readme.md"
;;
*)
echo "Error: Unknown OS '${os_name}'" >&2
echo "Valid: ubuntu*, win*, macos-*" >&2
return 1
;;
esac
local readme_path="images/${os_folder}/${pattern}"
# Verify file exists in git repository
if ! git cat-file -e "HEAD:${readme_path}" 2>/dev/null; then
echo "Error: Readme not found: ${readme_path}" >&2
return 1
fi
echo "${readme_path}"
}
validate_version() {
local version="${1}"
if [[ ! "${version}" =~ ^[0-9]{8}\.[0-9]+$ ]]; then
echo "Error: Invalid version '${version}'" >&2
echo "Format: YYYYMMDD.NNN (e.g., 20251102.127)" >&2
return 1
fi
return 0
}
tag_exists() {
local tag="${1}"
if git rev-parse "${tag}" >/dev/null 2>&1; then
return 0
else
echo "Error: Tag '${tag}' not found" >&2
return 1
fi
}
main() {
# Check arguments
if [[ $# -ne 3 ]]; then
usage
return 1
fi
local os_name="${1}"
local version1="${2}"
local version2="${3}"
# Validate inputs
validate_version "${version1}" || return 1
validate_version "${version2}" || return 1
# Get readme path
local readme_path
readme_path="$(get_readme_path "${os_name}")" || return 1
# Construct git tags
local tag1="${os_name}/${version1}"
local tag2="${os_name}/${version2}"
# Verify tags exist
tag_exists "${tag1}" || return 1
tag_exists "${tag2}" || return 1
# Get release dates
local date1
local date2
date1=$(git log -1 --format="%ci" "${tag1}" | cut -d' ' -f1)
date2=$(git log -1 --format="%ci" "${tag2}" | cut -d' ' -f1)
# Calculate days between releases
local days_diff
days_diff=$(( ($(date -d "${date2}" +%s) - $(date -d "${date1}" +%s)) / 86400 ))
# Display header
echo "================================================================================"
echo "Comparing: ${os_name}"
echo " From: ${version1} (${date1})"
echo " To: ${version2} (${date2})"
echo " Span: ${days_diff} days"
echo "================================================================================"
echo ""
# Perform diff with minimal context (only changed lines with colors)
# ANSI codes: ^[[31m (red for -), ^[[32m (green for +), ^[[36m (cyan for @@)
# Filter to show only lines starting with red/green (additions/deletions)
local diff_output
diff_output=$(git diff --color=always --unified=0 "${tag1}:${readme_path}" "${tag2}:${readme_path}" | \
grep -E $'^\x1b\\[(31|32)m' | \
grep -v -E $'^\x1b\\[1m(---|\\+\\+\\+)')
if [[ -n "${diff_output}" ]]; then
# Extract announcements from both versions
local announcements1
local announcements2
announcements1=$(git show "${tag1}:${readme_path}" | sed -n '/| Announcements |/,/^\*\*\*$/p' | grep -E '^\| \[' | sed 's/^| \[/• [/' | sed 's/ |$//' || true)
announcements2=$(git show "${tag2}:${readme_path}" | sed -n '/| Announcements |/,/^\*\*\*$/p' | grep -E '^\| \[' | sed 's/^| \[/• [/' | sed 's/ |$//' || true)
# Show announcement changes
if [[ "${announcements1}" != "${announcements2}" ]]; then
echo "📢 Announcement Changes:"
echo "────────────────────────────────────────────────────────────────────────────────"
if [[ -n "${announcements2}" ]]; then
echo "${announcements2}"
else
echo "(no announcements)"
fi
echo "────────────────────────────────────────────────────────────────────────────────"
echo ""
fi
# Extract cached tools sections
local cached_tools1
local cached_tools2
cached_tools1=$(git show "${tag1}:${readme_path}" | sed -n '/^### Cached Tools$/,/^###[^#]/p' | head -n -1 || true)
cached_tools2=$(git show "${tag2}:${readme_path}" | sed -n '/^### Cached Tools$/,/^###[^#]/p' | head -n -1 || true)
# Show cached tools changes
if [[ "${cached_tools1}" != "${cached_tools2}" ]]; then
local cached_diff
cached_diff=$(git diff --color=always --unified=2 --no-index \
<(echo "${cached_tools1}") <(echo "${cached_tools2}") 2>/dev/null | \
grep -E $'(^\x1b\\[(31|32)m[-+]| #### )' | \
sed -r 's/\x1b\[m$//' || true)
if [[ -n "${cached_diff}" ]]; then
echo "🔧 Cached Tools Changes (setup-* actions):"
echo "────────────────────────────────────────────────────────────────────────────────"
echo "${cached_diff}"
echo "────────────────────────────────────────────────────────────────────────────────"
echo ""
fi
fi
echo "Full Diff:"
echo "────────────────────────────────────────────────────────────────────────────────"
echo "${diff_output}"
echo "────────────────────────────────────────────────────────────────────────────────"
echo ""
# Count changes
local changes
changes=$(echo "${diff_output}" | wc -l)
echo "Changes: ${changes} lines"
# Parse version changes for breaking change analysis
local breaking_changes=()
local removals=()
local additions=()
# Extract clean lines (strip ANSI codes)
while IFS= read -r line; do
if [[ "${line}" =~ ^\-(.+)$ ]]; then
removals+=("${BASH_REMATCH[1]}")
elif [[ "${line}" =~ ^\+(.+)$ ]]; then
additions+=("${BASH_REMATCH[1]}")
fi
done < <(echo "${diff_output}" | sed -r 's/\x1b\[[0-9;]*m//g')
# Detect breaking changes
for removed in "${removals[@]}"; do
local tool_name=""
local old_version=""
local found_match=false
# Try to extract tool name and version (handle various formats)
if [[ "${removed}" =~ ^([^0-9]+[[:space:]]+)([0-9]+\.[0-9]+[^[:space:]]*) ]]; then
tool_name="${BASH_REMATCH[1]}"
old_version="${BASH_REMATCH[2]}"
elif [[ "${removed}" =~ ^([^0-9]+[[:space:]]+v)([0-9]+\.[0-9]+[^[:space:]]*) ]]; then
tool_name="${BASH_REMATCH[1]}"
old_version="${BASH_REMATCH[2]}"
fi
# If we found a semver-style version, look for matching addition
if [[ -n "${tool_name}" && -n "${old_version}" ]]; then
for added in "${additions[@]}"; do
if [[ "${added}" =~ ^${tool_name}([0-9]+\.[0-9]+[^[:space:]]*) ]]; then
local new_version="${BASH_REMATCH[1]}"
found_match=true
# Extract major version for semver comparison
if [[ "${old_version}" =~ ^([0-9]+)\. && "${new_version}" =~ ^([0-9]+)\. ]]; then
local old_major="${BASH_REMATCH[1]}"
local new_major="${BASH_REMATCH[1]}"
[[ "${old_version}" =~ ^([0-9]+)\. ]] && old_major="${BASH_REMATCH[1]}"
[[ "${new_version}" =~ ^([0-9]+)\. ]] && new_major="${BASH_REMATCH[1]}"
if [[ ${new_major} -gt ${old_major} ]]; then
breaking_changes+=("🔴 ${tool_name}${old_version}${new_version} (major version bump)")
fi
fi
break
fi
done
fi
# If no match found and looks like a versioned tool, it's a removal
if [[ ${found_match} == false && -n "${old_version}" ]]; then
breaking_changes+=("${removed} (removed)")
elif [[ ${found_match} == false && "${removed}" =~ [0-9]+\.[0-9]+ ]]; then
breaking_changes+=("${removed} (removed)")
fi
done
# Display breaking changes
if [[ ${#breaking_changes[@]} -gt 0 ]]; then
echo ""
echo "⚠️ Breaking changes detected (${#breaking_changes[@]}):"
echo "--------------------------------------------------------------------------------"
printf '%s\n' "${breaking_changes[@]}"
echo "--------------------------------------------------------------------------------"
fi
else
echo "No changes found."
fi
# Display PR link and commit count
local pr_number
pr_number=$(git log --all --format="%s" --grep="${version2}" | \
grep -oP '\(#\K[0-9]+(?=\))' | head -1)
local commit_count
commit_count=$(git rev-list --count "${tag1}..${tag2}")
echo "Commits: ${commit_count}"
if [[ -n "${pr_number}" ]]; then
echo "PR: https://github.com/actions/runner-images/pull/${pr_number}"
fi
return 0
}
# Execute main function
main "$@"
+31 -26
View File
@@ -1,16 +1,20 @@
| Announcements |
|-|
| [[Ubuntu & Windows] Four tools scheduled for deprecation on November 3, 2025](https://github.com/actions/runner-images/issues/12898) |
***
# Windows Server 2025
- OS Version: 10.0.26100 Build 7171
- Image Version: 20251208.136.1
- Image Version: 20251125.122.1
## Windows features
- Windows Subsystem for Linux (WSLv1): Enabled
- Windows Subsystem for Linux (Default, WSLv2): 2.6.2.0
- Windows Subsystem for Linux (Default, WSLv2): 2.6.1.0
## Installed Software
### Language and Runtime
- Bash 5.2.37(1)-release
- Go 1.24.11
- Go 1.24.10
- Julia 1.12.0
- Kotlin 2.2.21
- LLVM 20.1.8
@@ -21,16 +25,16 @@
- Ruby 3.3.10
### Package Management
- Chocolatey 2.6.0
- Chocolatey 2.5.1
- Composer 2.9.2
- Helm 4.0.0
- Miniconda 25.9.1 (pre-installed on the image but not added to PATH)
- NPM 10.9.4
- NuGet 7.0.1.1
- NuGet 7.0.0.289
- pip 25.3 (python 3.9)
- Pipx 1.8.0
- RubyGems 3.5.22
- Vcpkg (build from commit 52f93a645e)
- Vcpkg (build from commit 9aee6e968f)
- Yarn 1.22.22
#### Environment variables
@@ -54,14 +58,14 @@
- Bicep 0.39.26
- Cabal 3.16.0.0
- CMake 3.31.6
- CodeQL Action Bundle 2.23.7
- CodeQL Action Bundle 2.23.6
- Docker 27.5.1
- Docker Compose v2 2.32.2
- Docker-wincred 0.9.4
- ghc 9.12.2
- Git 2.52.0.windows.1
- Git LFS 3.7.1
- ImageMagick 7.1.2-9
- ImageMagick 7.1.2-8
- InnoSetup 6.6.1
- jq 1.8.1
- Kind 0.30.0
@@ -72,7 +76,7 @@
- Newman 6.2.1
- OpenSSL 3.6.0
- Packer 1.14.2
- Pulumi 3.210.0
- Pulumi 3.207.0
- R 4.5.2
- Service Fabric SDK 10.1.2493.9590
- Stack 3.7.1
@@ -85,10 +89,10 @@
- Ninja 1.13.2
### CLI Tools
- AWS CLI 2.32.11
- AWS SAM CLI 1.150.1
- AWS CLI 2.32.4
- AWS SAM CLI 1.148.0
- AWS Session Manager CLI 1.2.764.0
- Azure CLI 2.81.0
- Azure CLI 2.80.0
- Azure DevOps CLI extension 1.0.2
- GitHub CLI 2.83.1
@@ -103,14 +107,14 @@
- Rustfmt 1.8.0
### Browsers and Drivers
- Google Chrome 143.0.7499.41
- Chrome Driver 143.0.7499.40
- Microsoft Edge 143.0.3650.66
- Microsoft Edge Driver 143.0.3650.66
- Google Chrome 142.0.7444.176
- Chrome Driver 142.0.7444.175
- Microsoft Edge 142.0.3595.94
- Microsoft Edge Driver 142.0.3595.94
- Mozilla Firefox 145.0.2
- Gecko Driver 0.36.0
- IE Driver 4.14.0.0
- Selenium server 4.39.0
- Selenium server 4.38.0
#### Environment variables
| Name | Value |
@@ -151,11 +155,11 @@ Note: MSYS2 is pre-installed on image but not added to PATH.
#### Go
- 1.22.12
- 1.23.12
- 1.24.11
- 1.25.5
- 1.24.10
- 1.25.4
#### Node.js
- 20.19.6
- 20.19.5
- 22.21.1
- 24.11.1
@@ -164,8 +168,8 @@ Note: MSYS2 is pre-installed on image but not added to PATH.
- 3.10.11
- 3.11.9
- 3.12.10
- 3.13.11
- 3.14.2
- 3.13.9
- 3.14.0
#### PyPy
- 3.9.19 [PyPy 7.3.16]
@@ -202,7 +206,7 @@ Note: MSYS2 is pre-installed on image but not added to PATH.
- SQL OLEDB Driver 18 18.7.5.0
- SQL OLEDB Driver 19 19.4.1.0
- SQLPS 1.0
- MongoDB Shell (mongosh) 2.5.10
- MongoDB Shell (mongosh) 2.5.9
### Web Servers
| Name | Version | ConfigFile | ServiceName | ServiceStatus | ListenPort |
@@ -435,7 +439,7 @@ Note: MSYS2 is pre-installed on image but not added to PATH.
| wasm.tools | 9.0.1125.51309 |
| ProBITools.MicrosoftAnalysisServicesModelingProjects2022 | 4.0.0 |
| ProBITools.MicrosoftReportProjectsforVisualStudio2022 | 4.0.0 |
| SSIS.MicrosoftDataToolsIntegrationServices | 2.1.2 |
| SSIS.MicrosoftDataToolsIntegrationServices | 2.0 |
| VisualStudioClient.MicrosoftVisualStudio2022InstallerProjects | 2.0.1 |
| Windows Driver Kit Visual Studio Extension | 10.0.26100.15 |
| Windows Software Development Kit | 10.1.26100.6901 |
@@ -469,7 +473,7 @@ Note: MSYS2 is pre-installed on image but not added to PATH.
#### Powershell Modules
- Az: 12.5.0
- AWSPowershell: 5.0.111
- AWSPowershell: 5.0.104
- DockerMsftProvider: 1.0.0.8
- MarkdownPS: 1.10
- Microsoft.Graph: 2.32.0
@@ -484,7 +488,7 @@ Note: MSYS2 is pre-installed on image but not added to PATH.
| Package Name | Version |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Android Command Line Tools | 16.0 |
| Android Emulator | 36.3.10 |
| Android Emulator | 36.2.12 |
| Android SDK Build-tools | 36.0.0 36.1.0<br>35.0.0 35.0.1<br>34.0.0 |
| Android SDK Platforms | android-36.1 (rev 1)<br>android-36-ext19 (rev 1)<br>android-36-ext18 (rev 1)<br>android-36 (rev 2)<br>android-35-ext15 (rev 1)<br>android-35-ext14 (rev 1)<br>android-35 (rev 2)<br>android-34-ext8 (rev 1)<br>android-34-ext12 (rev 1)<br>android-34-ext11 (rev 1)<br>android-34-ext10 (rev 1)<br>android-34 (rev 3) |
| Android SDK Platform-Tools | 36.0.0 |
@@ -503,3 +507,4 @@ Note: MSYS2 is pre-installed on image but not added to PATH.
| ANDROID_NDK_LATEST_HOME | C:\Android\android-sdk\ndk\29.0.14206865 |
| ANDROID_NDK_ROOT | C:\Android\android-sdk\ndk\27.3.13750724 |
| ANDROID_SDK_ROOT | C:\Android\android-sdk |