GithubHelp home page GithubHelp logo

Comments (4)

Raboo avatar Raboo commented on June 16, 2024 1

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.

from buildah-build.

Raboo avatar Raboo commented on June 16, 2024

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?

from buildah-build.

kaovilai avatar kaovilai commented on June 16, 2024

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

from buildah-build.

kaovilai avatar kaovilai commented on June 16, 2024

Awesome!

from buildah-build.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.