Open kaovilai opened 1 year ago
I was also caught with the same problem.
I am able to build multiple architectures. But not publish, it simply overwrites the tag so only one architecture is available in ghcr.io.
name: Build container images
on: [push, workflow_dispatch]
concurrency:
group: '${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
cancel-in-progress: true
jobs:
build-image:
name: Build image
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
strategy:
matrix:
platform: [linux/amd64, linux/arm64]
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
submodules: true
- name: cache podman
uses: actions/cache@v3
with:
path: ~/.local/share/containers
key: podman
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: set lower case owner name
run: |
echo "OWNER_LC=${OWNER,,}" >>${GITHUB_ENV}
env:
OWNER: '${{ github.repository_owner }}'
- name: Container meta
id: meta
uses: docker/metadata-action@v4
with:
images: |
ghcr.io/${{ env.OWNER_LC }}/rtfm
tags: |
type=semver,pattern={{version}},value=${{ inputs.version }}
type=semver,pattern={{major}}.{{minor}},value=${{ inputs.version }}
type=semver,pattern={{major}},value=${{ inputs.version }}
type=ref,event=branch
type=ref,event=pr
# type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') }}
flavor: |
latest=${{ github.ref_name == github.event.repository.default_branch }}
- name: Build Image
id: build-image
uses: redhat-actions/buildah-build@v2
with:
image: rtfm
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
oci: true
containerfiles: |
./Dockerfile
platforms: ${{ matrix.platform }}
# I guess this is the part that needs some type of resource sharing between the runners.
- name: Push image to GHCR
uses: redhat-actions/push-to-registry@v2
id: push
with:
image: ${{ steps.build-image.outputs.image }}
tags: ${{ steps.build-image.outputs.tags }}
username: ${{ github.actor }}
password: ${{ github.token }}
registry: ghcr.io/${{ env.OWNER_LC }}
- name: Print image url
run: echo "Image pushed to ${{ steps.push.outputs.registry-paths }}"
Anyone has a good solution for this?
you would have to create manifests list containing different (already pushed single-arch, built by different runners) tags then push the manifest list in the final runner
Ok, I cracked it!
Here is a working example using multiple runners to build for each architecture, that later upload their images to github temporary storage and a runner that downloads the different architecture images and merges them and publishes to GHCR.
name: Build container images
on: [push, workflow_dispatch]
concurrency:
group: '${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
jobs:
build:
name: Build image
runs-on: ubuntu-latest
strategy:
matrix:
platform: [linux/amd64, linux/arm64]
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
submodules: true
- name: cache podman storage
uses: actions/cache@v3
with:
path: ~/.local/share/containers/storage
key: podman-storage-${{ matrix.platform }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: set lower case owner name
run: |
echo "OWNER_LC=${OWNER,,}" >>${GITHUB_ENV}
env:
OWNER: '${{ github.repository_owner }}'
- name: export architecture name (removing os prefix)
run: |
echo "PODMAN_ARCH=${PLATFORM#*/}" >>${GITHUB_ENV}
env:
PLATFORM: ${{ matrix.platform }}
- name: Container meta
id: meta
uses: docker/metadata-action@v4
with:
images: |
ghcr.io/${{ env.OWNER_LC }}/rtfm
tags: |
type=raw,value=build
flavor: |
suffix=-${{ env.PODMAN_ARCH }}
- name: Build Image
id: build-image
uses: redhat-actions/buildah-build@v2
with:
image: rtfm
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
oci: true
containerfiles: |
./Dockerfile
platforms: ${{ matrix.platform }}
- run: skopeo copy containers-storage:ghcr.io/${{ env.OWNER_LC }}/rtfm:build-${{ env.PODMAN_ARCH }} oci-archive:/tmp/${{ env.PODMAN_ARCH }}-oci.tar
- name: Upload digest
uses: actions/upload-artifact@v3
with:
name: rtfm-build-${{ env.PODMAN_ARCH }}
path: /tmp/${{ env.PODMAN_ARCH }}-oci.tar
if-no-files-found: error
retention-days: 1
upload:
name: Upload images
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
needs: build
steps:
- name: Download podman
uses: actions/download-artifact@v3
with:
name: rtfm-build-amd64
path: /tmp
- name: Download podman
uses: actions/download-artifact@v3
with:
name: rtfm-build-arm64
path: /tmp
- name: set lower case owner name
run: |
echo "OWNER_LC=${OWNER,,}" >>${GITHUB_ENV}
env:
OWNER: '${{ github.repository_owner }}'
- run: podman manifest create ghcr.io/${{ env.OWNER_LC }}/rtfm:manifest
- run: podman manifest add ghcr.io/${{ env.OWNER_LC }}/rtfm:manifest oci-archive:/tmp/arm64-oci.tar
- run: podman manifest add ghcr.io/${{ env.OWNER_LC }}/rtfm:manifest oci-archive:/tmp/amd64-oci.tar
# - run: podman manifest inspect ghcr.io/${{ env.OWNER_LC }}/rtfm:manifest
- name: Container meta
id: meta
uses: docker/metadata-action@v4
with:
images: |
ghcr.io/${{ env.OWNER_LC }}/rtfm
tags: |
type=semver,pattern={{version}},value=${{ inputs.version }}
type=semver,pattern={{major}}.{{minor}},value=${{ inputs.version }}
type=semver,pattern={{major}},value=${{ inputs.version }}
type=ref,event=branch
type=ref,event=pr
# type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') }}
flavor: |
latest=${{ github.ref_name == github.event.repository.default_branch }}
- name: add tags
run: |
# fix multi-line issue from steps.meta.outputs.tags
podman tag ghcr.io/${{ env.OWNER_LC }}/rtfm:manifest $(echo "${{ steps.meta.outputs.tags }}" | tr '\n' ' ')
- name: Push image to GHCR
uses: redhat-actions/push-to-registry@v2
id: push
with:
image: rtfm
tags: ${{ steps.meta.outputs.tags }}
username: ${{ github.actor }}
password: ${{ github.token }}
registry: ghcr.io/${{ env.OWNER_LC }}
- name: Print image url
run: echo "Image pushed to ${{ steps.push.outputs.registry-paths }}"
I guess we now need to document this example somewhere.
Awesome!
Is your feature request related to a problem? Please describe.
Clone of https://github.com/docker/docs/issues/16593
Describe the solution you'd like
similar to https://github.com/docker/docs/pull/17180
Describe alternatives you've considered
Additional context
This should allow us to use more runner resources for longer multiarch builds.