Skip to content

Build and publish Oracle Linux developer container images to GitHub Container Registry #718

Build and publish Oracle Linux developer container images to GitHub Container Registry

Build and publish Oracle Linux developer container images to GitHub Container Registry #718

name: Build and publish Oracle Linux developer container images to GitHub Container Registry
# Builds are triggered either by:
# - a push on the main branch with changes in this file.
# All container images will be (re)built.
# - a push on the main branch with changes the OracleLinuxDevelopers
# directory.
# Affected container images will be (re)built.
# - a manual trigger of the workflow using the API.
# Subset of OL version / language can be specified; default is to build
# all images.
# Images are built for both amd64 and arm64 architectures, except for
# - oracledb images (not available on arm)
# - php and nodejs on OL7 (packages not available)
on:
push:
branches:
- main
paths:
- 'OracleLinuxDevelopers/**'
- '.github/workflows/build-and-push-dev-images.yml'
workflow_dispatch:
inputs:
ol:
description: List of ol versions to build
default: 'oraclelinux7, oraclelinux8, oraclelinux9'
required: false
lang:
description: List of languages to build
default: 'gcc-toolset, golang, nginx, nodejs, php, python, redis, ruby, haproxy'
required: false
# Default values for the builds triggered by the push event
env:
ol: 'oraclelinux7, oraclelinux8, oraclelinux9'
lang: 'gcc-toolset, golang, nodejs, nginx, php, python, redis, ruby, haproxy'
jobs:
prepare:
name: Create build matrix
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.build-matrix.outputs.matrix }}
skip_build: ${{ steps.build-matrix.outputs.skip_build }}
repository_owner: ${{ steps.repository_owner.outputs.repository_owner }}
date_stamp: ${{ steps.date_stamp.outputs.date_stamp }}
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
# We need "some" commit history to check for changed files
fetch-depth: 32
- name: Build matrix
id: build-matrix
working-directory: OracleLinuxDevelopers
run: |
IFS=", " read -r -a ol_list <<< "${{ github.event.inputs.ol || env.ol}}"
IFS=", " read -r -a lang_list <<< "${{ github.event.inputs.lang || env.lang}}"
changes=$(mktemp)
# workflow is only set in the workflow_dispatch event payload
workflow="${{ github.event.workflow }}"
if [[ -z ${workflow} ]]; then
# Push event - retrieve list of changed files
git diff --name-only '${{ github.event.before }}..${{ github.event.after }}' > "${changes}"
if grep -q build-and-push-dev-images.yml "${changes}"; then
echo "PUSH: Action updated, rebuilding all images"
build_all=1
else
echo "PUSH: Rebuilding changed images only"
build_all=0
fi
else
echo "MANUAL: Rebuilding based on parameters"
build_all=1
fi
matrix=$(
for ol in "${ol_list[@]}"; do
pushd "${ol}" >/dev/null || exit 1
for lang in "${lang_list[@]}"; do
if [[ -d ${lang} ]]; then
pushd "${lang}" >/dev/null || exit 1
for dockerfile in */Dockerfile; do
tag=$(dirname "${dockerfile}")
if [[ -f ${tag}/.skip-arm64 ]]; then
multi=0
arch="linux/amd64"
else
multi=1
arch="linux/amd64,linux/arm64"
fi
if [[ ${build_all} -eq 1 ]] || grep -q "${ol}/${lang}/${tag}" "${changes}"; then
echo "${ol};${lang};${tag};${arch};${multi}"
fi
done
popd >/dev/null || exit 1
fi
done
popd >/dev/null || exit 1
done | jq --slurp --raw-input --compact-output '
split("\n") |
.[:-1] |
map(split(";")) |
map({"ol": .[0], "lang": .[1], "tag": .[2], "arch": .[3], "multi": (.[4] == "1")})'
)
rm "${changes}"
if [[ ${matrix} == "[]" ]]; then
# Empty array -- change didn't impact any image
skip_build=true
else
skip_build=false
matrix=$(jq --compact-output '{ "include": .}' <<<"${matrix}")
fi
echo "matrix=${matrix}" >> "$GITHUB_OUTPUT"
echo "skip_build=${skip_build}" >> "$GITHUB_OUTPUT"
- name: Lowercase repository owner
id: repository_owner
run: |
echo "repository_owner=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT"
- name: Date stamp
id: date_stamp
run: |
echo "date_stamp=$(date +'%Y%m%d')" >> "$GITHUB_OUTPUT"
build-image:
name: Build image
needs: [ prepare ]
if: always() && needs.prepare.outputs.skip_build == 'false'
strategy:
matrix: ${{fromJson(needs.prepare.outputs.matrix)}}
fail-fast: false
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
with:
platforms: arm64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Log into GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build image - amd64
uses: docker/build-push-action@v4
with:
context: OracleLinuxDevelopers/${{ matrix.ol }}/${{ matrix.lang }}/${{ matrix.tag }}
platforms: linux/amd64
push: ${{ github.event_name != 'pull_request' }}
tags: |
"ghcr.io/${{ needs.prepare.outputs.repository_owner }}/${{ matrix.ol }}-${{ matrix.lang }}:${{ matrix.tag }}-${{ needs.prepare.outputs.date_stamp }}${{ matrix.multi && '-amd64' || '' }}"
"ghcr.io/${{ needs.prepare.outputs.repository_owner }}/${{ matrix.ol }}-${{ matrix.lang }}:${{ matrix.tag }}${{ matrix.multi && '-amd64' || '' }}"
- name: Build image - arm64
uses: docker/build-push-action@v4
if: matrix.multi
with:
context: OracleLinuxDevelopers/${{ matrix.ol }}/${{ matrix.lang }}/${{ matrix.tag }}
platforms: linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: |
"ghcr.io/${{ needs.prepare.outputs.repository_owner }}/${{ matrix.ol }}-${{ matrix.lang }}:${{ matrix.tag }}-${{ needs.prepare.outputs.date_stamp }}-arm64"
"ghcr.io/${{ needs.prepare.outputs.repository_owner }}/${{ matrix.ol }}-${{ matrix.lang }}:${{ matrix.tag }}-arm64"
- name: Manifest
if: matrix.multi && github.event_name != 'pull_request'
run: |
docker buildx imagetools create --tag \
"ghcr.io/${{ needs.prepare.outputs.repository_owner }}/${{ matrix.ol }}-${{ matrix.lang }}:${{ matrix.tag }}-${{ needs.prepare.outputs.date_stamp }}" \
"ghcr.io/${{ needs.prepare.outputs.repository_owner }}/${{ matrix.ol }}-${{ matrix.lang }}:${{ matrix.tag }}-${{ needs.prepare.outputs.date_stamp }}-amd64" \
"ghcr.io/${{ needs.prepare.outputs.repository_owner }}/${{ matrix.ol }}-${{ matrix.lang }}:${{ matrix.tag }}-${{ needs.prepare.outputs.date_stamp }}-arm64"
docker buildx imagetools create --tag \
"ghcr.io/${{ needs.prepare.outputs.repository_owner }}/${{ matrix.ol }}-${{ matrix.lang }}:${{ matrix.tag }}" \
"ghcr.io/${{ needs.prepare.outputs.repository_owner }}/${{ matrix.ol }}-${{ matrix.lang }}:${{ matrix.tag }}-amd64" \
"ghcr.io/${{ needs.prepare.outputs.repository_owner }}/${{ matrix.ol }}-${{ matrix.lang }}:${{ matrix.tag }}-arm64"