diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 35905796..bd0645c4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,15 +18,14 @@ env: RELEASE_OUT: "./release-out" jobs: - build: + test: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v1 + with: + fetch-depth: 0 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 @@ -39,6 +38,22 @@ jobs: uses: codecov/codecov-action@v2 with: file: ./coverage/coverage.txt + + build: + runs-on: ubuntu-latest + needs: test + steps: + - + name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - + name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 - name: Build binaries run: | @@ -88,6 +103,29 @@ jobs: draft: true files: ${{ env.RELEASE_OUT }}/* + pkg: + runs-on: ubuntu-latest + needs: test + steps: + - + name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - + name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + with: + driver-opts: image=${{ env.REPO_SLUG_ORIGIN }} + - + name: Build packages + run: | + make pkg-cross + tree ./bin + buildkit-edge: runs-on: ubuntu-latest continue-on-error: true diff --git a/Dockerfile b/Dockerfile index 804050b0..1baad63c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,13 @@ -# syntax=docker/dockerfile:1.3 +# syntax=docker/dockerfile:1.3-labs ARG GO_VERSION=1.17 +ARG NFPM_VERSION=v2.13.0 ARG DOCKERD_VERSION=20.10.8 FROM docker:$DOCKERD_VERSION AS dockerd-release # xx is a helper for cross-compilation -FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.0.0 AS xx +FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.1.0 AS xx FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS golatest @@ -16,24 +17,24 @@ RUN apk add --no-cache file git ENV GOFLAGS=-mod=vendor WORKDIR /src -FROM gobase AS buildx-version +FROM gobase AS version RUN --mount=target=. \ PKG=github.com/docker/buildx VERSION=$(git describe --match 'v[0-9]*' --dirty='.m' --always --tags) REVISION=$(git rev-parse HEAD)$(if ! git diff --no-ext-diff --quiet --exit-code; then echo .m; fi); \ echo "-X ${PKG}/version.Version=${VERSION} -X ${PKG}/version.Revision=${REVISION} -X ${PKG}/version.Package=${PKG}" | tee /tmp/.ldflags; \ echo -n "${VERSION}" | tee /tmp/.version; -FROM gobase AS buildx-build +FROM gobase AS build ENV CGO_ENABLED=0 ARG LDFLAGS="-w -s" ARG TARGETPLATFORM RUN --mount=type=bind,target=. \ --mount=type=cache,target=/root/.cache \ --mount=type=cache,target=/go/pkg/mod \ - --mount=type=bind,source=/tmp/.ldflags,target=/tmp/.ldflags,from=buildx-version \ + --mount=type=bind,source=/tmp/.ldflags,target=/tmp/.ldflags,from=version \ set -x; xx-go build -ldflags "$(cat /tmp/.ldflags) ${LDFLAGS}" -o /usr/bin/buildx ./cmd/buildx && \ xx-verify --static /usr/bin/buildx -FROM buildx-build AS test +FROM build AS test RUN --mount=type=bind,target=. \ --mount=type=cache,target=/root/.cache \ --mount=type=cache,target=/go/pkg/mod \ @@ -44,13 +45,13 @@ FROM scratch AS test-coverage COPY --from=test /tmp/coverage.txt /coverage.txt FROM scratch AS binaries-unix -COPY --from=buildx-build /usr/bin/buildx / +COPY --from=build /usr/bin/buildx / FROM binaries-unix AS binaries-darwin FROM binaries-unix AS binaries-linux FROM scratch AS binaries-windows -COPY --from=buildx-build /usr/bin/buildx /buildx.exe +COPY --from=build /usr/bin/buildx /buildx.exe FROM binaries-$TARGETOS AS binaries @@ -59,12 +60,34 @@ FROM --platform=$BUILDPLATFORM alpine AS releaser WORKDIR /work ARG TARGETPLATFORM RUN --mount=from=binaries \ - --mount=type=bind,source=/tmp/.version,target=/tmp/.version,from=buildx-version \ + --mount=type=bind,source=/tmp/.version,target=/tmp/.version,from=version \ mkdir -p /out && cp buildx* "/out/buildx-$(cat /tmp/.version).$(echo $TARGETPLATFORM | sed 's/\//-/g')$(ls buildx* | sed -e 's/^buildx//')" FROM scratch AS release COPY --from=releaser /out/ / +# Pkg +FROM --platform=$BUILDPLATFORM goreleaser/nfpm:${NFPM_VERSION} AS nfpm +FROM --platform=$BUILDPLATFORM alpine AS build-pkg +RUN apk add --no-cache bash file git zip tar +WORKDIR /work +COPY --from=xx / / +COPY --from=build /usr/bin/buildx /usr/bin/buildx +ARG TARGETPLATFORM +ARG PKG_TYPES +ARG PKG_APK_RELEASES +ARG PKG_DEB_RELEASES +ARG PKG_RPM_RELEASES +ARG PKG_VENDOR +ARG PKG_PACKAGER +RUN --mount=source=.,target=/src \ + --mount=from=nfpm,source=/usr/bin/nfpm,target=/usr/bin/nfpm \ + --mount=source=/tmp/.version,target=/tmp/.version,from=version \ + VERSION=$(cat /tmp/.version) NFPM_CONFIG=/src/hack/nfpm.yml OUTPUT=/build /src/hack/create-pkg + +FROM scratch AS pkg +COPY --from=build-pkg /build / + # Shell FROM docker:$DOCKERD_VERSION AS dockerd-release FROM alpine AS shell diff --git a/Makefile b/Makefile index da70e877..4a39b4ff 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,12 @@ binaries: binaries-cross: $(BUILDX_CMD) bake binaries-cross +pkg: + $(BUILDX_CMD) bake pkg + +pkg-cross: + $(BUILDX_CMD) bake pkg-cross + install: binaries mkdir -p ~/.docker/cli-plugins install bin/buildx ~/.docker/cli-plugins/docker-buildx @@ -59,4 +65,4 @@ authors: mod-outdated: $(BUILDX_CMD) bake mod-outdated -.PHONY: shell binaries binaries-cross install release validate-all lint validate-vendor validate-docs validate-authors vendor docs authors +.PHONY: shell binaries binaries-cross pkg pkg-cross install release validate-all lint validate-vendor validate-docs validate-authors vendor docs authors diff --git a/docker-bake.hcl b/docker-bake.hcl index 036683f1..ee602ac6 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -147,3 +147,66 @@ target "image-local" { inherits = ["image"] output = ["type=docker"] } + +# Sets the list of package types to build: apk, deb, rpm and/or static +variable "PKG_TYPES" { + default = "apk,deb,rpm,static" +} +# Sets the list of apk releases (e.g., r0) +# docker-buildx-plugin_0.8.1-r0_aarch64.apk +variable "PKG_APK_RELEASES" { + default = "r0" +} +# Sets the list of deb releases (e.g., debian11) +# docker-buildx-plugin_0.8.1-debian11_arm64.deb +variable "PKG_DEB_RELEASES" { + default = "debian10,debian11,ubuntu1804,ubuntu2004,ubuntu2110,ubuntu2204,raspbian10,raspbian11" +} +# Sets the list of rpm releases (e.g., centos7) +# docker-buildx-plugin-0.8.1-fedora35.aarch64.rpm +variable "PKG_RPM_RELEASES" { + default = "centos7,centos8,fedora33,fedora34,fedora35,fedora36" +} +# Sets the vendor/maintainer name (only for linux packages) +variable "PKG_VENDOR" { + default = "Docker" +} +# Sets the name of the company that produced the package (only for linux packages) +variable "PKG_PACKAGER" { + default = "Docker " +} + +# Useful commands for this target +# PKG_TYPES=deb PKG_DEB_RELEASES=debian11 docker buildx bake pkg +# docker buildx bake --set *.platform=windows/amd64 --set *.output=./bin pkg +target "pkg" { + inherits = ["binaries"] + args = { + PKG_TYPES = PKG_TYPES + PKG_APK_RELEASES = PKG_APK_RELEASES + PKG_DEB_RELEASES = PKG_DEB_RELEASES + PKG_RPM_RELEASES = PKG_RPM_RELEASES + PKG_VENDOR = PKG_VENDOR + PKG_PACKAGER = PKG_PACKAGER + } + target = "pkg" +} + +# Useful commands for this target +# docker buildx bake pkg-cross --set *.output=type=image,push=true --set *.tags=crazymax/buildx-pkg:latest +target "pkg-cross" { + inherits = ["pkg"] + platforms = [ + "darwin/amd64", + "darwin/arm64", + "linux/amd64", + "linux/arm/v6", + "linux/arm/v7", + "linux/arm64", + "linux/ppc64le", + "linux/riscv64", + "linux/s390x", + "windows/amd64", + "windows/arm64" + ] +} diff --git a/hack/create-pkg b/hack/create-pkg new file mode 100755 index 00000000..150e67a9 --- /dev/null +++ b/hack/create-pkg @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +set -eu -o pipefail + +: "${VERSION=}" +: "${NFPM_CONFIG=}" +: "${OUTPUT=.}" + +: "${PKG_TYPES=}" +: "${PKG_APK_RELEASES=}" +: "${PKG_DEB_RELEASES=}" +: "${PKG_RPM_RELEASES=}" +: "${PKG_VENDOR=}" +: "${PKG_PACKAGER=}" + +if ! type nfpm > /dev/null 2>&1; then + echo >&2 "ERROR: nfpm is required" + exit 1 +fi +if ! type xx-info > /dev/null 2>&1; then + echo >&2 "ERROR: xx-info is required" + exit 1 +fi + +if [[ $VERSION =~ ^[a-f0-9]{7}$ ]]; then + VERSION="v0.0.0+${VERSION}" +fi + +workdir=$(mktemp -d -t buildx-pkg.XXXXXXXXXX) +trap 'rm -rf -- "$workdir"' EXIT +mkdir -p "$workdir/docker-buildx-plugin" + +PKG_OUTPUT="${OUTPUT}/$(xx-info os)/$(xx-info arch)/$(xx-info variant)" +mkdir -p "${PKG_OUTPUT}" + +for pkgtype in ${PKG_TYPES//,/ }; do + os=$(xx-info os) + arch=$(xx-info march) + releases=0 + if [ $pkgtype = "static" ]; then + cp /src/LICENSE /src/README.md "$workdir/docker-buildx-plugin/" + if [ "$os" = "windows" ]; then + cp /usr/bin/buildx "$workdir/docker-buildx-plugin/docker-buildx.exe" + (set -x ; cd "$workdir" && zip -r "$PKG_OUTPUT/docker-buildx-plugin_${VERSION#v}.zip" docker-buildx-plugin) + else + cp /usr/bin/buildx "$workdir/docker-buildx-plugin/docker-buildx" + (set -x ; tar -czf "$PKG_OUTPUT/docker-buildx-plugin_${VERSION#v}.tgz" -C "$workdir" docker-buildx-plugin) + fi + continue + fi + if [ "$os" != "linux" ]; then + continue + fi + case $pkgtype in + apk) + arch=$(xx-info alpine-arch) + releases=$PKG_APK_RELEASES + ;; + deb) + arch=$(xx-info debian-arch) + releases=$PKG_DEB_RELEASES + ;; + rpm) + arch=$(xx-info rhel-arch) + releases=$PKG_RPM_RELEASES + ;; + esac + for release in ${releases//,/ }; do + (set -x ; ARCH="${arch}" VERSION="${VERSION}" RELEASE="$release" VENDOR="${PKG_VENDOR}" PACKAGER="${PKG_PACKAGER}" nfpm package --config $NFPM_CONFIG --packager $pkgtype --target "$PKG_OUTPUT") + done +done diff --git a/hack/nfpm.yml b/hack/nfpm.yml new file mode 100644 index 00000000..90f723ad --- /dev/null +++ b/hack/nfpm.yml @@ -0,0 +1,37 @@ +name: docker-buildx-plugin + +# The architecture is specified using Go nomenclature (GOARCH) and translated +# to the platform specific equivalent. In order to manually set the architecture +# to a platform specific value, use deb_arch, rpm_arch and apk_arch. +arch: ${ARCH} +platform: linux + +version: ${VERSION} +epoch: 0 +release: ${RELEASE} + +section: default + +maintainer: Docker +description: Docker Buildx plugin extends build capabilities with BuildKit. +vendor: ${VENDOR} +homepage: https://github.com/docker/buildx +license: Apache-2.0 +disable_globbing: true + +contents: + - src: /usr/bin/buildx + dst: /usr/libexec/docker/cli-plugins/docker-buildx + +overrides: + deb: + replaces: + - docker-ce-cli # fixes implicit conflict with docker-ce-cli package < 22.04.0. can be removed later. + +rpm: + group: Tools/Docker + packager: ${PACKAGER} + compression: xz + +deb: + compression: xz