Build and push container images for Specific Ruby Version #34
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build and push container images | |
on: | |
workflow_dispatch: | |
schedule: | |
- cron: '0 1 * * 0' # weekly refresh on Sunday at 1am | |
push: | |
branches: [main] | |
paths: | |
- 'Dockerfile' | |
env: | |
COSIGN_EXPERIMENTAL: 1 | |
REGISTRY_IMAGE: zenjoy/ruby | |
jobs: | |
build: | |
name: Build and publish image | |
runs-on: ${{ matrix.os }} | |
strategy: | |
fail-fast: false | |
matrix: | |
ruby: ['3.0'] | |
debian: ['bookworm'] | |
include: | |
- os: ubuntu-latest | |
platform: linux/amd64 | |
- os: ubuntu-22.04-arm | |
platform: linux/arm64 | |
permissions: | |
id-token: write # keyless Cosign signatures | |
packages: write # GHCR | |
contents: write # git tags | |
steps: | |
- name: Checkout repo | |
uses: actions/checkout@v4 | |
- name: Prepare | |
run: | | |
platform=${{ matrix.platform }} | |
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV | |
- name: Parse ruby version | |
id: prepare | |
run: | | |
RUBY_VERSION=$(grep -Eo 'RUBY_VERSION ${{ matrix.ruby }}.[0-9]+$' Dockerfile | cut -d ' ' -f2) | |
MAJOR=$(echo $RUBY_VERSION | cut -d . -f 1) | |
MINOR=$(echo $RUBY_VERSION | cut -d . -f 2) | |
PATCH=$(echo $RUBY_VERSION | cut -d . -f 3) | |
TODAY=$(date +%Y-%m-%d) | |
echo "major=$MAJOR" | tee -a $GITHUB_OUTPUT | |
echo "minor=$MINOR" | tee -a $GITHUB_OUTPUT | |
echo "patch=$PATCH" | tee -a $GITHUB_OUTPUT | |
echo "version=$RUBY_VERSION" | tee -a $GITHUB_OUTPUT | |
echo "today=${TODAY}" | tee -a $GITHUB_OUTPUT | |
- name: Generate build tag from head | |
id: branch | |
run: | | |
export GIT_REF=${GITHUB_HEAD_REF:-$GITHUB_REF_NAME} | |
echo "branch=$(echo ${GIT_REF,,} | sed 's/[^a-zA-Z0-9]/-/g')" | tee -a $GITHUB_OUTPUT | |
- name: Generate Docker metadata with ruby version | |
uses: docker/metadata-action@v4 | |
id: metadata | |
with: | |
flavor: | | |
latest=${{ matrix.ruby == '3.3' }} | |
images: | | |
docker.io/${{ env.REGISTRY_IMAGE }} | |
ghcr.io/${{ env.REGISTRY_IMAGE }} | |
tags: | | |
type=semver,pattern={{version}},value=v${{ steps.prepare.outputs.version }} | |
type=semver,pattern={{major}}.{{minor}},value=v${{ steps.prepare.outputs.version }} | |
labels: | | |
org.opencontainers.image.title=ruby | |
- name: Install Cosign | |
uses: sigstore/[email protected] | |
- name: Login to Docker Hub | |
uses: docker/login-action@v3 | |
with: | |
username: ${{ secrets.DOCKER_HUB_USER }} | |
password: ${{ secrets.DOCKER_HUB_PASSWORD }} | |
- name: Login to GitHub Container Repository | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ github.token }} | |
- name: Build container image | |
uses: docker/build-push-action@v6 | |
id: build | |
with: | |
tags: ${{ steps.metadata.outputs.tags }} | |
labels: ${{ steps.metadata.outputs.labels }} | |
build-args: | | |
BUILD_AT=${{ steps.prepare.outputs.today }} | |
RUBY=${{ matrix.ruby }} | |
DEBIAN=${{ matrix.debian }} | |
platforms: ${{ matrix.platform }} | |
outputs: | | |
type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true | |
cache-from: type=gha | |
cache-to: type=gha,mode=max | |
- name: Export digest | |
run: | | |
mkdir -p /tmp/digests | |
digest="${{ steps.build.outputs.digest }}" | |
touch "/tmp/digests/${digest#sha256:}" | |
- name: Upload digest | |
uses: actions/upload-artifact@v4 | |
with: | |
name: digests-${{ matrix.ruby }}-${{ matrix.debian }}-${{ env.PLATFORM_PAIR }} | |
path: /tmp/digests/* | |
if-no-files-found: error | |
retention-days: 1 | |
- name: Sign container images | |
run: | | |
cosign sign --yes --recursive "docker.io/$IMAGE_NAME@$IMAGE_DIGEST" | |
cosign sign --yes --recursive "ghcr.io/$IMAGE_NAME@$IMAGE_DIGEST" | |
env: | |
IMAGE_NAME: ${{ env.REGISTRY_IMAGE }} | |
IMAGE_DIGEST: ${{ steps.build.outputs.digest }} | |
merge: | |
runs-on: ubuntu-latest | |
strategy: | |
fail-fast: false | |
matrix: | |
ruby: ['3.0', '3.1', '3.2', '3.3'] | |
debian: ['bookworm'] | |
needs: | |
- build | |
steps: | |
- name: Download digests | |
uses: actions/download-artifact@v4 | |
with: | |
path: /tmp/digests | |
pattern: digests-${{ matrix.ruby }}-${{ matrix.debian }}-* | |
merge-multiple: true | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Docker meta | |
id: meta | |
uses: docker/metadata-action@v5 | |
with: | |
images: ${{ env.REGISTRY_IMAGE }} | |
- name: Login to Docker Hub | |
uses: docker/login-action@v3 | |
with: | |
username: ${{ secrets.DOCKER_HUB_USER }} | |
password: ${{ secrets.DOCKER_HUB_PASSWORD }} | |
- name: Login to GitHub Container Repository | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ github.token }} | |
- name: Create manifest list and push | |
working-directory: /tmp/digests | |
run: | | |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ | |
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *) | |
- name: Inspect image | |
run: | | |
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }} |