Docker multi-arch build and push #15
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: Docker multi-arch build and push | |
on: | |
workflow_dispatch: ~ | |
jobs: | |
build: | |
name: Build Docker image (${{ matrix.arch }}) | |
runs-on: ubuntu-latest | |
env: | |
IMAGE_TAG: ${{ secrets.DOCKER_USERNAME }}/telegram-bot-api | |
ALPINE_VERSION: '3.20' | |
strategy: | |
matrix: | |
arch: | |
- linux/386 | |
- linux/amd64 | |
steps: | |
- name: Checkout current repo | |
uses: actions/checkout@v4 | |
- name: Checkout upstream repo | |
uses: actions/checkout@v4 | |
with: | |
repository: paigramteam/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) | |
# Convert IMAGE_TAG, HASH_VERSION and VERSION to lowercase (repository name must be lowercase) | |
IMAGE_TAG=$(echo "$IMAGE_TAG" | 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 "VERSION=$VERSION" >> $GITHUB_ENV | |
echo "SAFE_ARCH=$SAFE_ARCH" >> $GITHUB_ENV | |
# Print debug info | |
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 Docker Hub registry | |
uses: docker/login-action@v2 | |
if: ${{ github.event_name != 'pull_request' }} | |
with: | |
username: ${{ secrets.DOCKER_USERNAME }} | |
password: ${{ secrets.DOCKER_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 }} | |
build-args: | | |
ALPINE_VERSION=${{ env.ALPINE_VERSION }} | |
push: false | |
load: true | |
tags: | | |
${{ env.IMAGE_TAG }}:${{ env.VERSION }}-${{ env.SAFE_ARCH }} | |
- name: Tag and push image | |
if: ${{ github.event_name != 'pull_request' }} | |
run: | | |
docker push ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-${{ env.SAFE_ARCH }} | |
- name: Save image as tar archive | |
if: ${{ github.event_name != 'pull_request' }} | |
run: | | |
docker save ${{ env.IMAGE_TAG }}:${{ env.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' }} | |
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 | |
- name: Login to Docker Hub registry | |
uses: docker/login-action@v2 | |
with: | |
username: ${{ secrets.DOCKER_USERNAME }} | |
password: ${{ secrets.DOCKER_TOKEN }} | |
- name: Create and push manifest | |
run: | | |
docker manifest create ${{ env.IMAGE_TAG }}:${{ env.VERSION }} \ | |
--amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linux386 \ | |
--amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxamd64 | |
docker manifest push ${{ env.IMAGE_TAG }}:${{ env.VERSION }} | |
docker manifest create ${{ env.IMAGE_TAG }}:latest \ | |
--amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linux386 \ | |
--amend ${{ env.IMAGE_TAG }}:${{ env.VERSION }}-linuxamd64 | |
docker manifest push ${{ env.IMAGE_TAG }}:latest |