#!/usr/bin/env bash set -euo pipefail IMAGE="$1" VERSION="$2" # Always absolute path ROOTFS="${GITHUB_WORKSPACE}/images/${IMAGE}/rootfs" CHANGELOG_DIR="changelogs/${IMAGE}" mkdir -p "${CHANGELOG_DIR}" PKG_CUR="${CHANGELOG_DIR}/packages-current.txt" PKG_PREV="${CHANGELOG_DIR}/packages-latest.txt" BUILD_ID="$(cat .buildid)" CHANGELOG_FILE="${CHANGELOG_DIR}/${VERSION}.${BUILD_ID}.json" # Extract package list (name + evr) rpm -qa --root "${ROOTFS}" --qf '%{NAME} %{EVR}\n' | sort > "${PKG_CUR}" if [[ -f "${PKG_PREV}" ]]; then # Extract names only CUR_NAMES="$(cut -d' ' -f1 "${PKG_CUR}" | sort)" PREV_NAMES="$(cut -d' ' -f1 "${PKG_PREV}" | sort)" # Safe comm calls (|| true prevents exit 1) ADDED_NAMES="$(comm -13 <(echo "${PREV_NAMES}") <(echo "${CUR_NAMES}") || true)" REMOVED_NAMES="$(comm -23 <(echo "${PREV_NAMES}") <(echo "${CUR_NAMES}") || true)" COMMON_NAMES="$(comm -12 <(echo "${PREV_NAMES}") <(echo "${CUR_NAMES}") || true)" ADDED_LIST=() while read -r name; do [[ -z "$name" ]] && continue ver="$(grep -E "^${name} " "${PKG_CUR}" | awk '{print $2}')" ADDED_LIST+=("${name} ${ver}") done <<< "${ADDED_NAMES}" REMOVED_LIST=() while read -r name; do [[ -z "$name" ]] && continue ver="$(grep -E "^${name} " "${PKG_PREV}" | awk '{print $2}')" REMOVED_LIST+=("${name} ${ver}") done <<< "${REMOVED_NAMES}" UPDATED_LIST=() while read -r name; do [[ -z "$name" ]] && continue old_ver="$(grep -E "^${name} " "${PKG_PREV}" | awk '{print $2}')" new_ver="$(grep -E "^${name} " "${PKG_CUR}" | awk '{print $2}')" if [[ "${old_ver}" != "${new_ver}" ]]; then UPDATED_LIST+=("${name} ${old_ver} -> ${new_ver}") fi done <<< "${COMMON_NAMES}" ADDED_COUNT="${#ADDED_LIST[@]}" REMOVED_COUNT="${#REMOVED_LIST[@]}" UPDATED_COUNT="${#UPDATED_LIST[@]}" { echo "{" echo " \"image\": \"${IMAGE}\"," echo " \"version\": \"${VERSION}\"," echo " \"build_id\": \"${BUILD_ID}\"," echo " \"added_count\": ${ADDED_COUNT}," echo " \"removed_count\": ${REMOVED_COUNT}," echo " \"updated_count\": ${UPDATED_COUNT}," echo " \"added\": [" for i in "${!ADDED_LIST[@]}"; do sep=$([[ $i -lt $((ADDED_COUNT-1)) ]] && echo "," || echo "") printf ' "%s"%s\n' "${ADDED_LIST[$i]}" "${sep}" done echo " ]," echo " \"removed\": [" for i in "${!REMOVED_LIST[@]}"; do sep=$([[ $i -lt $((REMOVED_COUNT-1)) ]] && echo "," || echo "") printf ' "%s"%s\n' "${REMOVED_LIST[$i]}" "${sep}" done echo " ]," echo " \"updated\": [" for i in "${!UPDATED_LIST[@]}"; do sep=$([[ $i -lt $((UPDATED_COUNT-1)) ]] && echo "," || echo "") printf ' "%s"%s\n' "${UPDATED_LIST[$i]}" "${sep}" done echo " ]" echo "}" } > "${CHANGELOG_FILE}" else # First build: everything is added ADDED_LIST=() while read -r name ver; do ADDED_LIST+=("${name} ${ver}") done < "${PKG_CUR}" ADDED_COUNT="${#ADDED_LIST[@]}" { echo "{" echo " \"image\": \"${IMAGE}\"," echo " \"version\": \"${VERSION}\"," echo " \"build_id\": \"${BUILD_ID}\"," echo " \"added_count\": ${ADDED_COUNT}," echo " \"removed_count\": 0," echo " \"updated_count\": 0," echo " \"added\": [" for i in "${!ADDED_LIST[@]}"; do sep=$([[ $i -lt $((ADDED_COUNT-1)) ]] && echo "," || echo "") printf ' "%s"%s\n' "${ADDED_LIST[$i]}" "${sep}" done echo " ]," echo " \"removed\": []," echo " \"updated\": []" echo "}" } > "${CHANGELOG_FILE}" fi # Update latest snapshot mv "${PKG_CUR}" "${PKG_PREV}" echo "Changelog written to ${CHANGELOG_FILE}"