diff --git a/.github/workflows/build-ubuntu.yml b/.github/workflows/build-ubuntu.yml index 996cb01..5e2f25d 100644 --- a/.github/workflows/build-ubuntu.yml +++ b/.github/workflows/build-ubuntu.yml @@ -23,6 +23,9 @@ env: NODE: '16 18' BUILD_REF: ${{ github.sha }} SKIP_TEST: false + PUSH_GHCR: ${{ github.repository == (github.event.pull_request.head.repo.full_name || github.repository) && '1' || '' }} + PUSH_QUAY: ${{ secrets.QUAY_USER && secrets.QUAY_TOKEN && '1' || '' }} + PUSH_DOCKER_HUB: ${{ secrets.DOCKER_USER && secrets.DOCKER_TOKEN && '1' || '' }} defaults: run: @@ -39,37 +42,30 @@ jobs: max-parallel: 4 matrix: PLATFORMS: - - linux/amd64,linux/arm64,linux/armhf + - linux/amd64,linux/arm64,linux/arm/v7 TAG: - latest - 22.04 - 20.04 steps: - - name: Login to GitHub Container Registry - if: ${{ github.repository_owner == github.actor }} - id: ghcr - uses: docker/login-action@v2 + - name: Force SLUG to lowercase + uses: actions/github-script@v6 with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} + github-token: n/a + script: | + core.exportVariable('SLUG', process.env.SLUG.toLowerCase()); + + - name: Login to GitHub Container Registry + if: env.PUSH_GHCR + run: exec buildah login -u ${{ github.actor }} -p ${{ github.token }} ghcr.io - name: Login to Quay - if: ${{ github.repository_owner == github.actor }} - id: quay - uses: docker/login-action@v2 - with: - registry: quay.io - username: ${{ secrets.QUAY_USER }} - password: ${{ secrets.QUAY_TOKEN }} + if: env.PUSH_QUAY + run: exec buildah login -u ${{ secrets.QUAY_USER }} -p ${{ secrets.QUAY_TOKEN }} quay.io - name: Login to Docker Hub - if: ${{ github.repository_owner == github.actor }} - id: dckr - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKER_USER }} - password: ${{ secrets.DOCKER_TOKEN }} + if: env.PUSH_DOCKER_HUB + run: exec buildah login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_TOKEN }} docker.io - name: Print tag run: | @@ -90,20 +86,10 @@ jobs: - name: Set up QEMU uses: docker/setup-qemu-action@v2 - # setup buildkit ourselves so it doesn't create a new one each time act is executed - - run: | - docker buildx create \ - --use \ - --name image-builder \ - --buildkitd-flags '--allow-insecure-entitlement network.host' \ - --driver docker-container \ - --driver-opt "env.BUILDKIT_STEP_LOG_MAX_SIZE=50000000" \ - --platform "${{ env.PLATFORMS }}" - - uses: actions/checkout@v3 - name: Build and push ${{ env.DISTRO }}:${{ env.TAG }} - shell: pwsh + shell: buildah unshare pwsh "{0}" env: RUNNER: root TAG: act-${{ matrix.TAG }}-${{ env.PART_TAG }} @@ -116,13 +102,13 @@ jobs: ./build.ps1 ` -push ` -tags @( - 'ghcr.io/${{ env.SLUG }}:${{ env.TAG }}', - 'quay.io/${{ env.SLUG }}:${{ env.TAG }}', - 'docker.io/${{ env.SLUG }}:${{ env.TAG }}' + ${{ env.PUSH_GHCR && format('''ghcr.io/{0}:{1}''{2}', env.SLUG, env.TAG, (env.PUSH_QUAY || env.PUSH_DOCKER_HUB) && ',' || '') || '' }} + ${{ env.PUSH_QUAY && format('''quay.io/{0}:{1}''{2}', env.SLUG, env.TAG, (env.PUSH_DOCKER_HUB) && ',' || '') || '' }} + ${{ env.PUSH_DOCKER_HUB && format('''docker.io/{0}:{1}''{2}', env.SLUG, env.TAG, ('') && ',' || '') || '' }} ) - name: Build and push ${{ env.DISTRO }}:${{ env.TAG }} - shell: pwsh + shell: buildah unshare pwsh "{0}" env: RUNNER: runner TAG: runner-${{ matrix.TAG }}-${{ env.PART_TAG }} @@ -135,13 +121,13 @@ jobs: ./build.ps1 ` -push ` -tags @( - 'ghcr.io/${{ env.SLUG }}:${{ env.TAG }}', - 'quay.io/${{ env.SLUG }}:${{ env.TAG }}', - 'docker.io/${{ env.SLUG }}:${{ env.TAG }}' + ${{ env.PUSH_GHCR && format('''ghcr.io/{0}:{1}''{2}', env.SLUG, env.TAG, (env.PUSH_QUAY || env.PUSH_DOCKER_HUB) && ',' || '') || '' }} + ${{ env.PUSH_QUAY && format('''quay.io/{0}:{1}''{2}', env.SLUG, env.TAG, (env.PUSH_DOCKER_HUB) && ',' || '') || '' }} + ${{ env.PUSH_DOCKER_HUB && format('''docker.io/{0}:{1}''{2}', env.SLUG, env.TAG, ('') && ',' || '') || '' }} ) - if: ${{ !env.SKIP_TEST }} - uses: actions/setup-go@v4 + uses: actions/setup-go@v3 with: go-version: '^1.16' @@ -160,7 +146,7 @@ jobs: - name: Build and push ${{ env.DISTRO }}:${{ env.TAG }} if: ${{ ( github.event_name != 'pull_request' && github.event_name != 'push' && !env.ACT ) }} - shell: pwsh + shell: buildah unshare pwsh "{0}" env: TAG: act-${{ matrix.TAG }} TYPE: act @@ -170,16 +156,16 @@ jobs: BUILD_TAG: act-${{ matrix.TAG }} run: | ./build.ps1 ` - -push ` + ${{ '-push' || '' }} ` -tags @( - 'ghcr.io/${{ env.SLUG }}:${{ env.TAG }}', - 'quay.io/${{ env.SLUG }}:${{ env.TAG }}', - 'docker.io/${{ env.SLUG }}:${{ env.TAG }}' + ${{ env.PUSH_GHCR && format('''ghcr.io/{0}:{1}''{2}', env.SLUG, env.TAG, (env.PUSH_QUAY || env.PUSH_DOCKER_HUB) && ',' || '') || '' }} + ${{ env.PUSH_QUAY && format('''quay.io/{0}:{1}''{2}', env.SLUG, env.TAG, (env.PUSH_DOCKER_HUB) && ',' || '') || '' }} + ${{ env.PUSH_DOCKER_HUB && format('''docker.io/{0}:{1}''{2}', env.SLUG, env.TAG, ('') && ',' || '') || '' }} ) - name: Build and push ${{ env.DISTRO }}:${{ env.TAG }} if: ${{ ( github.event_name != 'pull_request' && github.event_name != 'push' && !env.ACT ) }} - shell: pwsh + shell: buildah unshare pwsh "{0}" env: RUNNER: runner TAG: runner-${{ matrix.TAG }} @@ -192,9 +178,9 @@ jobs: ./build.ps1 ` -push ` -tags @( - 'ghcr.io/${{ env.SLUG }}:${{ env.TAG }}', - 'quay.io/${{ env.SLUG }}:${{ env.TAG }}', - 'docker.io/${{ env.SLUG }}:${{ env.TAG }}' + ${{ env.PUSH_GHCR && format('''ghcr.io/{0}:{1}''{2}', env.SLUG, env.TAG, (env.PUSH_QUAY || env.PUSH_DOCKER_HUB) && ',' || '') || '' }} + ${{ env.PUSH_QUAY && format('''quay.io/{0}:{1}''{2}', env.SLUG, env.TAG, (env.PUSH_DOCKER_HUB) && ',' || '') || '' }} + ${{ env.PUSH_DOCKER_HUB && format('''docker.io/{0}:{1}''{2}', env.SLUG, env.TAG, ('') && ',' || '') || '' }} ) build-flavours: @@ -223,31 +209,24 @@ jobs: - dotnet - custom steps: - - name: Login to GitHub Container Registry - if: ${{ github.repository_owner == github.actor }} - id: ghcr - uses: docker/login-action@v2 + - name: Force SLUG to lowercase + uses: actions/github-script@v6 with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} + github-token: n/a + script: | + core.exportVariable('SLUG', process.env.SLUG.toLowerCase()); + + - name: Login to GitHub Container Registry + if: env.PUSH_GHCR + run: exec buildah login -u ${{ github.actor }} -p ${{ github.token }} ghcr.io - name: Login to Quay - if: ${{ github.repository_owner == github.actor }} - id: quay - uses: docker/login-action@v2 - with: - registry: quay.io - username: ${{ secrets.QUAY_USER }} - password: ${{ secrets.QUAY_TOKEN }} + if: env.PUSH_QUAY + run: exec buildah login -u ${{ secrets.QUAY_USER }} -p ${{ secrets.QUAY_TOKEN }} quay.io - name: Login to Docker Hub - if: ${{ github.repository_owner == github.actor }} - id: dckr - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKER_USER }} - password: ${{ secrets.DOCKER_TOKEN }} + if: env.PUSH_DOCKER_HUB + run: exec buildah login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_TOKEN }} docker.io - name: Print tag run: | @@ -268,19 +247,10 @@ jobs: - name: Set up QEMU uses: docker/setup-qemu-action@v2 - - run: | - docker buildx create \ - --use \ - --name image-builder \ - --buildkitd-flags '--allow-insecure-entitlement network.host' \ - --driver docker-container \ - --driver-opt "env.BUILDKIT_STEP_LOG_MAX_SIZE=50000000" \ - --platform "${{ env.PLATFORMS }}" - - uses: actions/checkout@v3 - name: Build and push ${{ env.DISTRO }}:${{ env.TAG }} - shell: pwsh + shell: buildah unshare pwsh "{0}" env: TAG: ${{ matrix.TYPE }}-${{ matrix.TAG }}-${{ env.PART_TAG }} FROM_IMAGE: ghcr.io/${{ env.SLUG }} @@ -290,13 +260,13 @@ jobs: ./build.ps1 ` -push ` -tags @( - 'ghcr.io/${{ env.SLUG }}:${{ env.TAG }}', - 'quay.io/${{ env.SLUG }}:${{ env.TAG }}', - 'docker.io/${{ env.SLUG }}:${{ env.TAG }}' + ${{ env.PUSH_GHCR && format('''ghcr.io/{0}:{1}''{2}', env.SLUG, env.TAG, (env.PUSH_QUAY || env.PUSH_DOCKER_HUB) && ',' || '') || '' }} + ${{ env.PUSH_QUAY && format('''quay.io/{0}:{1}''{2}', env.SLUG, env.TAG, (env.PUSH_DOCKER_HUB) && ',' || '') || '' }} + ${{ env.PUSH_DOCKER_HUB && format('''docker.io/{0}:{1}''{2}', env.SLUG, env.TAG, ('') && ',' || '') || '' }} ) - name: Build and push ${{ env.DISTRO }}:${{ env.TAG }} - shell: pwsh + shell: buildah unshare pwsh "{0}" if: ${{ ( github.event_name != 'pull_request' && github.event_name != 'push' && !env.ACT ) }} env: TAG: ${{ matrix.TYPE }}-${{ matrix.TAG }} @@ -307,7 +277,7 @@ jobs: ./build.ps1 ` -push ` -tags @( - 'ghcr.io/${{ env.SLUG }}:${{ env.TAG }}', - 'quay.io/${{ env.SLUG }}:${{ env.TAG }}', - 'docker.io/${{ env.SLUG }}:${{ env.TAG }}' - ) + ${{ env.PUSH_GHCR && format('''ghcr.io/{0}:{1}''{2}', env.SLUG, env.TAG, (env.PUSH_QUAY || env.PUSH_DOCKER_HUB) && ',' || '') || '' }} + ${{ env.PUSH_QUAY && format('''quay.io/{0}:{1}''{2}', env.SLUG, env.TAG, (env.PUSH_DOCKER_HUB) && ',' || '') || '' }} + ${{ env.PUSH_DOCKER_HUB && format('''docker.io/{0}:{1}''{2}', env.SLUG, env.TAG, ('') && ',' || '') || '' }} + ) \ No newline at end of file diff --git a/build.ps1 b/build.ps1 index db5ca5e..83772ab 100644 --- a/build.ps1 +++ b/build.ps1 @@ -37,22 +37,40 @@ param( [switch]$push ) -$basetags = @() +# https://stackoverflow.com/a/33545660 +function Flatten-Array{ + $input | ForEach-Object{ + if (($_ -is [array]) -and (-not ($_ -is [string])) ){$_ | Flatten-Array}else{$_} + } | Where-Object{![string]::IsNullorEmpty($_)} +} -$regstryid = $(& (Get-Command 'docker').source run --rm -d -p 8192:5000 registry:2) +function exec() { + $path, $myargs = $args | Flatten-Array + & "$path" $myargs + if($LASTEXITCODE -ne 0) { + throw "$($args | Flatten-Array) failed with exit code $LASTEXITCODE" + } +} +function exec_out() { + $path, $myargs = $args | Flatten-Array + $stdout = "$(& "$path" $myargs)" + if($LASTEXITCODE -ne 0) { + throw "$($args | Flatten-Array) failed with exit code $LASTEXITCODE, error: $stdout" + } + return "$stdout" +} + +$manifest = "$(New-Guid)-manifest:latest" + +exec buildah manifest create "$manifest" ForEach($platform in $platforms.Split(",")) { + $intermediatetag = "$(New-Guid)-intermediate:latest" + $arguments = @( - 'buildx', - 'build' - ) - - $arguments += $progress -ne '' ? @("--progress=$progress") : @("--progress=plain") - - $intermediatetag = "localhost:8192/intermediate:$($platform.Replace("/", "-"))" - - $arguments += @( - "--tag=${intermediatetag}", + "buildah", + "build", + "--platform=${platform}", "--build-arg=NODE_VERSION=${node}", "--build-arg=DISTRO=${distro}", "--build-arg=TYPE=${type}", @@ -67,55 +85,35 @@ ForEach($platform in $platforms.Split(",")) { "--build-arg=FROM_IMAGE=${from_image}", "--build-arg=FROM_TAG=${from_tag}", "--file=./linux/${image}/Dockerfile", - "--platform=${platform}", - "--load", - '.' - ) - - & (Get-Command 'docker').source $arguments - - # Not using buildx here, because buildx doesn't like a localhost registry - $arguments = @( - 'build' - ) - - $arguments += $progress -ne '' ? @("--progress=$progress") : @("--progress=plain") - - $imageid = $(& (Get-Command 'docker').source create "${intermediatetag}") - - $envfileContent = $(& (Get-Command 'docker').source cp "${imageid}:/etc/environment" - | tar x --to-stdout) - - & (Get-Command 'docker').source rm "${imageid}" - - echo "FROM ${intermediatetag}" > Dockerfile.tmp - - ForEach($envline in $envfileContent.Split("\n")) { - echo "ENV $envline" >> Dockerfile.tmp - } - - $arguments += @( "--tag=${intermediatetag}", - "--file=./Dockerfile.tmp", + "--format=docker", '.' ) - & (Get-Command 'docker').source $arguments - - & (Get-Command 'docker').source push ${intermediatetag} - - $basetags += @("${intermediatetag}") + exec $arguments + $containerName = New-Guid + # buildah bug: https://github.com/containers/buildah/commit/4b7d3555bfa4440c3c5264ae44b93822e10deec0 + # The arm variant is dropped in the previous step this causes a failure here + $plat = $platform.Split("/") + exec buildah from --format=docker --name "$containerName-container" --platform "$($plat[0])/$($plat[1])" "$intermediatetag" + $containerpath = exec_out buildah mount "$containerName-container" + $envfileContent = Get-Content "$containerpath/etc/environment" + $arguments = @( + "buildah", + "config" + ) + ForEach($envline in $envfileContent) { + $arguments += "--env","$envline" + } + $arguments += @("$containerName-container") + exec $arguments + exec buildah unmount "$containerName-container" + exec buildah commit --format=docker "$containerName-container" "$containerName-image" + exec buildah manifest add "$manifest" "$containerName-image" } -$arguments = @() - -if($push -ne $true) { - $arguments += @("--dry-run") +if($push -eq $true) { + ForEach($t in ($tags + ($tag -ne '' ? @("$tag") : @()))) { + exec buildah manifest push --all "$manifest" "docker://$t" + } } - -$tags.Count -ne 0 ? ($tags | ForEach-Object { $arguments += @("--tag=$_") }) : "" - -$arguments += $tag -ne '' ? @("--tag=$tag") : @() - -& (Get-Command 'docker').source buildx imagetools create $arguments $basetags - -& (Get-Command 'docker').source stop $regstryid