From 312aeebf97db2a4da01572989f901ab6f3602d4e Mon Sep 17 00:00:00 2001 From: "grafanarenovatebot[bot]" <146220760+grafanarenovatebot[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 01:01:04 +0000 Subject: [PATCH] Rework build to avoid emulation I'm sick of issues related to emulation, the most recent one being that stuff times out for some reason (and it's not necessarily that the build is slow). It would be much easier to build natively, but since that doesn't seem to be an option yet, change things so that binaries are cross-compiled. Signed-off-by: Marcelo E. Magallon --- .github/workflows/pr.yml | 24 ++++- .github/workflows/publish.yml | 116 ++++++++++++++++---- .gitignore | 1 + Dockerfile.build.tmpl | 195 ++++++++++++++++++++++++++++++++++ Dockerfile.tmpl | 128 +++------------------- Makefile | 50 +++++---- dist/.gitignore | 1 + scripts/build-os-arch | 86 +++++++++++++++ scripts/local-machine | 25 +++-- versions.yaml | 2 +- 10 files changed, 464 insertions(+), 164 deletions(-) create mode 100644 Dockerfile.build.tmpl create mode 100644 dist/.gitignore create mode 100755 scripts/build-os-arch diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index bc61baa..4db90fb 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -6,6 +6,7 @@ on: - main paths: - Dockerfile.tmpl + - Dockerfile.build.tmpl - .github/workflows/** - lib/** - Makefile @@ -60,10 +61,27 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Generate Dockerfile - run: make Dockerfile + run: make Dockerfile Dockerfile.build - - # This will only build the container image, not publish it - name: Build container image and export to Docker + - name: Build auxiliary image and export to docker + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile.build + push: false + load: true + tags: binaries:local + build-args: | + TARGET_GOOS=linux + TARGET_GOARCH=amd64 + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max + + - name: Capture binaries + run: | + ./scripts/build-os-arch --image binaries:local --no-build linux amd64 + + - name: Build container image and export to Docker uses: docker/build-push-action@v5 with: context: . diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 84a6399..c327e66 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,9 +12,83 @@ on: workflow_dispatch: jobs: + build: + name: Build binaries + runs-on: ubuntu-latest-8-cores + steps: + - uses: actions/checkout@v4 + with: + fetch-tags: true + + - name: Unshallow + run: git fetch --prune --tags --unshallow + + - name: Describe the current state + run: git describe --tags --always + + - name: Docker meta + id: docker_meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }} + tags: | + type=raw,value=sha-${{ github.sha }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Package Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Generate Dockerfile + run: make Dockerfile Dockerfile.build + + - name: Build auxiliary image and export to docker (linux/amd64) + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile.build + push: false + load: true + tags: binaries:local-linux-amd64 + build-args: | + TARGET_GOOS=linux + TARGET_GOARCH=amd64 + + - name: Build auxiliary image and export to docker (linux/arm64) + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile.build + push: false + load: true + tags: binaries:local-linux-arm64 + build-args: | + TARGET_GOOS=linux + TARGET_GOARCH=arm64 + + - name: Capture binaries + run: | + ./scripts/build-os-arch --image binaries:local-linux-amd64 --no-build linux amd64 + ./scripts/build-os-arch --image binaries:local-linux-arm64 --no-build linux arm64 + tar -czf dist/binaries.tar.gz dist/linux-amd64 dist/linux-arm64 + + - name: Archive binaries + uses: actions/upload-artifact@v4 + with: + name: binaries + path: dist/binaries.tar.gz + retention-days: 1 + publish: name: Publish container images runs-on: ubuntu-latest-8-cores + needs: build steps: - uses: actions/checkout@v4 @@ -49,14 +123,6 @@ jobs: with: config: .github/workflows/buildkitd.toml - - name: Cache Docker layers - uses: actions/cache@v4 - with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx- - - name: Login to GitHub Package Registry uses: docker/login-action@v3 with: @@ -64,6 +130,28 @@ jobs: username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Retrieve binaries + uses: actions/download-artifact@v4 + with: + name: binaries + + - name: Load binaries + run: tar -xzf binaries/binaries.tar.gz + + - name: Build image (linux/amd64) + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + push: false + load: true + platforms: linux/amd64 + tags: test:local + + - name: Test image + run: | + docker run --rm test:local image-test + - name: Build and push image uses: docker/build-push-action@v5 with: @@ -73,15 +161,3 @@ jobs: push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.docker_meta.outputs.tags }} labels: ${{ steps.docker_meta.outputs.labels }} - cache-from: type=local,src=/tmp/.buildx-cache - cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max - - - - # Temp fix - # https://github.com/docker/build-push-action/issues/252 - # https://github.com/moby/buildkit/issues/1896 - name: Move cache - run: | - rm -rf /tmp/.buildx-cache - mv /tmp/.buildx-cache-new /tmp/.buildx-cache - shell: bash diff --git a/.gitignore b/.gitignore index 9414382..861e93b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ Dockerfile +Dockerfile.build diff --git a/Dockerfile.build.tmpl b/Dockerfile.build.tmpl new file mode 100644 index 0000000..9ba4f0e --- /dev/null +++ b/Dockerfile.build.tmpl @@ -0,0 +1,195 @@ +FROM docker.io/library/golang:1.22.6 AS go + COPY lib/go.env /usr/local/go/ + RUN mkdir -p /build/bin + +FROM go AS go_jsonnet + ARG TARGET_GOOS + ARG TARGET_GOARCH + + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install github.com/google/go-jsonnet/cmd/jsonnet@v0.20.0 + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install github.com/google/go-jsonnet/cmd/jsonnetfmt@v0.20.0 + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install github.com/google/go-jsonnet/cmd/jsonnet-deps@v0.20.0 + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install github.com/google/go-jsonnet/cmd/jsonnet-lint@v0.20.0 + +FROM go AS wire + ARG TARGET_GOOS + ARG TARGET_GOARCH + + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install github.com/google/wire/cmd/wire@v0.6.0 + +FROM go AS bingo + ARG TARGET_GOOS + ARG TARGET_GOARCH + + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install github.com/bwplotka/bingo@v0.9.0 + +FROM go AS lefthook + ARG TARGET_GOOS + ARG TARGET_GOARCH + + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install github.com/evilmartians/lefthook@v1.7.11 + +FROM go AS dockerfile_json + ARG TARGET_GOOS + ARG TARGET_GOARCH + + RUN git clone --depth 1 --branch 1.0.8 https://github.com/keilerkonzept/dockerfile-json dockerfile-json && \ + cd dockerfile-json && \ + env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install . + +FROM go AS enumer + ARG TARGET_GOOS + ARG TARGET_GOARCH + + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install github.com/dmarkham/enumer@v1.5.10 + +FROM go AS protoc_gen_go + ARG TARGET_GOOS + ARG TARGET_GOARCH + + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.34.2 + +FROM go AS protoc_gen_go_grpc + ARG TARGET_GOOS + ARG TARGET_GOARCH + + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.5.1 + +FROM go AS buf + ARG TARGET_GOOS + ARG TARGET_GOARCH + + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install github.com/bufbuild/buf/cmd/buf@v1.35.1 + +FROM go AS mage + ARG TARGET_GOOS + ARG TARGET_GOARCH + + RUN git clone --depth 1 --branch v1.15.0 https://github.com/magefile/mage mage && \ + cd mage && \ + mkdir -p /host/bin /build/bin/${TARGET_GOOS}-${TARGET_GOARCH} && \ + env GOPATH=/host go run bootstrap.go && \ + env /host/bin/mage -compile /build/bin/${TARGET_GOOS}-${TARGET_GOARCH}/mage -goos ${TARGET_GOOS} -goarch ${TARGET_GOARCH} + +FROM go AS nilaway + ARG TARGET_GOOS + ARG TARGET_GOARCH + + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install go.uber.org/nilaway/cmd/nilaway@v0.0.0-20240719152558-28b542b82e69 + +FROM go AS grizzly + ARG TARGET_GOOS + ARG TARGET_GOARCH + + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install github.com/grafana/grizzly/cmd/grr@v0.4.3 + +FROM go AS semversort + ARG TARGET_GOOS + ARG TARGET_GOARCH + + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install github.com/whereswaldon/semversort@v0.0.6 + +FROM go AS golangci_lint + ARG TARGET_GOOS + ARG TARGET_GOARCH + + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.59.1 + +FROM go AS git_chglog + ARG TARGET_GOOS + ARG TARGET_GOARCH + + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install github.com/git-chglog/git-chglog/cmd/git-chglog@v0.15.4 + +FROM go AS gotestsum + ARG TARGET_GOOS + ARG TARGET_GOARCH + + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install gotest.tools/gotestsum@v1.12.0 + +FROM go AS xk6 + ARG TARGET_GOOS + ARG TARGET_GOARCH + + # The grafana/xk6 image only exists for amd64, so we need to build it for + # the target architecture. + RUN mkdir -p /host/bin /build/bin/${TARGET_GOOS}-${TARGET_GOARCH} && \ + env GOPATH=/host go install go.k6.io/xk6/cmd/xk6@v0.12.2 && \ + env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} go install go.k6.io/xk6/cmd/xk6@v0.12.2 + +FROM xk6 AS k6 + ARG TARGET_GOOS + ARG TARGET_GOARCH + + # The grafana/k6 image only exists for amd64, so we need to build it for + # the architecture we are targeting. The simplest way to build k6 is to + # (ab)use xk6 to build a binary without any extensions. In the future, if + # we wanted additional extensions, this is the place to add them. + RUN env GOPATH=/build GOOS=${TARGET_GOOS} GOARCH=${TARGET_GOARCH} /host/bin/xk6 build v0.52.0 --output /build/bin/${TARGET_GOOS}-${TARGET_GOARCH}/k6 + +FROM docker.io/library/debian:stable-slim AS skopeo + ARG TARGET_GOOS + ARG TARGET_GOARCH + + COPY --from=go /usr/local/go /usr/local/go + + ENV PATH="/usr/local/go/bin:${PATH}" + + RUN apt-get update && \ + apt-get install -y \ + build-essential \ + libgpgme-dev \ + libassuan-dev \ + libdevmapper-dev \ + pkg-config \ + git + + # skopeo is used to inspect container registries. This can be used to + # inspect the available versions without pulling the repos. + RUN git clone https://github.com/containers/skopeo && \ + cd skopeo && \ + git checkout "v1.16.0" && \ + make GOPATH=/build DISABLE_DOCS=1 bin/skopeo.${TARGET_GOOS}.${TARGET_GOARCH} && \ + mkdir -p /build/bin && \ + cp bin/skopeo.${TARGET_GOOS}.${TARGET_GOARCH} /build/bin/skopeo + +FROM docker.io/library/debian:stable-slim AS final + RUN mkdir -p /dist + + COPY --from=bingo /build/bin/* /dist/ + + COPY --from=buf /build/bin/* /dist/ + + COPY --from=dockerfile_json /build/bin/* /dist/ + + COPY --from=enumer /build/bin/* /dist/ + + COPY --from=git_chglog /build/bin/* /dist/ + + COPY --from=go_jsonnet /build/bin/* /dist/ + + COPY --from=golangci_lint /build/bin/* /dist/ + + COPY --from=gotestsum /build/bin/* /dist/ + + COPY --from=grizzly /build/bin/* /dist/ + + COPY --from=k6 /build/bin/* /dist/ + + COPY --from=lefthook /build/bin/* /dist/ + + COPY --from=mage /build/bin/* /dist/ + + COPY --from=nilaway /build/bin/* /dist/ + + COPY --from=protoc_gen_go /build/bin/* /dist/ + + COPY --from=protoc_gen_go_grpc /build/bin/* /dist/ + + COPY --from=semversort /build/bin/* /dist/ + + COPY --from=skopeo /build/bin/* /dist/ + + COPY --from=wire /build/bin/* /dist/ + + COPY --from=xk6 /build/bin/* /dist/ diff --git a/Dockerfile.tmpl b/Dockerfile.tmpl index 1ba64f3..1983c5b 100644 --- a/Dockerfile.tmpl +++ b/Dockerfile.tmpl @@ -2,122 +2,13 @@ FROM docker.io/library/golang:{{ .data.go }} as go COPY lib/go.env /usr/local/go/ RUN mkdir -p /build/bin -FROM go as go_jsonnet - RUN env GOBIN=/build/bin go install github.com/google/go-jsonnet/cmd/jsonnet@{{ .data.go_jsonnet }} - RUN env GOBIN=/build/bin go install github.com/google/go-jsonnet/cmd/jsonnetfmt@{{ .data.go_jsonnet }} - RUN env GOBIN=/build/bin go install github.com/google/go-jsonnet/cmd/jsonnet-deps@{{ .data.go_jsonnet }} - RUN env GOBIN=/build/bin go install github.com/google/go-jsonnet/cmd/jsonnet-lint@{{ .data.go_jsonnet }} +FROM scratch AS shellcheck + COPY --from=docker.io/koalaman/shellcheck:v0.10.0 /bin/shellcheck /build/bin/ -FROM go as wire - # Add wire - RUN env GOBIN=/build/bin go install github.com/google/wire/cmd/wire@{{ .data.wire }} - -FROM go as bingo - # Add bingo - RUN env GOBIN=/build/bin go install github.com/bwplotka/bingo@{{ .data.bingo }} - -FROM go as lefthook - # Add lefthook - RUN env GOBIN=/build/bin go install github.com/evilmartians/lefthook@{{ .data.lefthook }} - -FROM go as dockerfile_json - # Add dockerfile-json - RUN git clone --depth 1 --branch {{ .data.dockerfile_json }} https://github.com/keilerkonzept/dockerfile-json dockerfile-json && \ - cd dockerfile-json && \ - env GOBIN=/build/bin go install . - -FROM go as enumer - # Add enumer - RUN env GOBIN=/build/bin go install github.com/dmarkham/enumer@{{ .data.enumer }} - -FROM go as protoc_gen_go - # Add protoc-gen-go - RUN env GOBIN=/build/bin go install google.golang.org/protobuf/cmd/protoc-gen-go@{{ .data.protoc_gen_go }} - -FROM go as protoc_gen_go_grpc - # Add protoc-gen-go-grpc - RUN env GOBIN=/build/bin go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@{{ .data.protoc_gen_go_grpc }} - -FROM go as buf - # Add buf - RUN env GOBIN=/build/bin go install github.com/bufbuild/buf/cmd/buf@{{ .data.buf }} - -FROM go as mage - # Add mage - RUN git clone --depth 1 --branch {{ .data.mage }} https://github.com/magefile/mage mage && \ - cd mage && \ - mkdir -p /build/bin && \ - env GOBIN=/build/bin go run bootstrap.go - -FROM go as nilaway - # Add nilaway - RUN env GOBIN=/build/bin go install go.uber.org/nilaway/cmd/nilaway@{{ .data.nilaway }} - -FROM go as grizzly - # Add grizzly - RUN env GOBIN=/build/bin go install github.com/grafana/grizzly/cmd/grr@{{ .data.grizzly }} - -FROM go as semversort - # Add semversort - RUN env GOBIN=/build/bin go install github.com/whereswaldon/semversort@{{ .data.semversort }} - -FROM go as golangci_lint - # Add golangci-lint - RUN env GOBIN=/build/bin go install github.com/golangci/golangci-lint/cmd/golangci-lint@{{ .data.golangci_lint }} - -FROM go as shellcheck - # Add shellcheck - COPY --from=docker.io/koalaman/shellcheck:{{ .data.shellcheck }} /bin/shellcheck /build/bin/ - -FROM go as git_chglog - # Add git-chglog - RUN env GOBIN=/build/bin go install github.com/git-chglog/git-chglog/cmd/git-chglog@{{ .data.git_chglog }} - -FROM go as gotestsum - # Add gotestsum - RUN env GOBIN=/build/bin go install gotest.tools/gotestsum@{{ .data.gotestsum }} - -FROM go as jq - # Add jq - COPY --from=ghcr.io/jqlang/jq:{{ .data.jq }} /jq /build/bin/ - -FROM go AS xk6 - # The grafana/xk6 image only exists for amd64, so we need to build it for - # the target architecture. - RUN env GOBIN=/build/bin go install go.k6.io/xk6/cmd/xk6@{{ .data.xk6 }} - -FROM xk6 AS k6 - # The grafana/k6 image only exists for amd64, so we need to build it for - # the architecture we are targeting. The simplest way to build k6 is to - # (ab)use xk6 to build a binary without any extensions. In the future, if - # we wanted additional extensions, this is the place to add them. - RUN /build/bin/xk6 build {{ .data.k6 }} --output /build/bin/k6 - -FROM docker.io/library/debian:stable-slim as skopeo - COPY --from=go /usr/local/go /usr/local/go - - ENV PATH="/usr/local/go/bin:${PATH}" - - RUN apt-get update && \ - apt-get install -y \ - build-essential \ - libgpgme-dev \ - libassuan-dev \ - libdevmapper-dev \ - pkg-config \ - git - - # skopeo is used to inspect container registries. This can be used to - # inspect the available versions without pulling the repos. - RUN git clone https://github.com/containers/skopeo && \ - cd skopeo && \ - git checkout "{{ .data.skopeo }}" && \ - make GOBIN=/build/bin DISABLE_DOCS=1 bin/skopeo && \ - mkdir -p /build/bin && \ - cp bin/skopeo /build/bin/ +FROM scratch AS jq + COPY --from=ghcr.io/jqlang/jq:1.7.1 /jq /build/bin/ FROM docker.io/library/debian:stable-slim AS final - RUN apt-get update && \ apt-get install -y \ build-essential \ @@ -136,8 +27,17 @@ FROM docker.io/library/debian:stable-slim AS final COPY --from=go /usr/local/go /usr/local/go + ARG TARGETOS + ARG TARGETARCH + + ADD dist/${TARGETOS}-${TARGETARCH}/* /usr/local/bin/ + + COPY --from=shellcheck /build/bin/* /usr/local/bin/ + + COPY --from=jq /build/bin/* /usr/local/bin/ + ENV PATH="/usr/local/go/bin:${PATH}" {{ range $pkg, $info := .data }} - COPY --from={{ $pkg }} /build/bin/* /usr/local/bin/ + ### COPY --from={{ $pkg }} /build/bin/* /usr/local/bin/ {{ end }} diff --git a/Makefile b/Makefile index 1219c5b..104d04e 100644 --- a/Makefile +++ b/Makefile @@ -20,28 +20,28 @@ export DOCKER_BUILDKIT # locally. Be aware if you drop an arch then the "latest" tag won't include it, # so you will break users who are running that arch. Probably just don't push if # you're running locally. -PUSH_ARCHES ?= $(LOCAL_ARCH) +TARGET_ARCHES ?= $(LOCAL_ARCH) ##@ Development BUILD_TARGETS := define build-target -.PHONY: build-$(1) -build-$(1): Dockerfile -build-$(1): - @set -e - docker build . -f Dockerfile -t "$(IMAGE)-$(1)" +.PHONY: build-$(1)-$(2) +build-$(1)-$(2): Dockerfile +build-$(1)-$(2): + scripts/build-os-arch --image build:$(1)-$(2) $(1) $(2) -BUILD_TARGETS += build-$(1) +BUILD_TARGETS += build-$(1)-$(2) endef -$(foreach BUILD_ARCH,$(PUSH_ARCHES),$(eval $(call build-target,$(BUILD_ARCH)))) +split = $(word $(2),$(subst $(1), ,$(3))) + +$(foreach BUILD_ARCH,$(TARGET_ARCHES),$(eval $(call build-target,$(call split,-,1,$(BUILD_ARCH)),$(call split,-,2,$(BUILD_ARCH))))) .PHONY: build-local -build-local: Dockerfile -build-local: - docker build . -f Dockerfile -t "$(LOCAL_IMAGE)" +build-local: build-$(LOCAL_ARCH) + @true BUILD_TARGETS += build-local @@ -50,12 +50,22 @@ build: $(BUILD_TARGETS) build: ## build the image @true +.PHONY: image-$(LOCAL_ARCH) +image-$(LOCAL_ARCH) : build-$(LOCAL_ARCH) +image-$(LOCAL_ARCH) : + $(S) docker build -t $(LOCAL_IMAGE) -f Dockerfile --platform $(call split,-,1,$(LOCAL_ARCH))/$(call split,-,2,$(LOCAL_ARCH)) . + +.PHONY: image-local +image-local: image-$(LOCAL_ARCH) +image-local: ## build the image for the local arch + @true + .PHONY: test -test: build-$(LOCAL_ARCH) +test: image-$(LOCAL_ARCH) test: ## test the image - $(S) docker run --rm $(IMAGE)-$(LOCAL_ARCH) image-test + $(S) docker run --rm $(LOCAL_IMAGE) image-test -# Run the image from the first of the PUSH_ARCHES, assuming it'll run on this +# Run the image from the first of the TARGET_ARCHES, assuming it'll run on this # machine since it was built here (this target depends on 'build') .PHONY: shell shell: build-$(LOCAL_ARCH) @@ -67,7 +77,7 @@ shell: ## run the image in a container .PHONY: push-dev push-dev: build test push-dev: ## push the image to the registry - $(S) for arch in $(PUSH_ARCHES); do \ + $(S) for arch in $(TARGET_ARCHES); do \ set -xe ; \ docker push $(IMAGE)-$$arch ; \ done @@ -75,7 +85,7 @@ push-dev: ## push the image to the registry .PHONY: push push: build test push-dev push: ## tag latest and push the to the registry - $(S) for arch in $(PUSH_ARCHES); do \ + $(S) for arch in $(TARGET_ARCHES); do \ set -xe ; \ docker tag $(IMAGE)-$$arch $(LATEST_IMAGE)-$$arch ; \ docker push $(LATEST_IMAGE)-$$arch ; \ @@ -90,14 +100,14 @@ push-manifest: $(S) for tag in "$(LATEST_IMAGE)" "$(IMAGE)"; do \ set -xe ; \ echo "Building manifest for $$tag" ; \ - docker manifest create --amend $$tag $(foreach arch,$(PUSH_ARCHES),$$tag-$(arch)) ; \ + docker manifest create --amend $$tag $(foreach arch,$(TARGET_ARCHES),$$tag-$(arch)) ; \ docker manifest inspect $$tag ; \ docker manifest push $$tag ; \ done -Dockerfile: Dockerfile.tmpl versions.yaml +Dockerfile Dockerfile.build : % : %.tmpl versions.yaml $(S) docker run -i -v '/$(CURDIR)/versions.yaml:/data/versions.yaml' \ - hairyhenderson/gomplate --context 'data=file:///data/versions.yaml?type=application/yaml' < Dockerfile.tmpl > "$@" + hairyhenderson/gomplate --context 'data=file:///data/versions.yaml?type=application/yaml' < $< > "$@" ##@ Helpers @@ -117,7 +127,7 @@ tag: ## print out the tag $(S) if [ -z $(MULTI_ARCH) ] || [ $(N_ARCHES) -gt 1 ]; then \ echo $(IMAGE_TAG) ;\ else \ - echo $(IMAGE_TAG)-$(PUSH_ARCHES) ;\ + echo $(IMAGE_TAG)-$(TARGET_ARCHES) ;\ fi .PHONY: help diff --git a/dist/.gitignore b/dist/.gitignore new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/dist/.gitignore @@ -0,0 +1 @@ +* diff --git a/scripts/build-os-arch b/scripts/build-os-arch new file mode 100755 index 0000000..c033e51 --- /dev/null +++ b/scripts/build-os-arch @@ -0,0 +1,86 @@ +#!/bin/sh + +set -e +set -u + +OPTS=$(getopt -o bi: --long build:,no-build,image: -- "$@") + +if [ $? != 0 ] ; then + echo "E: Invalid options. Stop." + exit 1 +fi + +eval set -- "$OPTS" + +do_build=true + +while true ; do + case "$1" in + -b) + do_build=true + shift + ;; + + --no-build) + do_build=false + shift + ;; + + --build) + do_build="$2" + shift 2 + ;; + + -i|--image) + image_name="$2" + shift 2 + ;; + + --) + shift + break + ;; + + *) + # It should never get here. + echo "E: Internal error. Stop." + exit 1 + ;; + esac +done + +set -x + +target_os=${1:-} +target_arch=${2:-} + +if test -z "${target_os}" ; then + echo "E: Missing target OS. Stop." + exit 1 +fi + +if test -z "${target_arch}" ; then + echo "E: Missing target arch. Stop." + exit 1 +fi + +image_name="${image_name:-build:${target_os}-${target_arch}}" +container_name="container-${target_os}-${target_arch}" + +if "${do_build}" ; then + docker build . \ + --file Dockerfile.build \ + --tag "${image_name}" \ + --build-arg TARGET_GOOS="${target_os}" \ + --build-arg TARGET_GOARCH="${target_arch}" +fi + +docker create --name "${container_name}" "${image_name}" + +trap 'docker rm "${container_name}"' EXIT + +mkdir -p dist/"${target_os}"-"${target_arch}" + +# Extract everything in the dist directory of the image. +docker export "${container_name}" | + tar -C dist/"${target_os}"-"${target_arch}" --strip-components=1 -xf - dist diff --git a/scripts/local-machine b/scripts/local-machine index 42ec757..c699c54 100755 --- a/scripts/local-machine +++ b/scripts/local-machine @@ -2,16 +2,29 @@ set -eu -machine=$(uname --machine) +kernel=$(uname -s) + +case "${kernel}" in + Linux) + kernel=linux + ;; + FreeBSD) + kernel=freebsd + ;; + Darwin) + kernel=darwin + ;; +esac + +machine=$(uname -m) case "${machine}" in x86_64) - echo amd64 + machine=amd64 ;; aarch64) - echo arm64 - ;; - *) - echo "${machine}" + machine=arm64 ;; esac + +echo "${kernel}-${machine}" diff --git a/versions.yaml b/versions.yaml index 1220b12..b882fe5 100644 --- a/versions.yaml +++ b/versions.yaml @@ -31,7 +31,7 @@ enumer: v1.5.10 git_chglog: v0.15.4 # renovate: datasource=docker depName=go packageName=golang -go: 1.22.5 +go: 1.22.6 # renovate: datasource=github-releases depName=golangci-lint packageName=golangci/golangci-lint golangci_lint: v1.59.1