Skip to content

Conversation

@unixtech-06
Copy link

Closes #60

Add RPM diff generation and GitHub Release automation to CI

  • Detect previous dated image tags with skopeo and compare RPM lists
  • Generate Markdown changelog (Added / Updated / Removed) per platform
  • Publish combined RPM diff as GitHub Release with attached artifacts
  • Mark release as pre-release when pushing to testing registries

@alexiri
Copy link
Member

alexiri commented Oct 4, 2025

Great work!

For the atomic-desktop images, this changelog is generated by the rechunker, which is very useful. One of the things it does is attach the full package list (ie. your rpm_lists/.../*.txt) as a label to the container image itself. You can see it here, for example:

skopeo inspect docker://quay.io/almalinuxorg/atomic-desktop-gnome:10 | jq '.Labels["dev.hhd.rechunk.info"]'

How about doing this instead? This is kind of like a poor man's SBOM, and since it's tied to the image it makes it much easier for you to get the information of the previous released image and it also makes the information available for other future uses.

delc=$(wc -l < removed.tmp | tr -d ' ')
echo "" >> "${out}"
echo "**Added (${addc})**" >> "${out}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about skipping the sections altogether if there are no packages in that category?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion
I’ve updated the changelog generation so that it now skips any Added / Updated / Removed section when the count is zero

run: |
IMAGE_REPO="${IMAGE_NAMES%%,*}"
# Fetch tag list and pick latest dated tag (<today): <VMJ><VMIN>-YYYYMMDD
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just use the current ${VMJ} tag, which should always be the latest released tag?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing this out
I had overlooked that the ${VMJ} tag is always kept up to date with the latest release
I’ve updated the workflow to simply use ${VMJ} as the comparison base instead of scanning dated tags

@unixtech-06 unixtech-06 force-pushed the changelog-clean branch 5 times, most recently from c49569a to 5ebb806 Compare October 7, 2025 03:58
echo "Checking ${IMAGE_REPO}:${PREV_TAG}"
if ! skopeo inspect docker://"${IMAGE_REPO}:${PREV_TAG}" >/dev/null 2>&1; then
echo "::error ::Tag not found: ${IMAGE_REPO}:${PREV_TAG}"
exit 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes it impossible for the workflow to run the first time, when there's no previous tag. Not too relevant now that it exists, but still...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated the step so the workflow won’t fail on the very first run when there’s no previous tag

@unixtech-06 unixtech-06 force-pushed the changelog-clean branch 2 times, most recently from 97f081e to d299edb Compare October 8, 2025 01:39
… loop

ci: switch <details> blocks to printf and always close after platform loop
@unixtech-06
Copy link
Author

unixtech-06 commented Oct 9, 2025

Great work!

For the atomic-desktop images, this changelog is generated by the rechunker, which is very useful. One of the things it does is attach the full package list (ie. your rpm_lists/.../*.txt) as a label to the container image itself. You can see it here, for example:

skopeo inspect docker://quay.io/almalinuxorg/atomic-desktop-gnome:10 | jq '.Labels["dev.hhd.rechunk.info"]'

How about doing this instead? This is kind of like a poor man's SBOM, and since it's tied to the image it makes it much easier for you to get the information of the previous released image and it also makes the information available for other future uses.

I agree that this approach makes perfect sense.

Here’s what I’m thinking:

  • For each platform, generate a rechunker-style JSON that includes the full RPM list, its SHA256, and metadata such as built_at and prev_tag.
  • Compress the JSON with gzip + base64 and store it in an environment variable RCHUNK_INFO_LABEL.
  • During the final image push step, add the label as follows:
    dev.hhd.rechunk.info=${{ env.RCHUNK_INFO_LABEL }} (specified in docker/build-push-action@v5 under labels:).
  • The label can be verified in the same way as the atomic-desktop images:
    skopeo inspect docker://<registry>/<repo>:<tag> \
      | jq -r '.Labels["dev.hhd.rechunk.info"]' \
      | base64 -d | gzip -d | jq .

…iner images

feat: embed rechunker-style RPM metadata as compressed label in container images
IMT: ${{ matrix.image_types }}
PREV_TAG: ${{ env.prev_tag }}
DTS: ${{ needs.init-data.outputs.date_time_stamp }}
LABEL_KEY: dev.hhd.rechunk.info
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dev.hdd.rechunk.info isn't a standardized label or anything, and given the format is different maybe we shouldn't use the same label. How about org.almalinux.sbom? Reference: https://github.com/opencontainers/image-spec/blob/main/annotations.md

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds good
I'll use org.almalinux.sbom instead.

rm -f pkgs_${key}.json
done
# Compress and encode JSON into a single-line lable payload
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Compress and encode JSON into a single-line lable payload
# Compress and encode JSON into a single-line label payload

push: true
tags: ${{ steps.meta.outputs.tags }}
labels: |
${{ env.LABLE_KEY }}=${{ env.RCHUNK_INFO_LABEL }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
${{ env.LABLE_KEY }}=${{ env.RCHUNK_INFO_LABEL }}
${{ env.LABEL_KEY }}=${{ env.RCHUNK_INFO_LABEL }}

# Old image (if present): <image>:<tag>
if [ -n "${IMG_PREV:-}" ] && [ -n "${TAG_PREV:-}" ]; then
docker pull --platform "${plat}" "${IMG_PREV}:${TAG_PREV}" >/dev/null 2>&1 || true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to run the previous image and extract the list of packages again, now that it's attached as a label you could just get it from there. If you use crane, you can even get the label without having to pull the image!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll switch to using crane.
It seems that crane isn’t included in the default ubuntu-latest runner image, so I’ll add installation steps for it as well.
https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md

done
# Compress and encode JSON into a single-line lable payload
RCHUNK_INFO_LABEL=$(gzip -c "rechunk_${VMJ}_${IMT}.json" | base64 -w0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand wanting to reduce the size of this data, but making it binary makes it a bit less useful. It adds an extra couple of steps to be able to read and use it. There's no limit to the value size (as far as I can tell), so why not just store the json directly?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ll change it to store the JSON directly in the label instead of encoding it.

…ing old image

ci: read previous RPM list from image label via crane instead of running old image

ci: read previous RPM list from image label via crane instead of running old image

ci: read previous RPM list from image label via crane instead of running old image

ci: read previous RPM list from image label via crane instead of running old image
@alexiri
Copy link
Member

alexiri commented Oct 9, 2025

This looks great! Are you running it anywhere so we can verify everything works as expected and looks good?

@unixtech-06
Copy link
Author

This looks great! Are you running it anywhere so we can verify everything works as expected and looks good?

I'll try it out in my own repository by creating a new branch for testing.

@unixtech-06
Copy link
Author

The workflow ran successfully and generated the changelog correctly.
The result is available here:
https://github.com/unixtech-06/container-images/releases/tag/v20251010

@alexiri
Copy link
Member

alexiri commented Oct 15, 2025

Hi @unixtech-06, please take a look at this conversation: https://chat.almalinux.org/almalinux/pl/yuun4ire5jbibxtid1mfubgzfy

Now would be a great opportunity to standardize on the same SBOM format for all AlmaLinux images!

@unixtech-06
Copy link
Author

unixtech-06 commented Oct 21, 2025

Hi @unixtech-06, please take a look at this conversation: https://chat.almalinux.org/almalinux/pl/yuun4ire5jbibxtid1mfubgzfy

Now would be a great opportunity to standardize on the same SBOM format for all AlmaLinux images!

Sorry, I was mistaken earlier.

After thinking about it, the current rpm-based implementation doesn’t work for micro anyway since it doesn’t include the rpm command.
So for now, I think it’s fine to generate SBOMs for the other container images (excluding micro) by mounting their rootfs externally and using this script.

@alexiri
Copy link
Member

alexiri commented Dec 16, 2025

@javihernandez, what do you think, good to go with the SBOM?

@javihernandez
Copy link
Member

javihernandez commented Dec 17, 2025

@javihernandez, what do you think, good to go with the SBOM?

Hey, currently, the sbom tools are not part of the cloud images pipelines, its inclusion in the gcp images pipelines is being finalized as part of AlmaLinux/cloud-images#266.

In any case, yes, I think that we can proceed with the SBOM tools approach. For that, @unixtech-06 needs to:

  1. Create a PR with the rpm bindings fallback changes in https://github.com/AlmaLinux/cloud-images-sbom-tools
  2. Update this PR accordingly. Please check the GCP images PR above for inspiration on how to include the tools into the container images pipeline(s)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add CI to automatically generate changelog for image releases

3 participants