name: Docker Images for Framework # # Update Docker images we use for building CI # on: workflow_dispatch: schedule: - cron: '0 3 * * *' # Scheduled runs every day at 3am UTC permissions: contents: write actions: write packages: write jobs: docker-per-arch: if: ${{ github.repository_owner == 'armbian' }} strategy: fail-fast: false # let other jobs try to complete if one fails matrix: include: #### NOTE(rpardini): needs to be kept in-sync with the second job "join-arches" down below around line 152 - { os: "ubuntu", release: "jammy", arch: "amd64", runner: "ubuntu-22.04" } - { os: "ubuntu", release: "jammy", arch: "arm64", runner: "ubuntu-22.04-arm" } - { os: "debian", release: "bookworm", arch: "amd64", runner: "ubuntu-24.04" } - { os: "debian", release: "bookworm", arch: "arm64", runner: "ubuntu-24.04-arm" } - { os: "debian", release: "trixie", arch: "amd64", runner: "ubuntu-24.04" } - { os: "debian", release: "trixie", arch: "arm64", runner: "ubuntu-24.04-arm" } - { os: "ubuntu", release: "noble", arch: "amd64", runner: "ubuntu-24.04" } - { os: "ubuntu", release: "noble", arch: "arm64", runner: "ubuntu-24.04-arm" } runs-on: "${{ matrix.runner }}" name: "${{ matrix.release }} ${{ matrix.arch }} (${{ matrix.os }})" env: DOCKERFILE_OS: "${{ matrix.os }}" DOCKERFILE_RELEASE: "${{ matrix.release }}" steps: - name: Checkout Armbian Framework uses: actions/checkout@v4 with: repository: armbian/build ref: main fetch-depth: 1 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx id: buildx_1 continue-on-error: true # this process is prone to failure, lets repeat it again if fails uses: docker/setup-buildx-action@v3 - name: Set up Docker Buildx (retry) id: buildx_2 if: steps.buildx.outcome == 'failure' uses: docker/setup-buildx-action@v3 - name: Set up Docker Buildx id: buildx_3 if: steps.buildx.outcome == 'failure' uses: docker/setup-buildx-action@v3 - name: Docker Login to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.repository_owner }} # github username or org password: ${{ secrets.GITHUB_TOKEN }} # github actions builtin token. repo has to have pkg access. - name: Prepare id: prep run: echo "created=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT - name: Generate Dockerfile for ${{env.DOCKERFILE_OS}}:${{env.DOCKERFILE_RELEASE}} via Armbian helper script id: generate env: DOCKER_ARMBIAN_BASE_IMAGE: "${{env.DOCKERFILE_OS}}:${{env.DOCKERFILE_RELEASE}}" # Use this base image DOCKERFILE_USE_ARMBIAN_IMAGE_AS_BASE: "no" # Do NOT use the Armbian image as base image to speed up; we're creating it here run: | bash ./compile.sh generate-dockerfile - name: Build and push ${{env.DOCKERFILE_OS}}:${{env.DOCKERFILE_RELEASE}} (first try) id: docker_build_first continue-on-error: true timeout-minutes: 40 uses: docker/build-push-action@v6 with: context: . provenance: false # until ghcr.io doesn't show provenance attestations properly, it reports an unknown/unknown "arch" instead. disable sbom: false # no SBOM for now, ghcr.io doesn't support it and pukes file: ./Dockerfile platforms: "linux/${{ matrix.arch }}" pull: true # Pull new version of base image, always; avoid bit-rot push: true labels: | org.opencontainers.image.title=${{ github.repository }} org.opencontainers.image.description=${{ github.event.repository.description }} org.opencontainers.image.url=${{ github.event.repository.html_url }} org.opencontainers.image.source=${{ github.event.repository.clone_url }} org.opencontainers.image.created=${{ steps.prep.outputs.created }} org.opencontainers.image.revision=${{ github.sha }} org.opencontainers.image.licenses=${{ github.event.repository.license.spdx_id }} tags: ghcr.io/${{ github.repository }}:armbian-${{env.DOCKERFILE_OS}}-${{env.DOCKERFILE_RELEASE}}-${{ matrix.arch }}-latest - name: sleep a random amount of seconds, up to 60, if build/push failed, before trying again if: steps.docker_build_first.outcome == 'failure' run: | echo "::notice os=${{env.DOCKERFILE_OS}},release=${{env.DOCKERFILE_RELEASE}}::Build/push failed, retrying" sleep $((RANDOM % 60)) - name: Build and push again (second try if first failed) id: docker_build_second if: steps.docker_build_first.outcome == 'failure' continue-on-error: false # let the build break if the two tries fail timeout-minutes: 40 uses: docker/build-push-action@v6 with: context: . provenance: false # until ghcr.io doesn't show provenance attestations properly, it reports an unknown/unknown "arch" instead. disable sbom: false # no SBOM for now, ghcr.io doesn't support it and pukes file: ./Dockerfile platforms: "linux/${{ matrix.arch }}" pull: true # Pull new version of base image, always; avoid bit-rot push: true labels: | org.opencontainers.image.title=${{ github.repository }} org.opencontainers.image.description=${{ github.event.repository.description }} org.opencontainers.image.url=${{ github.event.repository.html_url }} org.opencontainers.image.source=${{ github.event.repository.clone_url }} org.opencontainers.image.created=${{ steps.prep.outputs.created }} org.opencontainers.image.revision=${{ github.sha }} org.opencontainers.image.licenses=${{ github.event.repository.license.spdx_id }} tags: ghcr.io/${{ github.repository }}:armbian-${{env.DOCKERFILE_OS}}-${{env.DOCKERFILE_RELEASE}}-${{ matrix.arch }}-latest join-arches: if: ${{ github.repository_owner == 'armbian' }} runs-on: ubuntu-latest needs: docker-per-arch # Use docker manifest to join the multi-arch images into a single manifest for each os+release steps: - name: Docker Login to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.repository_owner }} # github username or org password: ${{ secrets.GITHUB_TOKEN }} # github actions builtin token. repo has to have pkg access. - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: ubuntu-jammy - Create and push multi-arch manifest using buildx run: | docker buildx imagetools create -t \ ghcr.io/${{ github.repository }}:armbian-ubuntu-jammy-latest \ ghcr.io/${{ github.repository }}:armbian-ubuntu-jammy-amd64-latest \ ghcr.io/${{ github.repository }}:armbian-ubuntu-jammy-arm64-latest docker buildx imagetools inspect ghcr.io/${{ github.repository }}:armbian-ubuntu-jammy-latest - name: debian-bookworm - Create and push multi-arch manifest using buildx run: | docker buildx imagetools create -t \ ghcr.io/${{ github.repository }}:armbian-debian-bookworm-latest \ ghcr.io/${{ github.repository }}:armbian-debian-bookworm-amd64-latest \ ghcr.io/${{ github.repository }}:armbian-debian-bookworm-arm64-latest docker buildx imagetools inspect ghcr.io/${{ github.repository }}:armbian-debian-bookworm-latest - name: debian-trixie - Create and push multi-arch manifest using buildx run: | docker buildx imagetools create -t \ ghcr.io/${{ github.repository }}:armbian-debian-trixie-latest \ ghcr.io/${{ github.repository }}:armbian-debian-trixie-amd64-latest \ ghcr.io/${{ github.repository }}:armbian-debian-trixie-arm64-latest docker buildx imagetools inspect ghcr.io/${{ github.repository }}:armbian-debian-trixie-latest - name: ubuntu-noble - Create and push multi-arch manifest using buildx run: | docker buildx imagetools create -t \ ghcr.io/${{ github.repository }}:armbian-ubuntu-noble-latest \ ghcr.io/${{ github.repository }}:armbian-ubuntu-noble-amd64-latest \ ghcr.io/${{ github.repository }}:armbian-ubuntu-noble-arm64-latest docker buildx imagetools inspect ghcr.io/${{ github.repository }}:armbian-ubuntu-noble-latest keepalive: if: ${{ github.repository_owner == 'armbian' }} name: Keep Alive needs: join-arches runs-on: ubuntu-latest permissions: actions: write steps: - uses: actions/checkout@v4 - uses: liskin/gh-workflow-keepalive@v1