From cec31019914a2d0d312b84f099574e0473afb19c Mon Sep 17 00:00:00 2001 From: jakobmoellerdev Date: Thu, 28 Nov 2024 18:07:48 +0100 Subject: [PATCH 1/3] chore: rework default Dockerfile uses make now to unify our build process to work exactly like we expect, everytime --- .dockerignore | 2 ++ .github/workflows/components.yaml | 8 +++++++ Dockerfile | 19 ++++++++-------- Makefile | 12 +++++----- components/ocmcli/Dockerfile | 23 ------------------- components/ocmcli/Makefile | 38 +++++++++++++++---------------- 6 files changed, 43 insertions(+), 59 deletions(-) delete mode 100644 components/ocmcli/Dockerfile diff --git a/.dockerignore b/.dockerignore index ba8f5ffed7..fc54fb0a69 100644 --- a/.dockerignore +++ b/.dockerignore @@ -22,6 +22,7 @@ bin /hack /LICENSES /local +/gen /pkg/test* @@ -35,3 +36,4 @@ bin !go.* !**/*.go +!.git \ No newline at end of file diff --git a/.github/workflows/components.yaml b/.github/workflows/components.yaml index c519473c20..7cb6aa3997 100644 --- a/.github/workflows/components.yaml +++ b/.github/workflows/components.yaml @@ -66,6 +66,14 @@ jobs: with: go-version-file: '${{ github.workspace }}/go.mod' cache: false + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Docker Login + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Get go environment for use with cache run: | echo "go_cache=$(go env GOCACHE)" >> $GITHUB_ENV diff --git a/Dockerfile b/Dockerfile index 1a8f590786..133b3dc146 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,25 +1,24 @@ -FROM golang:1.23-alpine3.20 AS build +FROM --platform=$BUILDPLATFORM golang:1.23-alpine3.20 AS build + +RUN apk add --no-cache make git WORKDIR /src -RUN go env -w GOMODCACHE=/root/.cache/go-build COPY go.mod go.sum *.go VERSION ./ ARG GO_PROXY="https://proxy.golang.org" ENV GOPROXY=${GO_PROXY} -RUN --mount=type=cache,target=/root/.cache/go-build go mod download +RUN go mod download COPY . . -RUN --mount=type=cache,target=/root/.cache/go-build \ - export VERSION=$(go run api/version/generate/release_generate.go print-rc-version) && \ - export NOW=$(date -u +%FT%T%z) && \ - go build -trimpath -ldflags \ - "-s -w -X ocm.software/ocm/api/version.gitVersion=$VERSION -X ocm.software/ocm/api/version.buildDate=$NOW" \ - -o /bin/ocm ./cmds/ocm/main.go + +ENV BUILD_FLAGS="-trimpath" + +RUN make bin/ocm FROM gcr.io/distroless/static-debian12:nonroot@sha256:d71f4b239be2d412017b798a0a401c44c3049a3ca454838473a4c32ed076bfea -COPY --from=build /bin/ocm /usr/local/bin/ocm +COPY --from=build /src/bin/ocm /usr/local/bin/ocm # https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys LABEL org.opencontainers.image.description="Open Component Model command line interface based on Distroless" diff --git a/Makefile b/Makefile index 726de3d3f2..95082ae572 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ SOURCES := $(shell go list -f '{{$$I:=.Dir}}{{range .GoFiles }}{{$$I}}/{{.}} {{e GOPATH := $(shell go env GOPATH) NOW := $(shell date -u +%FT%T%z) -BUILD_FLAGS := "-s -w \ +LD_FLAGS := "-s -w \ -X ocm.software/ocm/api/version.gitVersion=$(EFFECTIVE_VERSION) \ -X ocm.software/ocm/api/version.gitTreeState=$(GIT_TREE_STATE) \ -X ocm.software/ocm/api/version.gitCommit=$(COMMIT) \ @@ -42,19 +42,19 @@ bin: mkdir -p bin bin/ocm: bin $(SOURCES) - CGO_ENABLED=$(CGO_ENABLED) go build -ldflags $(BUILD_FLAGS) -o bin/ocm ./cmds/ocm + CGO_ENABLED=$(CGO_ENABLED) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/ocm ./cmds/ocm bin/helminstaller: bin $(SOURCES) - CGO_ENABLED=$(CGO_ENABLED) go build -ldflags $(BUILD_FLAGS) -o bin/helminstaller ./cmds/helminstaller + CGO_ENABLED=$(CGO_ENABLED) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/helminstaller ./cmds/helminstaller bin/demo: bin $(SOURCES) - CGO_ENABLED=$(CGO_ENABLED) go build -ldflags $(BUILD_FLAGS) -o bin/demo ./cmds/demoplugin + CGO_ENABLED=$(CGO_ENABLED) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/demo ./cmds/demoplugin bin/cliplugin: bin $(SOURCES) - CGO_ENABLED=$(CGO_ENABLED) go build -ldflags $(BUILD_FLAGS) -o bin/cliplugin ./cmds/cliplugin + CGO_ENABLED=$(CGO_ENABLED) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/cliplugin ./cmds/cliplugin bin/ecrplugin: bin $(SOURCES) - CGO_ENABLED=$(CGO_ENABLED) go build -ldflags $(BUILD_FLAGS) -o bin/ecrplugin ./cmds/ecrplugin + CGO_ENABLED=$(CGO_ENABLED) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/ecrplugin ./cmds/ecrplugin api: $(SOURCES) go build ./api/... diff --git a/components/ocmcli/Dockerfile b/components/ocmcli/Dockerfile deleted file mode 100644 index b17ec7e741..0000000000 --- a/components/ocmcli/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# This Dockerfile is used by `make` via the Makefile - -FROM --platform=$BUILDPLATFORM gcr.io/distroless/static-debian12:nonroot@sha256:d71f4b239be2d412017b798a0a401c44c3049a3ca454838473a4c32ed076bfea - -ARG SUFFIX -ARG OCM_VERSION - -COPY gen/ocmcli/ocmcli.$SUFFIX /usr/local/bin/ocm - -# https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys -LABEL org.opencontainers.image.description="Open Component Model command line interface based on Distroless" -LABEL org.opencontainers.image.vendor="SAP SE" -LABEL org.opencontainers.image.licenses="Apache-2.0" -LABEL org.opencontainers.image.url="https://ocm.software/" -LABEL org.opencontainers.image.source="https://github.com/open-component-model/ocm" -LABEL org.opencontainers.image.title="ocm" -LABEL org.opencontainers.image.version="${OCM_VERSION}" -LABEL org.opencontainers.image.revision="${OCM_VERSION}" -LABEL org.opencontainers.image.documentation="https://github.com/open-component-model/ocm/blob/main/docs/reference/ocm.md" -LABEL org.opencontainers.image.base.name="gcr.io/distroless/static-debian12:nonroot" - -ENTRYPOINT ["/usr/local/bin/ocm"] -CMD ["version"] diff --git a/components/ocmcli/Makefile b/components/ocmcli/Makefile index 20915dab42..76f1fa45a2 100644 --- a/components/ocmcli/Makefile +++ b/components/ocmcli/Makefile @@ -68,40 +68,38 @@ $(GEN)/build: $(GEN) $(GEN)/.exists $(CMDSRCS) $(OCMSRCS) @touch $(GEN)/build .PHONY: image -image: $(GEN)/image - -$(GEN)/image: $(GEN)/.exists Dockerfile $(GEN)/build +image: @PLATFORM_OS_OVERRIDE=$(PLATFORM_OS); \ if [ $$PLATFORM_OS_OVERRIDE == darwin ]; then \ echo; echo "Building linux instead of darwin as there's no native Docker platform for darwin"; echo; \ - docker buildx build -t $(IMAGE):$(VERSION) --platform linux/$(PLATFORM_ARCH) --file Dockerfile $(REPO_ROOT) \ - --build-arg OCM_VERSION=$(EFFECTIVE_VERSION) \ - --build-arg SUFFIX=$$(echo linux/$(PLATFORM_ARCH) | sed -e s:/:-:g); \ + docker buildx build -t $(IMAGE):$(VERSION) --platform linux/$(PLATFORM_ARCH) --file $(REPO_ROOT)/Dockerfile $(REPO_ROOT) \ + --label org.opencontainers.image.version=$(VERSION) \ + --label org.opencontainers.image.revision=$(VERSION); \ else \ echo; echo "Building for $(PLATFORM_OS)/$(ARCH)"; echo; \ - docker buildx build -t $(IMAGE):$(VERSION) --platform $(PLATFORM_OS)/$(PLATFORM_ARCH) --file Dockerfile $(REPO_ROOT) \ - --build-arg OCM_VERSION=$(EFFECTIVE_VERSION) \ - --build-arg SUFFIX=$$(echo $(PLATFORM_OS)/$(PLATFORM_ARCH) | sed -e s:/:-:g); \ + docker buildx build -t $(IMAGE):$(VERSION) --platform $(PLATFORM_OS)/$(PLATFORM_ARCH) --file $(REPO_ROOT)/Dockerfile $(REPO_ROOT) \ + --label org.opencontainers.image.version=$(VERSION) \ + --label org.opencontainers.image.revision=$(VERSION); \ fi - @touch $(GEN)/image -.PHONY: image.multi -image.multi: $(GEN)/image.multi +space := $(subst ,, ) +comma := , -$(GEN)/image.multi: Dockerfile $(GEN)/build +.PHONY: image.multi +image.multi: for i in $(IMAGE_PLATFORMS); do \ - tag=$$(echo $$i | sed -e s:/:-:g); \ - echo building platform $$i; \ - docker buildx build --load -t $(IMAGE):$(VERSION)-$$tag --platform $$i --file Dockerfile $(REPO_ROOT) \ - --build-arg OCM_VERSION=$(EFFECTIVE_VERSION) \ - --build-arg SUFFIX=$$tag; \ + tag=$$(echo $$i | sed -e s:/:-:g); \ + echo building platform $$i; \ + docker buildx build --load -t $(IMAGE):$(VERSION)-$$tag --platform $$i --file $(REPO_ROOT)/Dockerfile $(REPO_ROOT) \ + --build-arg OCM_VERSION=$(EFFECTIVE_VERSION) \ + --label org.opencontainers.image.version=$(VERSION) \ + --label org.opencontainers.image.revision=$(VERSION); \ done - @touch $(GEN)/image.multi .PHONY: ctf ctf: $(GEN)/ctf -$(GEN)/ctf: $(OCM_BIN) $(GEN)/.exists $(GEN)/build $(GEN)/image$(FLAGSUF) component-constructor.yaml $(CHARTSRCS) Makefile +$(GEN)/ctf: $(OCM_BIN) $(GEN)/.exists $(GEN)/build image$(FLAGSUF) component-constructor.yaml $(CHARTSRCS) Makefile @rm -rf "$(GEN)/ctf" $(OCM) add componentversions \ --create \ From 41f9e9572831df946e6d54069c8ad3dad767feca Mon Sep 17 00:00:00 2001 From: jakobmoellerdev Date: Thu, 28 Nov 2024 20:24:42 +0100 Subject: [PATCH 2/3] chore: rework default Dockerfile uses make now to unify our build process to work exactly like we expect, everytime --- Dockerfile | 6 +++++- Makefile | 12 +++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 133b3dc146..77c00ef102 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,11 @@ COPY . . ENV BUILD_FLAGS="-trimpath" -RUN make bin/ocm +# the GOARCH has not a default value to allow the binary be built according to the host where the command +# was called. For example, if we call make docker-build in a local env which has the Apple Silicon SO +# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore, +# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. +RUN make bin/ocm GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} FROM gcr.io/distroless/static-debian12:nonroot@sha256:d71f4b239be2d412017b798a0a401c44c3049a3ca454838473a4c32ed076bfea diff --git a/Makefile b/Makefile index 95082ae572..87542905e6 100644 --- a/Makefile +++ b/Makefile @@ -32,6 +32,8 @@ LD_FLAGS := "-s -w \ -X ocm.software/ocm/api/version.gitCommit=$(COMMIT) \ -X ocm.software/ocm/api/version.buildDate=$(NOW)" CGO_ENABLED := 0 +GOOS := $(shell go env GOOS) +GOARCH := $(shell go env GOARCH) COMPONENTS ?= ocmcli helminstaller demoplugin ecrplugin helmdemo subchartsdemo @@ -42,19 +44,19 @@ bin: mkdir -p bin bin/ocm: bin $(SOURCES) - CGO_ENABLED=$(CGO_ENABLED) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/ocm ./cmds/ocm + CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/ocm ./cmds/ocm bin/helminstaller: bin $(SOURCES) - CGO_ENABLED=$(CGO_ENABLED) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/helminstaller ./cmds/helminstaller + CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/helminstaller ./cmds/helminstaller bin/demo: bin $(SOURCES) - CGO_ENABLED=$(CGO_ENABLED) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/demo ./cmds/demoplugin + CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/demo ./cmds/demoplugin bin/cliplugin: bin $(SOURCES) - CGO_ENABLED=$(CGO_ENABLED) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/cliplugin ./cmds/cliplugin + CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/cliplugin ./cmds/cliplugin bin/ecrplugin: bin $(SOURCES) - CGO_ENABLED=$(CGO_ENABLED) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/ecrplugin ./cmds/ecrplugin + CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/ecrplugin ./cmds/ecrplugin api: $(SOURCES) go build ./api/... From 1d9c9dc478d5d77a8105b936ad7302008111ca3f Mon Sep 17 00:00:00 2001 From: jakobmoellerdev Date: Thu, 28 Nov 2024 20:47:44 +0100 Subject: [PATCH 3/3] chore: add build caching adds a buildcache --- .github/workflows/components.yaml | 4 ++++ components/helminstaller/Makefile | 14 +++++++++++--- components/ocmcli/Makefile | 16 ++++++++++------ 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/.github/workflows/components.yaml b/.github/workflows/components.yaml index 7cb6aa3997..9cf04be0c3 100644 --- a/.github/workflows/components.yaml +++ b/.github/workflows/components.yaml @@ -33,6 +33,8 @@ env: components: '["ocmcli", "helminstaller", "helmdemo", "subchartsdemo", "ecrplugin"]' IMAGE_PLATFORMS: 'linux/amd64 linux/arm64' PLATFORMS: 'windows/amd64 darwin/arm64 darwin/amd64 linux/amd64 linux/arm64' + BUILDX_CACHE_PUSH: ${{ github.ref == 'refs/heads/main' }} + BUILDX_CACHE_REF_BASE: ghcr.io/${{ github.repository }}/buildx-cache jobs: define-matrix: @@ -103,6 +105,8 @@ jobs: VERSION=${{ inputs.version }} \ PLATFORMS="${{ env.PLATFORMS }}" \ IMAGE_PLATFORMS="${{ env.IMAGE_PLATFORMS }}" \ + BUILDX_CACHE_REF=${{ env.BUILDX_CACHE_REF_BASE }}:${{ matrix.component }} \ + BUILDX_CACHE_PUSH=${{ env.BUILDX_CACHE_PUSH }} \ make \ ctf descriptor describe - name: Upload CTF diff --git a/components/helminstaller/Makefile b/components/helminstaller/Makefile index e6c8d43b1c..9dafc4da79 100644 --- a/components/helminstaller/Makefile +++ b/components/helminstaller/Makefile @@ -23,6 +23,14 @@ PLATFORM := $(shell go env GOOS)/$(shell g CACHE_DIR := $(shell go env GOCACHE) MOD_CACHE_DIR := $(shell go env GOMODCACHE) + +ifneq ($(BUILDX_CACHE_REF),) + ADDITIONAL_BUILDX_ARGS += --cache-from type=registry,ref=$(BUILDX_CACHE_REF) + ifeq ($(BUILDX_CACHE_PUSH),true) + ADDITIONAL_BUILDX_ARGS += --cache-to type=registry,ref=$(BUILDX_CACHE_REF) + endif +endif + CREDS ?= # Define the path to the binary OCM_BIN = $(REPO_ROOT)/bin/ocm @@ -48,7 +56,7 @@ BUILD_FLAGS := "-s -w \ -X ocm.software/ocm/api/version.buildDate=$(NOW)" CMDSRCS=$(shell find $(REPO_ROOT)/cmds/$(NAME) -type f) -OCMSRCS=$(shell find $(REPO_ROOT)/pkg -type f) $(REPO_ROOT)/go.* +OCMSRCS=$(shell find $(REPO_ROOT)/api -type f) $(REPO_ROOT)/go.* ifeq ($(MULTI),true) FLAGSUF = .multi @@ -89,7 +97,7 @@ $(GEN)/image.$(NAME): $(GEN)/.exists Dockerfile $(CMDSRCS) $(OCMSRCS) --build-arg CACHE_DIR=$(CACHE_DIR) \ --build-arg MOD_CACHE_DIR=$(MOD_CACHE_DIR) \ --build-arg EFFECTIVE_VERSION=$(EFFECTIVE_VERSION) \ - --build-arg GIT_TREE_STATE=$(GIT_TREE_STATE); \ + --build-arg GIT_TREE_STATE=$(GIT_TREE_STATE) $(ADDITIONAL_BUILDX_ARGS); \ @touch $(GEN)/image.$(NAME) push-image: @@ -108,7 +116,7 @@ $(GEN)/image.$(NAME).multi: $(GEN)/.exists Dockerfile $(CMDSRCS) $(OCMSRCS) --build-arg CACHE_DIR=$(CACHE_DIR) \ --build-arg MOD_CACHE_DIR=$(MOD_CACHE_DIR) \ --build-arg EFFECTIVE_VERSION=$(EFFECTIVE_VERSION) \ - --build-arg GIT_TREE_STATE=$(GIT_TREE_STATE); \ + --build-arg GIT_TREE_STATE=$(GIT_TREE_STATE) $(ADDITIONAL_BUILDX_ARGS); \ done @touch $(GEN)/image.$(NAME).multi diff --git a/components/ocmcli/Makefile b/components/ocmcli/Makefile index 76f1fa45a2..aa5174f443 100644 --- a/components/ocmcli/Makefile +++ b/components/ocmcli/Makefile @@ -31,6 +31,13 @@ ifeq ($(MULTI),true) FLAGSUF = .multi endif +ifneq ($(BUILDX_CACHE_REF),) + ADDITIONAL_BUILDX_ARGS += --cache-from type=registry,ref=$(BUILDX_CACHE_REF) + ifeq ($(BUILDX_CACHE_PUSH),true) + ADDITIONAL_BUILDX_ARGS += --cache-to type=registry,ref=$(BUILDX_CACHE_REF),mode=max + endif +endif + CREDS ?= # Define the path to the binary OCM_BIN = $(REPO_ROOT)/bin/ocm @@ -74,17 +81,14 @@ image: echo; echo "Building linux instead of darwin as there's no native Docker platform for darwin"; echo; \ docker buildx build -t $(IMAGE):$(VERSION) --platform linux/$(PLATFORM_ARCH) --file $(REPO_ROOT)/Dockerfile $(REPO_ROOT) \ --label org.opencontainers.image.version=$(VERSION) \ - --label org.opencontainers.image.revision=$(VERSION); \ + --label org.opencontainers.image.revision=$(VERSION) $(ADDITIONAL_BUILDX_ARGS); \ else \ echo; echo "Building for $(PLATFORM_OS)/$(ARCH)"; echo; \ docker buildx build -t $(IMAGE):$(VERSION) --platform $(PLATFORM_OS)/$(PLATFORM_ARCH) --file $(REPO_ROOT)/Dockerfile $(REPO_ROOT) \ --label org.opencontainers.image.version=$(VERSION) \ - --label org.opencontainers.image.revision=$(VERSION); \ + --label org.opencontainers.image.revision=$(VERSION) $(ADDITIONAL_BUILDX_ARGS); \ fi -space := $(subst ,, ) -comma := , - .PHONY: image.multi image.multi: for i in $(IMAGE_PLATFORMS); do \ @@ -93,7 +97,7 @@ image.multi: docker buildx build --load -t $(IMAGE):$(VERSION)-$$tag --platform $$i --file $(REPO_ROOT)/Dockerfile $(REPO_ROOT) \ --build-arg OCM_VERSION=$(EFFECTIVE_VERSION) \ --label org.opencontainers.image.version=$(VERSION) \ - --label org.opencontainers.image.revision=$(VERSION); \ + --label org.opencontainers.image.revision=$(VERSION) $(ADDITIONAL_BUILDX_ARGS); \ done .PHONY: ctf