Docker multi-arch build and push #8
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
# Based on https://github.com/tdlight-team/tdlight-telegram-bot-api/blob/8990b79e9eac85c6107922283f25385b5e8c027a/.github/workflows/docker.yml#L1 | |
name: Docker multi-arch build and push | |
on: | |
push: | |
branches: | |
- main | |
- master | |
# - rework-structure | |
# pull_request: | |
schedule: | |
- cron: '20 4 * * *' | |
jobs: | |
build: | |
name: Build Docker image (${{ matrix.arch }}) | |
runs-on: ubuntu-latest | |
env: | |
IMAGE_TAG: ghcr.io/${{ github.repository_owner }}/telegram-bot-api | |
IMAGE_TAG_DH: ${{ secrets.DOCKERHUB_OWNER }}/telegram-bot-api | |
permissions: write-all | |
strategy: | |
matrix: | |
arch: | |
- linux/386 | |
- linux/amd64 | |
- linux/arm/v6 | |
- linux/arm/v7 | |
- linux/arm64 | |
- linux/ppc64le | |
steps: | |
- name: Checkout current repo | |
uses: actions/checkout@v4 | |
- name: Checkout upstream repo | |
uses: actions/checkout@v4 | |
with: | |
repository: tdlib/telegram-bot-api | |
path: telegram-bot-api | |
submodules: recursive | |
- name: Get version | |
run: | | |
# Get latest commit short hash | |
HASH_VERSION=$(git rev-parse --short HEAD) | |
# Get real version from the code | |
VERSION=$(cat telegram-bot-api/CMakeLists.txt | grep TelegramBotApi | cut -d " " -f3) | |
# Use Docker `latest` tag convention | |
# [ "$VERSION" == "master" ] && VERSION=latest | |
# Convert IMAGE_TAG, HASH_VERSION and VERSION to lowercase (repository name must be lowercase) | |
IMAGE_TAG=$(echo "$IMAGE_TAG" | awk '{print tolower($0)}') | |
IMAGE_TAG_DH=$(echo "$IMAGE_TAG_DH" | awk '{print tolower($0)}') | |
HASH_VERSION=$(echo "$HASH_VERSION" | awk '{print tolower($0)}') | |
VERSION=$(echo "$VERSION" | awk '{print tolower($0)}') | |
ARCH=${{ matrix.arch }} | |
SAFE_ARCH=${ARCH///} # linux/amd64 -> linuxamd64 | |
# Store variable for future use | |
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV | |
echo "IMAGE_TAG_DH=$IMAGE_TAG_DH" >> $GITHUB_ENV | |
echo "HASH_VERSION=$HASH_VERSION" >> $GITHUB_ENV | |
echo "VERSION=$VERSION" >> $GITHUB_ENV | |
echo "SAFE_ARCH=$SAFE_ARCH" >> $GITHUB_ENV | |
# Print debug info | |
echo "hash version: $HASH_VERSION" | |
echo "version: $VERSION" | |
echo "safe arch: $SAFE_ARCH" | |
# Save env to file | |
cat $GITHUB_ENV > github.env | |
- name: Upload environment info as artifact | |
uses: actions/upload-artifact@v2 | |
with: | |
name: github_env | |
path: github.env | |
- name: Set up QEMU | |
uses: docker/setup-qemu-action@v1 | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v2 | |
- name: Cache Docker layers | |
uses: actions/cache@v3 | |
with: | |
path: /tmp/.buildx-cache | |
key: ${{ runner.os }}-buildx-${{ env.SAFE_ARCH }}-${{ github.sha }} | |
restore-keys: | | |
${{ runner.os }}-buildx-${{ env.SAFE_ARCH }}- | |
- name: Login to ghcr registry | |
uses: docker/login-action@v2 | |
if: ${{ github.event_name != 'pull_request' }} | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Login to Docker Hub registry | |
uses: docker/login-action@v2 | |
if: ${{ github.event_name != 'pull_request' }} | |
with: | |
username: ${{ secrets.DOCKERHUB_LOGIN }} | |
password: ${{ secrets.DOCKERHUB_TOKEN }} | |
- name: Build image | |
uses: docker/build-push-action@v2 | |
with: | |
context: . | |
file: ./Dockerfile | |
cache-from: type=local,src=/tmp/.buildx-cache | |
cache-to: type=local,mode=max,dest=/tmp/.buildx-cache | |
platforms: ${{ matrix.arch }} | |
push: false | |
load: true | |
tags: | | |
telegrambotapi:${{ env.HASH_VERSION }}-${{ env.SAFE_ARCH }} | |
- name: Tag and push image | |
if: ${{ github.event_name != 'pull_request' }} | |
run: | | |
docker tag telegrambotapi:${{ env.HASH_VERSION }}-${{ env.SAFE_ARCH }} ${{ env.IMAGE_TAG }}:${{ env.HASH_VERSION }}-${{ env.SAFE_ARCH }} | |
docker tag telegrambotapi:${{ env.HASH_VERSION }}-${{ env.SAFE_ARCH }} ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-${{ env.SAFE_ARCH }} | |
docker tag telegrambotapi:${{ env.HASH_VERSION }}-${{ env.SAFE_ARCH }} ${{ env.IMAGE_TAG_DH }}:${{ env.HASH_VERSION }}-${{ env.SAFE_ARCH }} | |
docker tag telegrambotapi:${{ env.HASH_VERSION }}-${{ env.SAFE_ARCH }} ${{ env.IMAGE_TAG_DH }}:${{ env.VERSION }}-${{ env.SAFE_ARCH }} | |
docker push ${{ env.IMAGE_TAG}}:${{ env.HASH_VERSION}}-${{ env.SAFE_ARCH }} | |
docker push ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-${{ env.SAFE_ARCH }} | |
docker push ${{ env.IMAGE_TAG_DH }}:${{ env.HASH_VERSION }}-${{ env.SAFE_ARCH }} | |
docker push ${{ env.IMAGE_TAG_DH }}:${{ env.VERSION }}-${{ env.SAFE_ARCH }} | |
- name: Save image as tar archive | |
if: ${{ github.event_name != 'pull_request' }} | |
run: | | |
docker save ${{ env.IMAGE_TAG }}:${{ env.HASH_VERSION }}-${{ env.SAFE_ARCH }} -o ${{ env.SAFE_ARCH }}.tar | |
- name: Save image as tar archive (pull request) | |
if: ${{ github.event_name == 'pull_request' }} | |
run: | | |
docker save telegrambotapi:${{ env.HASH_VERSION }}-${{ env.SAFE_ARCH }} -o ${{ env.SAFE_ARCH }}.tar | |
- name: Upload image as artifact | |
uses: actions/upload-artifact@v2 | |
with: | |
name: image_${{ env.SAFE_ARCH }} | |
path: ${{ env.SAFE_ARCH }}.tar | |
push-manifest: | |
name: Create and push multi-arch Docker manifest | |
runs-on: ubuntu-latest | |
if: ${{ github.event_name != 'pull_request' }} | |
permissions: write-all | |
env: | |
DOCKER_CLI_EXPERIMENTAL: enabled | |
needs: build | |
steps: | |
- name: Download artifacts | |
uses: actions/download-artifact@v2 | |
- name: Load environment info and built images | |
run: | | |
cat github_env/github.env > $GITHUB_ENV | |
docker load --input image_linux386/linux386.tar | |
docker load --input image_linuxamd64/linuxamd64.tar | |
docker load --input image_linuxarmv6/linuxarmv6.tar | |
docker load --input image_linuxarmv7/linuxarmv7.tar | |
docker load --input image_linuxarm64/linuxarm64.tar | |
docker load --input image_linuxppc64le/linuxppc64le.tar | |
- name: Login to ghcr registry | |
uses: docker/login-action@v2 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Login to Docker Hub registry | |
uses: docker/login-action@v2 | |
with: | |
username: ${{ secrets.DOCKERHUB_LOGIN }} | |
password: ${{ secrets.DOCKERHUB_TOKEN }} | |
- name: Create and push manifest | |
run: | | |
docker tag ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linux386 ${{ env.IMAGE_TAG_DH }}:${{ env.VERSION }}-linux386 | |
docker tag ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxamd64 ${{ env.IMAGE_TAG_DH }}:${{ env.VERSION }}-linuxamd64 | |
docker tag ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxarmv6 ${{ env.IMAGE_TAG_DH }}:${{ env.VERSION }}-linuxarmv6 | |
docker tag ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxarmv7 ${{ env.IMAGE_TAG_DH }}:${{ env.VERSION }}-linuxarmv7 | |
docker tag ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxarm64 ${{ env.IMAGE_TAG_DH }}:${{ env.VERSION }}-linuxarm64 | |
docker tag ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxppc64le ${{ env.IMAGE_TAG_DH }}:${{ env.VERSION }}-linuxppc64le | |
docker manifest create ${{ env.IMAGE_TAG_DH }}:${{ env.VERSION }} \ | |
--amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linux386 \ | |
--amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxamd64 \ | |
--amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxarmv6 \ | |
--amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxarmv7 \ | |
--amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxarm64 \ | |
--amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxppc64le | |
docker manifest push ${{ env.IMAGE_TAG_DH }}:${{ env.VERSION }} | |
docker manifest create ${{ env.IMAGE_TAG_DH }}:latest \ | |
--amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linux386 \ | |
--amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxamd64 \ | |
--amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxarmv6 \ | |
--amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxarmv7 \ | |
--amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxarm64 \ | |
--amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxppc64le | |
docker manifest push ${{ env.IMAGE_TAG_DH }}:latest |