Skip to content

AlmaLinux 8 and 9, Container/Docker Images builder and uploader #335

AlmaLinux 8 and 9, Container/Docker Images builder and uploader

AlmaLinux 8 and 9, Container/Docker Images builder and uploader #335

name: AlmaLinux 8 and 9, Container/Docker Images builder and uploader
on:
workflow_dispatch:
inputs:
major_version:
description: 'AlmaLinux major version'
required: true
default: '9'
type: choice
options:
- 10
- 9
- 8
platform:
description: 'Comma-separated list of platforms: linux/amd64, linux/ppc64le, linux/s390x, linux/arm64'
required: true
default: 'linux/amd64, linux/arm64'
type_default:
description: 'default'
required: true
type: boolean
type_minimal:
description: 'minimal'
required: true
type: boolean
type_micro:
description: 'micro'
required: true
type: boolean
type_base:
description: 'base'
required: true
type: boolean
type_init:
description: 'init'
required: true
type: boolean
# image_types:
# description: 'Comma-separated list of image types (put each type in quotes): "default", "minimal", "micro", "base", "init"'
# required: true
# default: '"micro"'
# registry:
# description: 'Registry to push'
# required: true
# default: 'docker.io/ykohut'
# type: choice
# options:
# - docker.io/ykohut
# - quay.io/ykohut
# - ghcr.io/yuravk
registry:
description: 'Comma-separated list of registries: docker.io/ykohut, quay.io/ykohut, ghcr.io/yuravk'
required: true
default: 'docker.io/ykohut, quay.io/ykohut, ghcr.io/yuravk'
push:
description: 'Push to registries'
required: true
type: boolean
pr:
description: 'Create PR to Docker official'
required: true
type: boolean
env:
# VERSION_MINOR: ${{ inputs.major_version == '9' && '3' || '9' }}
REGISTRY_IMAGE: ykohut/almalinux
# docker-library/official-images
DOCKER_LIBRARY_OFFICIAL: LKHN/official-images
LOCAL_LIBRARY_OFFICIAL: ${{ github.actor }}/official-images
jobs:
build:
name: "Build ${{ inputs.major_version }} ${{ matrix.image_types }} for ${{ inputs.platform }} and push to all registries"
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# platform: ${{ fromJSON(format('[{0}]', inputs.platform || '"linux/amd64", "linux/ppc64le", "linux/s390x", "linux/arm64"')) }}
# - linux/amd64
# - linux/ppc64le
# - linux/s390x
# - linux/arm64
image_types: ${{ fromJSON(format('["{0}", "{1}", "{2}", "{3}", "{4}"]', ( inputs.type_default && 'default' ), ( inputs.type_minimal && 'minimal' ), ( inputs.type_micro && 'micro' ), ( inputs.type_base && 'base' ), ( inputs.type_init && 'init' ) )) }}
exclude:
- image_types: 'false'
steps:
-
name: "Set environment variables"
run: |
platform="$( echo '${{ inputs.platform }}' | sed 's/\//_/g' )"
echo "PLATFORM_PAIR=${platform//,/}" >> $GITHUB_ENV
-
name: "Prepare version minor number"
run: |
# set minor version
case ${{ inputs.major_version }} in
8)
VERSION_MINOR="9" ;;
9)
VERSION_MINOR="3" ;;
10)
VERSION_MINOR="0" ;;
esac
echo "VERSION_MINOR=${VERSION_MINOR}" >> $GITHUB_ENV
-
name: "Prepare date stamp"
id: date_stamp
run: |
# date stamp
STAMP=$(date '+%Y%m%d')
echo "STAMP=${STAMP}" >> $GITHUB_ENV
echo "::set-output name=date_stamp::${STAMP}"
-
name: "Prepare image names"
run: |
# list of registries to push to
REGISTRIES="${{ inputs.registry }}"
IMAGE_NAMES=
# generate image names in format $REGISTRY/almalinux or $REGISTRY/${{ inputs.major_version }}-${{ matrix.image_types }}
# image names are used by docker/metadata-action to set 'images'
for REGISTRY in ${REGISTRIES//,/ }; do
# 'default' images should not go to docker.io
[ "${{ matrix.image_types }}" = "default" ] && [[ $REGISTRY = *'docker'* ]] && continue
# 'default' images goes to $REGISTRY/almalinux
[ "${{ matrix.image_types }}" = "default" ] \
&& IMAGE_NAME="$REGISTRY/almalinux" \
|| IMAGE_NAME="$REGISTRY/${{ inputs.major_version }}-${{ matrix.image_types }}"
IMAGE_NAMES="${IMAGE_NAMES} ${IMAGE_NAME}"
unset IMAGE_NAME
done
# remove space at the beginning of string
IMAGE_NAMES=${IMAGE_NAMES# }
# separate with comma instead of space and export to the action
echo "IMAGE_NAMES=${IMAGE_NAMES// /,}" >> $GITHUB_ENV
echo
echo $IMAGE_NAMES
# -
# name: "Prepare tags"
# run: |
# # list of repositories to push
# REPOS=$( echo '${{ inputs.image_types }}' | tr -d '"')
# # list of registries to push to
# REGISTRIES="${{ inputs.registry }}"
# TAGS=
# # generate tags list in format $REGISTRY/${{ inputs.major_version }}-${REPO}:$TAG
# for REPO in ${REPOS//,/ }; do
# for REGISTRY in ${REGISTRIES//,/ }; do
# case ${{ matrix.image_types }} in
# default )
# # tags: MAJOR, MAJOR.MINOR
# TAGS="${TAGS} $REGISTRY/${{ inputs.major_version }}-${REPO}:${{ inputs.major_version }} $REGISTRY/${{ inputs.major_version }}-${REPO}:${{ inputs.major_version }}.${VERSION_MINOR}"
# # tags: MAJOR.MINOR-STAMP
# TAGS="${TAGS} $REGISTRY/${{ inputs.major_version }}-${REPO}:${{ inputs.major_version }}.${VERSION_MINOR}-${STAMP}"
# # tags: latest
# [ "${{ inputs.major_version }}" = "9" ] && TAGS="${TAGS} $REGISTRY/${{ inputs.major_version }}-${REPO}:latest"
# ;;
# * )
# # tags: MAJOR-TYPE, MAJOR.MINOR-TYPE
# TAGS="${TAGS} $REGISTRY/${{ inputs.major_version }}-${REPO}:${{ inputs.major_version }}-${{ matrix.image_types }} $REGISTRY/${{ inputs.major_version }}-${REPO}:${{ inputs.major_version }}.${VERSION_MINOR}-${{ matrix.image_types }}"
# # tags: MAJOR.MINOR-TYPE-STAMP
# TAGS="${TAGS} $REGISTRY/${{ inputs.major_version }}-${REPO}:${{ inputs.major_version }}.${VERSION_MINOR}-${{ matrix.image_types }}-${STAMP}"
# ;;
# esac
# done
# done
# # remove space at the beginning of string
# TAGS=${TAGS# }
# # separate with comma instead of space and export to the action
# echo "TAGS=${TAGS// /,}" >> $GITHUB_ENV
# echo
# echo $TAGS
-
name: "Switch into containerd image store"
run: |
# Use containerd image store
sudo sed -i '$s/}/, "features": { "containerd-snapshotter": true } }/' /etc/docker/daemon.json
sudo systemctl restart docker
docker info -f '{{ .DriverStatus }}'
-
name: Checkout
uses: actions/checkout@v4
with:
ref: official
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Login to Docker.io
if: contains(inputs.registry, 'docker.io') && inputs.push
uses: docker/login-action@v3
with:
registry: docker.io
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Login to Quay.io
if: contains(inputs.registry, 'quay.io') && inputs.push
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ secrets.QUAY_IO_USERNAME }}
password: ${{ secrets.QUAY_IO_CLI_PASSWORD }}
-
name: Login to Ghcr.io
if: contains(inputs.registry, 'ghcr.io') && inputs.push
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ secrets.GIT_HUB_USERNAME }}
password: ${{ secrets.GIT_HUB_TOKEN }}
-
name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
# list of Docker images to use as base name for tags
images: ${{ env.IMAGE_NAMES }}
# images: ${{ inputs.registry }}/${{ inputs.major_version }}-${{ matrix.image_types }}
# images: |
# docker.io/ykohut/${{ inputs.major_version }}-${{ matrix.image_types }}
# quay.io/ykohut/${{ inputs.major_version }}-${{ matrix.image_types }}
# ghcr.io/yuravk/${{ inputs.major_version }}-${{ matrix.image_types }}
# generate Docker tags
tags: |
type=raw,priority=500,value=latest,enable=${{ matrix.image_types != 'default' || ( matrix.image_types == 'default' && inputs.major_version == '9' ) }}
type=raw,priority=400,value=${{ inputs.major_version }},enable=true
type=raw,priority=300,value=${{ inputs.major_version }}.${{ env.VERSION_MINOR }},enable=true
type=raw,priority=200,value=${{ inputs.major_version }}.${{ env.VERSION_MINOR }}-${{ env.STAMP }},enable=true
# labels: |
# maintainer=Yuriy Kohut <[email protected]>
# org.opencontainers.image.title=${{ inputs.major_version }}-${{ matrix.image_types }}
# org.opencontainers.image.description=Almalinux ${{ inputs.major_version }}.${{ env.VERSION_MINOR }} ${{ matrix.image_types }} images.
# org.opencontainers.image.vendor=AlmaLinux.org
-
name: Build images
# if 'Push to registries' is checked
if: inputs.push
id: build-images
uses: docker/build-push-action@v5
with:
provenance: false
context: "{{defaultContext}}:dockerfiles/al${{ inputs.major_version }}"
file: ./Dockerfile.${{ matrix.image_types }}
platforms: ${{ inputs.platform }}
push: false
load: true
# tags: ${{ env.TAGS }}
tags: ${{ steps.meta.outputs.tags }}
# labels: ${{ steps.meta.outputs.labels }}
-
name: "[Debug] Test images"
# if 'Push to registries' is checked
if: inputs.push
id: test-images
run: |
archs="${{ inputs.platform }}"
for arch in ${archs//,/ }; do
# docker run --platform=${arch} ${{ steps.build-images.outputs.imageid }} /bin/bash -c " \
docker run --platform=${arch} ${{ steps.build-images.outputs.digest }} /bin/bash -c " \
uname -m \
&& cat /etc/almalinux-release \
&& ( test "${{ matrix.image_types }}" != "micro" && rpm -q gpg-pubkey) || true "
done
-
name: Push to registry
# if 'Push to registries' is checked
if: inputs.push
id: push-images
uses: docker/build-push-action@v5
with:
provenance: false
context: "{{defaultContext}}:dockerfiles/al${{ inputs.major_version }}"
file: ./Dockerfile.${{ matrix.image_types }}
platforms: ${{ inputs.platform }}
push: ${{ inputs.push }}
# tags: ${{ env.TAGS }}
tags: ${{ steps.meta.outputs.tags }}
# labels: ${{ steps.meta.outputs.labels }}
# Change 'tag:' in the 'dockerfiles/official/al*/Dockerfile.*'
-
name: "Set tag into official Dockerfile"
# if 'Push to registries' is checked and 'default' or 'minimal' image
if: matrix.image_types == 'default' || matrix.image_types == 'minimal'
run: |
case ${{ matrix.image_types }} in
default)
tags="${{ inputs.major_version }}, ${{ inputs.major_version }}.${{ env.VERSION_MINOR }}, ${{ inputs.major_version }}.${{ env.VERSION_MINOR }}-${{ env.STAMP }}"
[ "${{ inputs.major_version }}" = "9" ] && tags="latest, ${tags}" ;;
minimal)
tags="${{ inputs.major_version }}-${{ matrix.image_types }}, ${{ inputs.major_version }}.${{ env.VERSION_MINOR }}-${{ matrix.image_types }}, ${{ inputs.major_version }}.${{ env.VERSION_MINOR }}-${{ matrix.image_types }}-${{ env.STAMP }}"
[ "${{ inputs.major_version }}" = "9" ] && tags="minimal, ${tags}" ;;
*)
esac
# # the data for tag in MAJOR.MINOR-TYPE-DATE format
# tag="${{ inputs.major_version }}.${{ env.VERSION_MINOR }}-${{ matrix.image_types }}-${{ env.STAMP}}"
# # if 'default' image, the data for tag in MAJOR.MINOR-DATE format
# [ "${{ matrix.image_types }}" = "default" ] && tag="${{ inputs.major_version }}.${{ env.VERSION_MINOR }}-${{ env.STAMP}}"
sed -i "/^\([[:space:]]*#[[:space:]]*tag: \).*/s//\1${tags}/" dockerfiles/official/al${{ inputs.major_version }}/Dockerfile.${{ matrix.image_types }}
sed -i 's/^\([[:space:]]*FROM[[:space:]]\+.\+:\).\+$/\1${{ inputs.major_version }}.${{ env.VERSION_MINOR }}-${{ env.STAMP}}/' dockerfiles/official/al${{ inputs.major_version }}/Dockerfile.${{ matrix.image_types }}
cat dockerfiles/official/al${{ inputs.major_version }}/Dockerfile.${{ matrix.image_types }}
# Upload changed 'dockerfiles/official/al*/Dockerfile.*'
- uses: actions/upload-artifact@v4
# if 'Push to registries' is checked and 'default' or 'minimal' image
if: matrix.image_types == 'default' || matrix.image_types == 'minimal'
with:
name: dockerfiles-${{ matrix.image_types }}
path: dockerfiles/official/al${{ inputs.major_version }}/Dockerfile.${{ matrix.image_types }}
outputs:
date_stamp: ${{ steps.date_stamp.outputs.date_stamp }}
commit:
# if: contains(inputs.image_types, 'default') || contains(inputs.image_types, 'minimal')
if: inputs.type_default || inputs.type_minimal
name: "Commit official Dockerfile for ${{ inputs.major_version }}"
runs-on: ubuntu-latest
needs:
- build
steps:
-
name: Checkout
uses: actions/checkout@v4
with:
ref: official
# Download uploaded above 'dockerfiles/official/al*/Dockerfile.*'
- uses: actions/download-artifact@v4
with:
merge-multiple: true
path: dockerfiles/official/al${{ inputs.major_version }}
-
name: "[Debug] Print dockerfiles/official/al${{ inputs.major_version }}/Dockerfile.*"
run: |
echo "Date stamp: ${{ needs.build.outputs.date_stamp }}"
cat dockerfiles/official/al${{ inputs.major_version }}/Dockerfile.*
# Commit 'dockerfiles/official/al*/Dockerfile.*'
# TODO: does this run only if files changed ... ?
-
name: "Commit tag for dockerfiles/official/al${{ inputs.major_version }}"
# if 'Push to registries' is checked
# if: inputs.push
uses: EndBug/add-and-commit@v9
with:
default_author: user_info
new_branch: official
message: "Almalinux ${{ inputs.major_version }} image build as of ${{ needs.build.outputs.date_stamp }} (with ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})."
# push: true
push: ${{ inputs.push }}
prepare-manifest:
# if: inputs.pr && ( contains(inputs.image_types, 'default') || contains(inputs.image_types, 'minimal') )
if: inputs.pr && ( inputs.type_default || inputs.type_minimal )
name: "Generate manifest for ${{ matrix.major_version }} ${{ matrix.image_types }}"
runs-on: ubuntu-latest
needs:
- commit
strategy:
fail-fast: false
matrix:
image_types:
- default
- minimal
major_version:
- 8
- 9
steps:
-
name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
with:
ref: official
fetch-depth: 0
-
name: Checkout ${{ env.LOCAL_LIBRARY_OFFICIAL }}
uses: actions/checkout@v4
with:
repository: ${{ env.LOCAL_LIBRARY_OFFICIAL }}
path: official-images
-
name: "Get data to prepare manifest for ${{ matrix.major_version }} ${{ matrix.image_types }}"
run: |
to_manifest=true
echo "to_manifest=${to_manifest}" >> $GITHUB_ENV
dockerfile="dockerfiles/official/al${{ matrix.major_version }}/Dockerfile.${{ matrix.image_types }}"
# The recent commit of Dockerfile for specific version and image type
last_commit=$( git log -1 --format='%H' -- ${dockerfile} )
echo "commit_hash=${last_commit}" >> $GITHUB_ENV
echo "commit_hash=${last_commit}"
# Get tags from the Dockerfile
tag=$( grep 'tag:' ${dockerfile} | sed "s/^[[:space:]]*#[[:space:]]*tag: \(.*\)$/\1/" )
echo "tag=${tag}" >> $GITHUB_ENV
echo "tag=${tag}"
-
name: "Render manifest for ${{ matrix.major_version }} ${{ matrix.image_types }}"
if: env.to_manifest == 'true'
id: minifest
uses: chuhlomin/render-template@v1
with:
template: official-manifest.tmpl
result_path: official-images/library/almalinux.${{ matrix.major_version }}.${{ matrix.image_types }}
vars: |
tags: ${{ env.tag }}
commit_hash: ${{ env.commit_hash}}
version_major: ${{ matrix.major_version }}
image_type: ${{ matrix.image_types }}
-
name: "[Debug] Check manifest for ${{ matrix.major_version }} ${{ matrix.image_types }}"
if: env.to_manifest == 'true'
run: |
cat official-images/library/almalinux.${{ matrix.major_version }}.${{ matrix.image_types }}
# Upload changed 'official-images/library/almalinux.*'
- uses: actions/upload-artifact@v4
if: env.to_manifest == 'true'
with:
name: manifest-${{ matrix.major_version }}.${{ matrix.image_types }}
path: official-images/library/almalinux.${{ matrix.major_version }}.${{ matrix.image_types }}
push-pr:
# if: inputs.pr && ( contains(inputs.image_types, 'default') || contains(inputs.image_types, 'minimal') )
if: inputs.pr && ( inputs.type_default || inputs.type_minimal )
name: "Create pull request for the new manifest"
runs-on: ubuntu-latest
needs:
- prepare-manifest
steps:
-
name: Checkout ${{ env.LOCAL_LIBRARY_OFFICIAL }}
uses: actions/checkout@v4
with:
repository: ${{ env.LOCAL_LIBRARY_OFFICIAL }}
path: official-images
token: ${{ secrets.GIT_HUB_TOKEN }}
# -
# name: Sync upstream changes for ${{ env.LOCAL_LIBRARY_OFFICIAL }}
# id: sync
# uses: aormsby/[email protected]
# with:
# target_sync_branch: master
# # REQUIRED 'target_repo_token' exactly like this!
# target_repo_token: ${{ secrets.GIT_HUB_TOKEN }}
# upstream_sync_branch: master
# upstream_sync_repo: ${{ env.DOCKER_LIBRARY_OFFICIAL }}
# upstream_repo_access_token: ${{ secrets.GIT_HUB_TOKEN }}
-
name: "Sync ${{ env.LOCAL_LIBRARY_OFFICIAL }} with upstream"
run: |
cd official-images
# gh repo sync ${{ env.DOCKER_LIBRARY_OFFICIAL }} -b master --force
git remote add upstream https://github.com/${{ env.DOCKER_LIBRARY_OFFICIAL }}.git
git fetch upstream
git checkout master
# rebase or merge or merge --no-ff ...
git rebase upstream/master
# Download uploaded above 'official-images/library/almalinux.*'
- uses: actions/download-artifact@v4
with:
pattern: manifest-*
merge-multiple: true
path: official-images/library/
-
name: "Create head of official-images/library/almalinux"
run: |
echo "# This file is generated using ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
Maintainers: The AlmaLinux OS Foundation <[email protected]> (@AlmaLinux)
GitRepo: ${{ github.server_url }}/${{ github.repository }}.git" > official-images/library/almalinux
-
name: "[Debug] Squash manifests into official-images/library/almalinux"
run: |
for file in $( ls -1 official-images/library/almalinux.*.* ); do
echo "" >> official-images/library/almalinux
cat $file >> official-images/library/almalinux
done
rm -f official-images/library/almalinux.*.*
cat official-images/library/almalinux
-
name: "Prepare date stamp"
run: |
# date stamp
STAMP=$(date '+%Y%m%d')
echo "STAMP=${STAMP}" >> $GITHUB_ENV
-
name: "Commit and push official-images/library/almalinux"
uses: EndBug/add-and-commit@v9
with:
cwd: official-images
default_author: user_info
message: "Almalinux auto-update - ${{ env.STAMP }}"
# push: false
push: ${{ inputs.pr }}
-
name: Create Pull Request [commendline]
run: |
cd official-images
gh auth login --with-token < <(echo ${{ secrets.GIT_HUB_TOKEN }})
gh pr create \
--title "Almalinux auto-update - ${{ env.STAMP }}" \
--body "This is an auto-generated commit. Any concern or issues, please contact or email AlmaLinux OS Foundation [email protected] (@AlmaLinux)" \
--repo ${{ env.DOCKER_LIBRARY_OFFICIAL }} \
--base master \
--draft
# -
# name: Create Pull Request
# uses: peter-evans/create-pull-request@v6
# with:
# path: official-images
# add-paths: library
# # branch: master
# # base: master
# # committer: ${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com>
# commit-message: "Almalinux auto-update - ${{ env.STAMP }}"
# title: "Almalinux auto-update - ${{ env.STAMP }}"
# body: "This is an auto-generated commit. Any concern or issues, please contact or email AlmaLinux OS Foundation [email protected] (@AlmaLinux)"
# push-to-fork: ${{ env.DOCKER_LIBRARY_OFFICIAL }}
# draft: true
# token: ${{ secrets.GIT_HUB_TOKEN }}