|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +# This script is used to generate the changelog for an FBC image. |
| 4 | +# You can call it locally with 2 commit hashes to see the changes between them. |
| 5 | +# e.g: |
| 6 | +# ./changelog.sh <old-commit> <new-commit> |
| 7 | +# Where <old-commit> and <new-commit> are git commit hashes for changes to the |
| 8 | +# catalog-template.yaml file. |
| 9 | +# |
| 10 | +# If no arguments are provided, it will retrieve the latest built image's git tag |
| 11 | +# and generate the changelog since that tag up to HEAD. |
| 12 | +# This method is used in the build system to generate a changelog file that will |
| 13 | +# be included in the built image. |
| 14 | +# |
| 15 | + |
| 16 | +#set -x |
| 17 | + |
| 18 | +# Takes an image reference with digest, and looks at the quay.io repository |
| 19 | +# for all the tags that point to the same image digest. |
| 20 | +# One of those tags is expected to be the git tag used to build the image. |
| 21 | +# |
| 22 | +# See quay.io API docs for more details: |
| 23 | +# https://docs.quay.io/api/swagger/ |
| 24 | +function get_commit_for_image() { |
| 25 | + if [ -z "$1" ]; then |
| 26 | + echo "HEAD" |
| 27 | + return |
| 28 | + fi |
| 29 | + |
| 30 | + # Convert the reference to the quay.io api URL format |
| 31 | + IMAGE_REF=${1/registry.redhat.io\/openshift-sandboxed-containers\//quay.io\/api\/v1\/repository\/redhat-user-workloads\/ose-osc-tenant\/} |
| 32 | + # remove "-rhel9" from image names |
| 33 | + IMAGE_REF=$(echo $IMAGE_REF | sed 's/-rhel9//') |
| 34 | + |
| 35 | + IMAGE_NAME=$(echo "$IMAGE_REF" | cut -d "@" -f 1) |
| 36 | + IMAGE_DIGEST=$(echo "$IMAGE_REF" | cut -d "@" -f 2) |
| 37 | + |
| 38 | + # As the quay.io API is paginated, we need to make a loop until we find |
| 39 | + # the image we're looking for. |
| 40 | + PAGE=1 |
| 41 | + while true; do |
| 42 | + RESPONSE=$(curl -s "https://$IMAGE_NAME/tag/?limit=100&page=${PAGE}") |
| 43 | + if [ $? -ne 0 ]; then |
| 44 | + # Image not found? |
| 45 | + echo "Error: Failed to retrieve tags from quay.io for image $IMAGE_NAME" >&2 |
| 46 | + break |
| 47 | + fi |
| 48 | + TAGS=$(echo "$RESPONSE" | jq -r '.tags[] | select(.manifest_digest=="'"$IMAGE_DIGEST"'") | .name') |
| 49 | + if [ -n "$TAGS" ]; then |
| 50 | + # found some tags for our image |
| 51 | + for TAG in $TAGS; do |
| 52 | + # Check if the tag looks like a git commit hash (7 to 40 hex characters) |
| 53 | + if [[ $TAG =~ ^[0-9a-f]{7,40}$ ]]; then |
| 54 | + echo "$TAG" |
| 55 | + return |
| 56 | + fi |
| 57 | + done |
| 58 | + fi |
| 59 | + PAGE=$((PAGE + 1)) |
| 60 | + done |
| 61 | +} |
| 62 | + |
| 63 | +function get_repo_for_image() { |
| 64 | + COMPONENT=$(echo "$1" | sed 's/registry.redhat.io\/openshift-sandboxed-containers\///' | sed 's/-rhel9//' | cut -d "@" -f 1) |
| 65 | + case "$COMPONENT" in |
| 66 | + "osc-operator" | "osc-must-gather" | "osc-podvm-builder") |
| 67 | + echo "https://github.com/openshift/sandboxed-containers-operator" |
| 68 | + ;; |
| 69 | + "osc-caa" | "osc-caa-webhook" | "osc-podvm-payload") |
| 70 | + echo "https://github.com/openshift/cloud-api-adaptor" |
| 71 | + ;; |
| 72 | + "osc-monitor") |
| 73 | + echo "https://github.com/openshift/kata-containers" |
| 74 | + ;; |
| 75 | + "osc-dm-verity-image") |
| 76 | + echo "https://github.com/confidential-devhub/coco-podvm-scripts" |
| 77 | + ;; |
| 78 | + "osc-pccs" | "osc-tdx-qgs" | "osc-storage-helper") |
| 79 | + echo "https://github.com/openshift/confidential-compute-artifacts" |
| 80 | + ;; |
| 81 | + esac |
| 82 | +} |
| 83 | + |
| 84 | +if [ "$#" -eq 2 ]; then |
| 85 | + OLD_COMMIT=$1 |
| 86 | + NEW_COMMIT=$2 |
| 87 | +else |
| 88 | + # retrieve the git tag used to build the latest image |
| 89 | + echo "No commit range provided, retrieving latest built image commit" |
| 90 | + OLD_COMMIT=$(skopeo inspect "docker://quay.io/redhat-user-workloads/ose-osc-tenant/osc-test-fbc:latest" | jq -r '.Labels["org.opencontainers.image.revision"]') |
| 91 | + NEW_COMMIT=HEAD |
| 92 | +fi |
| 93 | + |
| 94 | +# Get the bundle references for old and new commits |
| 95 | +OLD_BUNDLE=$(git show "${OLD_COMMIT}" catalog-template.yaml | grep -E '^\+ - image:'| awk '{print $NF}') |
| 96 | +NEW_BUNDLE=$(git show "${NEW_COMMIT}" catalog-template.yaml | grep -E '^\+ - image:'| awk '{print $NF}') |
| 97 | + |
| 98 | +# Retrieve the commit hashes for old and new bundles |
| 99 | +OLD_BUNDLE_COMMIT=$(get_commit_for_image $OLD_BUNDLE) |
| 100 | +NEW_BUNDLE_COMMIT=$(get_commit_for_image $NEW_BUNDLE) |
| 101 | + |
| 102 | +# Generate the list of commits between the two bundle |
| 103 | +COMMIT_LIST=$(git log --oneline "${OLD_BUNDLE_COMMIT}..${NEW_BUNDLE_COMMIT}" ../../bundle/manifests/sandboxed-containers-operator.clusterserviceversion.yaml | awk '{print $1}') |
| 104 | + |
| 105 | +echo "Generating changelog between bundle commits $OLD_BUNDLE_COMMIT and $NEW_BUNDLE_COMMIT" | tee CHANGELOG |
| 106 | +for COMMIT in $COMMIT_LIST; do |
| 107 | + # each bundle commit should have exactly one image change |
| 108 | + # extract old and new image references, and get their commit hashes |
| 109 | + OLD_IMAGE=$(git show $COMMIT | grep "image:" | grep -E '^-' -m 1 | awk '{print $NF}') |
| 110 | + NEW_IMAGE=$(git show $COMMIT | grep "image:" | grep -E '^\+' -m 1 | awk '{print $NF}') |
| 111 | + |
| 112 | + echo "Changes in commit $COMMIT:" | tee -a CHANGELOG |
| 113 | + echo "From image: $OLD_IMAGE" | tee -a CHANGELOG |
| 114 | + echo "To image: $NEW_IMAGE" | tee -a CHANGELOG |
| 115 | + |
| 116 | + OLD_IMAGE_COMMIT=$(get_commit_for_image $OLD_IMAGE) |
| 117 | + NEW_IMAGE_COMMIT=$(get_commit_for_image $NEW_IMAGE) |
| 118 | + |
| 119 | + REPO=$(get_repo_for_image $OLD_IMAGE) |
| 120 | + echo "Looking at commits from the repo $REPO" | tee -a CHANGELOG |
| 121 | + echo "between $OLD_IMAGE_COMMIT and $NEW_IMAGE_COMMIT" | tee -a CHANGELOG |
| 122 | + |
| 123 | + PATH_PREFIX="" |
| 124 | + if [ "$REPO" != "https://github.com/openshift/sandboxed-containers-operator" ]; then |
| 125 | + # Do not clone sandboxed-containers-operator: that's the local repo already! |
| 126 | + git clone $REPO |
| 127 | + pushd $(basename $REPO) |
| 128 | + PATH_PREFIX="../" |
| 129 | + fi |
| 130 | + |
| 131 | + git log --oneline $OLD_IMAGE_COMMIT..$NEW_IMAGE_COMMIT | tee -a ${PATH_PREFIX}CHANGELOG |
| 132 | + if [ "$REPO" != "https://github.com/openshift/sandboxed-containers-operator" ]; then |
| 133 | + popd |
| 134 | + rm -rf $(basename $REPO) |
| 135 | + fi |
| 136 | + echo "" | tee -a CHANGELOG |
| 137 | +done |
0 commit comments