diff --git a/.github/workflows/buildkit.yml b/.github/workflows/buildkit.yml index 37414fe1d2f7..5a19c4ae1760 100644 --- a/.github/workflows/buildkit.yml +++ b/.github/workflows/buildkit.yml @@ -50,60 +50,66 @@ jobs: fields: platforms binaries: + uses: docker/github-builder-experimental/.github/workflows/bake.yml@c56377b5e16c21afb2f3ea02f9021a1ed4b51f45 + permissions: + contents: read + id-token: write # for signing attestation manifests and registry authentication if needed with GitHub OIDC Token + packages: write # for pushing manifests to GHCR if needed (caller must provide the same permissions used in the reusable workflow) + with: + runner: amd64 + target: release + output: local + push: ${{ github.event_name != 'pull_request' }} + artifact-name: buildkit + cache: true + cache-scope: binaries + setup-qemu: true + bake-sbom: true + bake-set: | + *.no-cache-filter=${{ startsWith(github.ref, 'refs/tags/v') && 'gobuild-base' || '' }} + + binaries-finalize: runs-on: ubuntu-24.04 needs: - - prepare - strategy: - fail-fast: false - matrix: - include: ${{ fromJson(needs.prepare.outputs.binaries-platforms) }} + - binaries steps: - - name: Prepare - run: | - platform=${{ matrix.platforms }} - echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - with: - version: ${{ env.SETUP_BUILDX_VERSION }} - driver-opts: image=${{ env.SETUP_BUILDKIT_IMAGE }} - buildkitd-flags: --debug - - - name: Build - uses: docker/bake-action@v6 + name: Download artifacts + uses: actions/download-artifact@v6 with: - # FIXME: remove context once git context with query string implemented in actions-toolkit - source: ${{ github.server_url }}/${{ github.repository }}.git#${{ github.ref }} - targets: release - provenance: mode=max - sbom: true - set: | - *.platform=${{ matrix.platforms }} - *.cache-from=type=gha,scope=binaries - *.cache-to=type=gha,scope=binaries - *.no-cache-filter=${{ startsWith(github.ref, 'refs/tags/v') && 'gobuild-base' || '' }} + path: /tmp/buildx-output + pattern: ${{ needs.binaries.outputs.artifact-name }}* + merge-multiple: true - name: Rename provenance and sbom + run: | + for pdir in /tmp/buildx-output/*/; do + ( + cd "$pdir" + binname=$(find . -name 'buildkit-*') + filename=$(basename "$binname" | sed -E 's/\.(tar\.gz|zip)$//') + mv "provenance.json" "${filename}.provenance.json" + mv "sbom-binaries.spdx.json" "${filename}.sbom.json" + find . -name 'sbom*.json' -exec rm {} \; + if [ -f "provenance.sigstore.json" ]; then + mv "provenance.sigstore.json" "${filename}.provenance.sigstore.json" + fi + ) + done + mkdir -p "${{ env.DESTDIR }}" + mv /tmp/buildx-output/**/* "${{ env.DESTDIR }}/" + - + name: List artifacts working-directory: ${{ env.DESTDIR }} run: | - binname=$(find . -name 'buildkit-*') - filename=$(basename "$binname" | sed -E 's/\.(tar\.gz|zip)$//') - mv "provenance.json" "${filename}.provenance.json" - mv "sbom-binaries.spdx.json" "${filename}.sbom.json" - find . -name 'sbom*.json' -exec rm {} \; + tree -nh . - - name: Upload artifacts + name: Upload release binaries uses: actions/upload-artifact@v5 with: - name: buildkit-${{ env.PLATFORM_PAIR }} + name: release path: ${{ env.DESTDIR }}/* if-no-files-found: error - retention-days: 1 test: uses: ./.github/workflows/.test.yml @@ -164,128 +170,130 @@ jobs: with: sarif_file: ${{ env.DESTDIR }}/govulncheck.out - image: + image-prepare: runs-on: ubuntu-24.04 - env: - DEFAULT_BASE: alpine + outputs: + includes: ${{ steps.set.outputs.includes }} + steps: + - + name: Set outputs + id: set + uses: actions/github-script@v8 + env: + INPUT_DEFAULT-BASE: alpine + INPUT_REF: ${{ github.ref }} + INPUT_IMAGE-NAME: ${{ env.IMAGE_NAME }} + with: + script: | + const defaultBase = core.getInput('default-base'); + const ref = core.getInput('ref'); + const imageName = core.getInput('image-name'); + + function getTagSuffixAndLatest(base, target) { + let tagSuffix = ''; + if (target) { + tagSuffix += `-${target}`; + } + if (base && base !== defaultBase) { + tagSuffix += `-${base}`; + } + let tagLatest = ''; + if (ref && ref.startsWith('refs/tags/v')) { + const version = ref.replace('refs/tags/', ''); + if (/^v[0-9]+\.[0-9]+\.[0-9]+$/.test(version)) { + tagLatest = target ? target : 'latest'; + if (base && base !== defaultBase) { + tagLatest += `-${base}`; + } + } + } + return { tagSuffix, tagLatest }; + } + + const matrix = [ + { base: 'alpine' }, + { base: 'alpine', target: 'rootless'}, + { base: 'ubuntu', buildTags: 'nvidia venus' } + ] + + for (const entry of matrix) { + const { tagSuffix, tagLatest } = getTagSuffixAndLatest(entry.base, entry.target); + entry.imageName = imageName; + entry.tagSuffix = tagSuffix; + entry.tagLatest = tagLatest; + } + + core.info(JSON.stringify(matrix, null, 2)); + core.setOutput('includes', JSON.stringify(matrix)); + + image: + uses: docker/github-builder-experimental/.github/workflows/bake.yml@c56377b5e16c21afb2f3ea02f9021a1ed4b51f45 needs: + - image-prepare - test strategy: fail-fast: false matrix: - include: - - - base: 'alpine' - - - base: 'alpine' - target: 'rootless' - - - base: 'ubuntu' - build-tags: 'nvidia venus' - steps: - - - name: Prepare - run: | - tagSuffix="" - if [ -n "${{ matrix.target }}" ]; then - tagSuffix="${tagSuffix}-${{ matrix.target }}" - fi - if [ "${{ matrix.base }}" != "$DEFAULT_BASE" ]; then - tagSuffix="${tagSuffix}-${{ matrix.base }}" - fi - echo "TAG_SUFFIX=${tagSuffix}" >> $GITHUB_ENV - if [[ $GITHUB_REF == refs/tags/v* ]]; then - if [[ "${GITHUB_REF#refs/tags/}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - tagLatest="" - if [ -n "${{ matrix.target }}" ]; then - tagLatest=${{ matrix.target }} - else - tagLatest=latest - fi - if [ "${{ matrix.base }}" != "$DEFAULT_BASE" ]; then - tagLatest="${tagLatest}-${{ matrix.base }}" - fi - echo "TAG_LATEST=${tagLatest}" >> $GITHUB_ENV - fi - fi - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - with: - version: ${{ env.SETUP_BUILDX_VERSION }} - driver-opts: image=${{ env.SETUP_BUILDKIT_IMAGE }} - buildkitd-flags: --debug - - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 - with: - images: | - ${{ env.IMAGE_NAME }} - # versioning strategy - ## push semver tag v0.24.0 - ### moby/buildkit:v0.24.0 - ### moby/buildkit:latest - ### moby/buildkit:v0.24.0-rootless - ### moby/buildkit:rootless - ### moby/buildkit:v0.24.0-ubuntu - ### moby/buildkit:latest-ubuntu - ## push semver prerelease tag v0.24.0-rc1 - ### moby/buildkit:v0.24.0-rc1 - ### moby/buildkit:v0.24.0-rc1-rootless - ### moby/buildkit:v0.24.0-rc1-ubuntu - ## push on master - ### moby/buildkit:master - ### moby/buildkit:master-rootless - ### moby/buildkit:master-ubuntu - ## scheduled event on master - ### moby/buildkit:nightly - ### moby/buildkit:nightly-rootless - ### moby/buildkit:nightly-ubuntu - tags: | - type=schedule,pattern=nightly,suffix=${{ env.TAG_SUFFIX }} - type=ref,event=branch,suffix=${{ env.TAG_SUFFIX }} - type=ref,event=pr,suffix=${{ env.TAG_SUFFIX }} - type=semver,pattern={{raw}},suffix=${{ env.TAG_SUFFIX }} - type=raw,value=${{ env.TAG_LATEST }} - flavor: | - latest=false - annotations: | - org.opencontainers.image.title=BuildKit - org.opencontainers.image.vendor=Moby - bake-target: meta-helper - - - name: Login to DockerHub - if: ${{ github.repository == 'moby/buildkit' && (github.event_name == 'schedule' || github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v')) }} - uses: docker/login-action@v3 - with: + include: ${{ fromJson(needs.image-prepare.outputs.includes) }} + permissions: + contents: read + id-token: write # for signing attestation manifests and registry authentication if needed with GitHub OIDC Token + packages: write # for pushing manifests to GHCR if needed (caller must provide the same permissions used in the reusable workflow) + with: + runner: amd64 + target: image-cross + output: image + push: ${{ github.repository == 'moby/buildkit' && (github.event_name == 'schedule' || github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v')) }} + envs: | + IMAGE_TARGET=${{ matrix.target }} + EXPORT_BASE=${{ matrix.base }} + BUILDKITD_TAGS=${{ matrix.buildTags }} + cache: true + cache-scope: image${{ matrix.target }}-${{ matrix.base }} + set-meta-annotations: true + meta-images: | + ${{ matrix.imageName }} + # versioning strategy + ## push semver tag v0.24.0 + ### moby/buildkit:v0.24.0 + ### moby/buildkit:latest + ### moby/buildkit:v0.24.0-rootless + ### moby/buildkit:rootless + ### moby/buildkit:v0.24.0-ubuntu + ### moby/buildkit:latest-ubuntu + ## push semver prerelease tag v0.24.0-rc1 + ### moby/buildkit:v0.24.0-rc1 + ### moby/buildkit:v0.24.0-rc1-rootless + ### moby/buildkit:v0.24.0-rc1-ubuntu + ## push on master + ### moby/buildkit:master + ### moby/buildkit:master-rootless + ### moby/buildkit:master-ubuntu + ## scheduled event on master + ### moby/buildkit:nightly + ### moby/buildkit:nightly-rootless + ### moby/buildkit:nightly-ubuntu + meta-tags: | + type=schedule,pattern=nightly,suffix=${{ matrix.tagSuffix }} + type=ref,event=branch,suffix=${{ matrix.tagSuffix }} + type=ref,event=pr,suffix=${{ matrix.tagSuffix }} + type=semver,pattern={{raw}},suffix=${{ matrix.tagSuffix }} + type=raw,value=${{ matrix.tagLatest }} + meta-flavor: | + latest=false + meta-annotations: | + org.opencontainers.image.title=BuildKit + org.opencontainers.image.vendor=Moby + meta-bake-target: meta-helper + setup-qemu: true + bake-sbom: true + bake-set: | + *.no-cache-filter=${{ (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v')) && 'buildkit-export-alpine,buildkit-export-ubuntu,gobuild-base,rootless' || '' }} + secrets: + registry-auths: | + - registry: docker.io username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build - uses: docker/bake-action@v6 - with: - # FIXME: remove context once git context with query string implemented in actions-toolkit - source: ${{ github.server_url }}/${{ github.repository }}.git#${{ github.ref }} - files: | - ./docker-bake.hcl - cwd://${{ steps.meta.outputs.bake-file-tags }} - cwd://${{ steps.meta.outputs.bake-file-annotations }} - targets: image-cross - push: ${{ github.repository == 'moby/buildkit' && (github.event_name == 'schedule' || github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v')) }} - provenance: mode=max,version=v1 - sbom: true - set: | - *.cache-from=type=gha,scope=image${{ matrix.target }}-${{ matrix.base }} - *.cache-to=type=gha,scope=image${{ matrix.target }}-${{ matrix.base }} - *.no-cache-filter=${{ (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v')) && 'buildkit-export-alpine,buildkit-export-ubuntu,gobuild-base,rootless' || '' }} - env: - IMAGE_TARGET: ${{ matrix.target }} - EXPORT_BASE: ${{ matrix.base }} - BUILDKITD_TAGS: ${{ matrix.build-tags }} scout: runs-on: ubuntu-24.04 @@ -338,20 +346,15 @@ jobs: contents: write needs: - test - - binaries + - binaries-finalize - image steps: - - name: Download artifacts + name: Download release binaries uses: actions/download-artifact@v6 with: path: ${{ env.DESTDIR }} - pattern: buildkit-* - merge-multiple: true - - - name: List artifacts - run: | - tree -nh ${{ env.DESTDIR }} + name: release - name: GitHub Release if: startsWith(github.ref, 'refs/tags/v') diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml index f3311e053dec..a9895c6ee677 100644 --- a/.github/workflows/frontend.yml +++ b/.github/workflows/frontend.yml @@ -44,7 +44,7 @@ jobs: prepare: runs-on: ubuntu-24.04 outputs: - channels: ${{ steps.set.outputs.matrix }} + includes: ${{ steps.set.outputs.includes }} tag: ${{ steps.set.outputs.tag }} steps: - @@ -56,140 +56,143 @@ jobs: INPUT_CHANNELS: | mainline labs + INPUT_IMAGE-NAME: ${{ env.IMAGE_NAME }} with: script: | const ref = core.getInput('ref'); const channels = core.getMultilineInput('channels'); + const imageName = core.getInput('image-name'); + + function getTags(channel) { + let tagSuffix = ''; + if (channel !== 'mainline') { + tagSuffix = `-${channel}`; + } + let tagLatest = ''; + let tagVersion = ''; + if (ref.startsWith('refs/tags/dockerfile/')) { + const version = ref.replace('refs/tags/dockerfile/', '').replace(new RegExp(`-${channel}$`), ''); + if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(version)) { + tagLatest = channel === 'mainline' ? 'latest' : channel; + } + tagVersion = version; + } + return { tagSuffix, tagLatest, tagVersion }; + } + const matrix = []; if (ref.startsWith('refs/tags/dockerfile/')) { const version = ref.replace('refs/tags/dockerfile/', ''); for (const channel of channels) { if (version.endsWith(`-${channel}`)) { - matrix.push(channel); + const { tagSuffix, tagLatest, tagVersion } = getTags(channel); + matrix.push({ + channel: channel, + imageName: imageName, + tagSuffix: tagSuffix, + tagLatest: tagLatest, + tagVersion: tagVersion + }); break; } } if (matrix.length === 0) { // default to mainline if no channel suffix - matrix.push('mainline'); + const { tagSuffix, tagLatest, tagVersion } = getTags('mainline'); + matrix.push({ + channel: 'mainline', + imageName: imageName, + tagSuffix: tagSuffix, + tagLatest: tagLatest, + tagVersion: tagVersion + }); } core.setOutput('tag', ref.replace('refs/tags/', '')); } else { - matrix.push('mainline', 'labs'); + for (const channel of channels) { + const { tagSuffix, tagLatest, tagVersion } = getTags(channel); + matrix.push({ + channel: channel, + imageName: imageName, + tagSuffix: tagSuffix, + tagLatest: tagLatest, + tagVersion: tagVersion + }); + } } + core.info(JSON.stringify(matrix, null, 2)); - core.setOutput('matrix', JSON.stringify(matrix)); + core.setOutput('includes', JSON.stringify(matrix)); image: - runs-on: ubuntu-24.04 + uses: docker/github-builder-experimental/.github/workflows/bake.yml@c56377b5e16c21afb2f3ea02f9021a1ed4b51f45 needs: - - test - prepare + - test strategy: fail-fast: false matrix: - channel: ${{ fromJson(needs.prepare.outputs.channels) }} - steps: - - - name: Prepare - uses: actions/github-script@v8 - env: - INPUT_CHANNEL: ${{ matrix.channel }} - INPUT_REF: ${{ github.ref }} - with: - script: | - const channel = core.getInput('channel'); - const ref = core.getInput('ref'); - if (channel !== 'mainline') { - core.exportVariable('TAG_SUFFIX', `-${channel}`); - } - if (ref.startsWith('refs/tags/dockerfile/')) { - const version = ref.replace('refs/tags/dockerfile/', '').replace(new RegExp(`-${channel}$`), ''); - if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(version)) { - // stable release - core.exportVariable('TAG_LATEST', channel === 'mainline' ? 'latest' : channel); - } - core.exportVariable('TAG_VERSION', version); - } - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - with: - version: ${{ env.SETUP_BUILDX_VERSION }} - driver-opts: image=${{ env.SETUP_BUILDKIT_TAG }} - buildkitd-flags: --debug - - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 - with: - images: | - ${{ env.IMAGE_NAME }} - # versioning strategy - ## push tag dockerfile/1.17.0 - ### docker/dockerfile-upstream:1.17.0 - ### docker/dockerfile-upstream:1.17 - ### docker/dockerfile-upstream:1 - ### docker/dockerfile-upstream:latest - ## push tag dockerfile/1.17.0-labs - ### docker/dockerfile-upstream:1.17.0-labs - ### docker/dockerfile-upstream:1.17-labs - ### docker/dockerfile-upstream:1-labs - ### docker/dockerfile-upstream:labs - ## push prerelease tag dockerfile/1.17.0-rc1 - ### docker/dockerfile-upstream:1.17.0-rc1 - ## push prerelease tag dockerfile/1.17.0-rc1-labs - ### docker/dockerfile-upstream:1.17.0-rc1-labs - ## push on master - ### docker/dockerfile-upstream:master - ### docker/dockerfile-upstream:master-labs - tags: | - type=ref,event=branch,suffix=${{ env.TAG_SUFFIX }} - type=ref,event=pr,suffix=${{ env.TAG_SUFFIX }} - type=semver,pattern={{version}},value=${{ env.TAG_VERSION }},suffix=${{ env.TAG_SUFFIX }} - type=semver,pattern={{major}}.{{minor}},value=${{ env.TAG_VERSION }},suffix=${{ env.TAG_SUFFIX }} - type=semver,pattern={{major}},value=${{ env.TAG_VERSION }},suffix=${{ env.TAG_SUFFIX }} - type=raw,value=${{ env.TAG_LATEST }} - flavor: | - latest=false - annotations: | - org.opencontainers.image.title=Dockerfile Frontend - org.opencontainers.image.vendor=Moby - bake-target: frontend-meta-helper - - - name: Login to DockerHub - uses: docker/login-action@v3 - if: ${{ github.repository == 'moby/buildkit' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/dockerfile/')) }} - with: + include: ${{ fromJson(needs.prepare.outputs.includes) }} + permissions: + contents: read + id-token: write # for signing attestation manifests and registry authentication if needed with GitHub OIDC Token + packages: write # for pushing manifests to GHCR if needed (caller must provide the same permissions used in the reusable workflow) + with: + runner: amd64 + target: frontend-image-cross + output: image + push: ${{ github.repository == 'moby/buildkit' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/dockerfile/')) }} + envs: | + FRONTEND_CHANNEL=${{ matrix.channel }} + cache: true + cache-scope: frontend-${{ matrix.channel }} + set-meta-annotations: true + meta-images: | + ${{ matrix.imageName }} + # versioning strategy + ## push tag dockerfile/1.17.0 + ### docker/dockerfile-upstream:1.17.0 + ### docker/dockerfile-upstream:1.17 + ### docker/dockerfile-upstream:1 + ### docker/dockerfile-upstream:latest + ## push tag dockerfile/1.17.0-labs + ### docker/dockerfile-upstream:1.17.0-labs + ### docker/dockerfile-upstream:1.17-labs + ### docker/dockerfile-upstream:1-labs + ### docker/dockerfile-upstream:labs + ## push prerelease tag dockerfile/1.17.0-rc1 + ### docker/dockerfile-upstream:1.17.0-rc1 + ## push prerelease tag dockerfile/1.17.0-rc1-labs + ### docker/dockerfile-upstream:1.17.0-rc1-labs + ## push on master + ### docker/dockerfile-upstream:master + ### docker/dockerfile-upstream:master-labs + meta-tags: | + type=ref,event=branch,suffix=${{ matrix.tagSuffix }} + type=ref,event=pr,suffix=${{ matrix.tagSuffix }} + type=semver,pattern={{version}},value=${{ matrix.tagVersion }},suffix=${{ matrix.tagSuffix }} + type=semver,pattern={{major}}.{{minor}},value=${{ matrix.tagVersion }},suffix=${{ matrix.tagSuffix }} + type=semver,pattern={{major}},value=${{ matrix.tagVersion }},suffix=${{ matrix.tagSuffix }} + type=raw,value=${{ matrix.tagLatest }} + meta-flavor: | + latest=false + meta-annotations: | + org.opencontainers.image.title=Dockerfile Frontend + org.opencontainers.image.vendor=Moby + meta-bake-target: frontend-meta-helper + setup-qemu: true + bake-sbom: true + bake-set: | + *.no-cache-filter=${{ (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/dockerfile/')) && 'base' || '' }} + secrets: + registry-auths: | + - registry: docker.io username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build - uses: docker/bake-action@v6 - with: - # FIXME: remove context once git context with query string implemented in actions-toolkit - source: ${{ github.server_url }}/${{ github.repository }}.git#${{ github.ref }} - files: | - ./docker-bake.hcl - cwd://${{ steps.meta.outputs.bake-file-tags }} - cwd://${{ steps.meta.outputs.bake-file-annotations }} - targets: frontend-image-cross - push: ${{ github.repository == 'moby/buildkit' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/dockerfile/')) }} - provenance: mode=max,version=v1 - sbom: true - set: | - *.cache-from=type=gha,scope=frontend-${{ matrix.channel }} - *.cache-to=type=gha,scope=frontend-${{ matrix.channel }} - *.no-cache-filter=${{ (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/dockerfile/')) && 'base' || '' }} - env: - FRONTEND_CHANNEL: ${{ matrix.channel }} scout: runs-on: ubuntu-24.04 - if: ${{ github.ref == 'refs/heads/master' && github.repository == 'moby/buildkit' }} + if: ${{ github.repository == 'moby/buildkit' && github.ref == 'refs/heads/master' }} permissions: # same as global permission contents: read diff --git a/.yamllint.yml b/.yamllint.yml index e190c1613ec2..95e7060762a0 100644 --- a/.yamllint.yml +++ b/.yamllint.yml @@ -11,3 +11,8 @@ rules: truthy: disable line-length: disable document-start: disable + trailing-spaces: disable + comments: + require-starting-space: true + ignore-shebangs: true + min-spaces-from-content: 1