Skip to content

Merge pull request #10 from DataDog/lloeki/add-musl-images #75

Merge pull request #10 from DataDog/lloeki/add-musl-images

Merge pull request #10 from DataDog/lloeki/add-musl-images #75

Workflow file for this run

name: Build Ruby
on:
workflow_dispatch:
inputs:
push:
description: Push images
required: true
type: boolean
default: true
push:
branches:
- "**"
env:
REGISTRY: ghcr.io
REPO: datadog/images-rb
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
# gnu
- engine: ruby
version: "2.1"
libc: gnu
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "2.2"
libc: gnu
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "2.3"
libc: gnu
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "2.4"
libc: gnu
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "2.5"
libc: gnu
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "2.6"
libc: gnu
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "2.7"
libc: gnu
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "3.0"
libc: gnu
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "3.1"
libc: gnu
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "3.2"
libc: gnu
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "3.3"
libc: gnu
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "3.4"
libc: gnu
arch: ["x86_64", "aarch64"]
- engine: jruby
version: "9.2"
libc: gnu
arch: ["x86_64", "aarch64"]
- engine: jruby
version: "9.3"
libc: gnu
arch: ["x86_64", "aarch64"]
- engine: jruby
version: "9.4"
libc: gnu
arch: ["x86_64", "aarch64"]
# musl
- engine: ruby
version: "2.1"
libc: musl
arch: ["x86_64"]
- engine: ruby
version: "2.2"
libc: musl
arch: ["x86_64"]
- engine: ruby
version: "2.3"
libc: musl
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "2.4"
libc: musl
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "2.5"
libc: musl
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "2.6"
libc: musl
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "2.7"
libc: musl
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "3.0"
libc: musl
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "3.1"
libc: musl
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "3.2"
libc: musl
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "3.3"
libc: musl
arch: ["x86_64", "aarch64"]
- engine: ruby
version: "3.4"
libc: musl
arch: ["x86_64", "aarch64"]
- engine: jruby
version: "9.2"
libc: musl
arch: ["x86_64", "aarch64"]
- engine: jruby
version: "9.3"
libc: musl
arch: ["x86_64", "aarch64"]
- engine: jruby
version: "9.4"
libc: musl
arch: ["x86_64", "aarch64"]
runs-on: ubuntu-latest
name: Build (${{ matrix.engine }} ${{ matrix.version }} ${{ matrix.libc }})
steps:
- name: Set up Docker
uses: crazy-max/ghaction-setup-docker@v3
with:
daemon-config: |
{
"features": {
"containerd-snapshotter": true
}
}
- name: Set variables
id: vars
run: |
echo "SRC=src/engines/${{ matrix.engine }}/${{ matrix.version }}" >> $GITHUB_OUTPUT
echo "IMAGE=${{ env.REGISTRY }}/${{ env.REPO }}/engines/${{ matrix.engine }}" >> $GITHUB_OUTPUT
echo "RELEASE_TAG=${{ matrix.version }}-${{ matrix.libc }}" >> $GITHUB_OUTPUT
echo "TAG=${{ matrix.version }}-${{ matrix.libc }}-gha${{ github.run_id }}-g${{ github.sha }}" >> $GITHUB_OUTPUT
echo "DOCKERFILE=src/engines/${{ matrix.engine }}/${{ matrix.version }}/Dockerfile.${{ matrix.libc }}" >> $GITHUB_OUTPUT
echo "DOCKER_PLATFORMS=$(echo ${{ join(matrix.arch) }} | tr ',' '\n' | sed 's/^/linux\//' | paste -s -d, -)" >> $GITHUB_OUTPUT
- name: Checkout
uses: actions/checkout@v4
# First, build image for x86_64 as it will fail fast
#
# Tagging is necessary to reference the image for the testing step
# Tagging is done separately to avoid interfrence with caching
- name: Build single-arch image (x86_64)
if: ${{ contains(matrix.arch, 'x86_64') }}
run: |
docker buildx build ${{ steps.vars.outputs.SRC }} --cache-from=type=registry,ref=${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }} --output=type=image,push=false --platform linux/x86_64 -f ${{ steps.vars.outputs.DOCKERFILE }}
- name: Tag single-arch image (x86_64)
if: ${{ contains(matrix.arch, 'x86_64') }}
run: |
docker buildx build ${{ steps.vars.outputs.SRC }} --cache-from=type=registry,ref=${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }} --load --platform linux/x86_64 -f ${{ steps.vars.outputs.DOCKERFILE }} --tag ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.TAG }}
- name: Test single-arch image (x86_64)
if: ${{ contains(matrix.arch, 'x86_64') }}
run: |
docker run --platform linux/x86_64 --rm ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.TAG }} /bin/sh -c 'true'
docker run --platform linux/x86_64 --rm ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.TAG }} ruby -e 'puts RUBY_DESCRIPTION'
docker run --platform linux/x86_64 --rm ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.TAG }} gem --version
docker run --platform linux/x86_64 --rm ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.TAG }} bundle --version
docker run --platform linux/x86_64 --rm -v "${PWD}":"${PWD}" -w "${PWD}" -e BUNDLE_GEMFILE=gemfiles/${{ matrix.engine }}-${{ matrix.version }}.gemfile ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.TAG }} /bin/sh -c 'bundle install --with="test" --without="check ide" && bundle exec rake test'
# TODO: hardcoded musl, unify gnu instead
# TODO: hardcoded tags, use proper tag building
- name: Tag single-arch image (x86_64)
if: ${{ contains(matrix.arch, 'x86_64') }}
run: |
docker buildx build ${{ steps.vars.outputs.SRC }} --cache-from=type=registry,ref=${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }} --load --platform linux/x86_64 -f ${{ steps.vars.outputs.DOCKERFILE }} --tag ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }}
docker image list
- name: Build single-arch compiler image (x86_64)
if: ${{ contains(matrix.arch, 'x86_64') && matrix.libc == 'musl' }}
run: |
docker image list # image not in builder=container!
docker buildx build ${{ steps.vars.outputs.SRC }} --cache-from=type=registry,ref=${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }}-gcc --output=type=image,push=false --platform linux/x86_64 -f ${{ steps.vars.outputs.DOCKERFILE }}.gcc
# TODO: add CI tag and test
# Then, build image for aarch64 which, being emulated under qemu, is slower
#
# Tagging is necessary to reference the image for the testing step
# Tagging is done separately to avoid interfrence with caching
# Start by enabling qemu for aarch64
- name: Enable aarch64 emulation (x86_64)
if: ${{ contains(matrix.arch, 'aarch64') }}
run: |
docker run --privileged --rm tonistiigi/binfmt --install arm64
- name: Build single-arch image (aarch64)
if: ${{ contains(matrix.arch, 'aarch64') }}
run: |
docker buildx build ${{ steps.vars.outputs.SRC }} --cache-from=type=registry,ref=${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }} --output=type=image,push=false --platform linux/aarch64 -f ${{ steps.vars.outputs.DOCKERFILE }}
- name: Tag single-arch image (aarch64)
if: ${{ contains(matrix.arch, 'aarch64') }}
run: |
docker buildx build ${{ steps.vars.outputs.SRC }} --cache-from=type=registry,ref=${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }} --load --platform linux/aarch64 -f ${{ steps.vars.outputs.DOCKERFILE }} --tag ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.TAG }}
- name: Test single-arch image (aarch64)
if: ${{ contains(matrix.arch, 'aarch64') }}
run: |
docker run --platform linux/aarch64 --rm ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.TAG }} /bin/sh -c 'true'
docker run --platform linux/aarch64 --rm ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.TAG }} ruby -e 'puts RUBY_DESCRIPTION'
docker run --platform linux/aarch64 --rm ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.TAG }} gem --version
docker run --platform linux/aarch64 --rm ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.TAG }} bundle --version
docker run --platform linux/aarch64 --rm -v "${PWD}":"${PWD}" -w "${PWD}" -e BUNDLE_GEMFILE=gemfiles/${{ matrix.engine }}-${{ matrix.version }}.gemfile ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.TAG }} /bin/sh -c 'bundle install --with="test" --without="check ide" && bundle exec rake test'
# TODO: hardcoded musl, unify gnu instead
# TODO: hardcoded tags, use proper tag building
- name: Tag single-arch image (aarch64)
if: ${{ contains(matrix.arch, 'aarch64') }}
run: |
docker buildx build ${{ steps.vars.outputs.SRC }} --cache-from=type=registry,ref=${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }} --load --platform linux/aarch64 -f ${{ steps.vars.outputs.DOCKERFILE }} --tag ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }}
- name: Build single-arch compiler image (aarch64)
if: ${{ contains(matrix.arch, 'aarch64') && matrix.libc == 'musl' }}
run: |
docker buildx build ${{ steps.vars.outputs.SRC }} --cache-from=type=registry,ref=${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }}-gcc --output=type=image,push=false --platform linux/aarch64 -f ${{ steps.vars.outputs.DOCKERFILE }}.gcc
# TODO: add CI tag and test
# Finally, assemble multi-arch image for a combined push to the registry
#
# This reruns docker build but layers are in the cache, so it's fast
- name: Log in to the Container Registry
run: |
echo ${{ secrets.GITHUB_TOKEN }} | docker login ${{ env.REGISTRY }} -u ${{ github.actor }} --password-stdin
- name: Push CI run image (${{ join(matrix.arch, ', ') }})
run: |
docker buildx build ${{ steps.vars.outputs.SRC }} --cache-from=type=registry,ref=${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }} --output=type=image,push=true --build-arg BUILDKIT_INLINE_CACHE=1 --platform ${{ steps.vars.outputs.DOCKER_PLATFORMS }} -f ${{ steps.vars.outputs.DOCKERFILE }} --tag ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.TAG }}
- name: Push release image (${{ join(matrix.arch, ', ') }})
if: ${{ inputs.push }}
run: |
docker buildx build ${{ steps.vars.outputs.SRC }} --cache-from=type=registry,ref=${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }} --output=type=image,push=true --build-arg BUILDKIT_INLINE_CACHE=1 --platform ${{ steps.vars.outputs.DOCKER_PLATFORMS }} -f ${{ steps.vars.outputs.DOCKERFILE }} --tag ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }}
# TODO: hardcoded, reuse strip-tags directive instead (or better, unify gnu)
- name: Push unqualified release image (${{ join(matrix.arch, ', ') }})
if: ${{ inputs.push && matrix.libc == 'gnu' }}
run: |
docker buildx build ${{ steps.vars.outputs.SRC }} --cache-from=type=registry,ref=${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }} --output=type=image,push=true --build-arg BUILDKIT_INLINE_CACHE=1 --platform ${{ steps.vars.outputs.DOCKER_PLATFORMS }} -f ${{ steps.vars.outputs.DOCKERFILE }} --tag ${{ steps.vars.outputs.IMAGE }}:${{ matrix.version }}
# TODO: hardcoded, reuse append-tags directive instead (or better, unify gnu)
- name: Push release compiler image (${{ join(matrix.arch, ', ') }})
if: ${{ inputs.push && matrix.libc == 'gnu' }}
run: |
docker buildx build ${{ steps.vars.outputs.SRC }} --cache-from=type=registry,ref=${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }}-gcc --output=type=image,push=true --build-arg BUILDKIT_INLINE_CACHE=1 --platform ${{ steps.vars.outputs.DOCKER_PLATFORMS }} -f ${{ steps.vars.outputs.DOCKERFILE }} --tag ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }}-gcc
# TODO: hardcoded musl, unify gnu instead
- name: Push release compiler image (${{ join(matrix.arch, ', ') }})
if: ${{ inputs.push && matrix.libc == 'musl' }}
run: |
docker buildx build ${{ steps.vars.outputs.SRC }} --cache-from=type=registry,ref=${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }}-gcc --output=type=image,push=true --build-arg BUILDKIT_INLINE_CACHE=1 --platform ${{ steps.vars.outputs.DOCKER_PLATFORMS }} -f ${{ steps.vars.outputs.DOCKERFILE }}.gcc --tag ${{ steps.vars.outputs.IMAGE }}:${{ steps.vars.outputs.RELEASE_TAG }}-gcc