From 990b4a361bd5c2b43f5fa4266038012caf13d234 Mon Sep 17 00:00:00 2001
From: Paulo Gomes <paulo.gomes@weave.works>
Date: Mon, 31 Jan 2022 14:45:13 +0000
Subject: [PATCH 1/7] Use static libraries from built image

Signed-off-by: Paulo Gomes <paulo.gomes@weave.works>
---
 .github/actions/run-tests/Dockerfile |  35 ---------
 .github/actions/run-tests/action.yml |  12 ----
 .github/workflows/e2e.yaml           |   9 ++-
 Dockerfile                           |  60 +++++++++++-----
 Makefile                             | 102 +++++++++------------------
 hack/download-musl.sh                |  36 ++++++++++
 hack/install-libraries.sh            |  66 +++++++++++++++++
 7 files changed, 181 insertions(+), 139 deletions(-)
 delete mode 100644 .github/actions/run-tests/Dockerfile
 delete mode 100644 .github/actions/run-tests/action.yml
 create mode 100755 hack/download-musl.sh
 create mode 100755 hack/install-libraries.sh

diff --git a/.github/actions/run-tests/Dockerfile b/.github/actions/run-tests/Dockerfile
deleted file mode 100644
index a67d9b060..000000000
--- a/.github/actions/run-tests/Dockerfile
+++ /dev/null
@@ -1,35 +0,0 @@
-ARG BASE_VARIANT=bullseye
-ARG GO_VERSION=1.17.5
-ARG XX_VERSION=1.1.0
-
-ARG LIBGIT2_IMG=ghcr.io/fluxcd/golang-with-libgit2
-ARG LIBGIT2_TAG=libgit2-1.1.1-3
-
-FROM tonistiigi/xx:${XX_VERSION} AS xx
-FROM ${LIBGIT2_IMG}:${LIBGIT2_TAG} as libgit2
-
-FROM golang:${GO_VERSION}-${BASE_VARIANT} as gostable
-
-# Copy the build utiltiies
-COPY --from=xx / /
-COPY --from=libgit2 /Makefile /libgit2/
-
-# Install the libgit2 build dependencies
-RUN make -C /libgit2 cmake
-
-RUN make -C /libgit2 dependencies
-
-# Compile and install libgit2
-RUN FLAGS=$(xx-clang --print-cmake-defines) make -C /libgit2 libgit2
-
-# Use the GitHub Actions uid:gid combination for proper fs permissions
-RUN groupadd -g 116 test && \
-    useradd -u 1001 --gid test --shell /bin/sh --create-home test
-
-# Set path to envtest binaries.
-ENV PATH="/github/workspace/envtest:${PATH}"
-
-# Run as test user
-USER test
-
-ENTRYPOINT [ "/bin/sh", "-c" ]
diff --git a/.github/actions/run-tests/action.yml b/.github/actions/run-tests/action.yml
deleted file mode 100644
index 6679361aa..000000000
--- a/.github/actions/run-tests/action.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-name: 'Run tests'
-description: 'Run tests in docker container'
-inputs:
-  command:
-    description: 'Command to run inside the container'
-    required: true
-    default: 'make test'
-runs:
-  using: 'docker'
-  image: 'Dockerfile'
-  args:
-    - ${{ inputs.command }}
diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml
index aec5dcd56..1c230115c 100644
--- a/.github/workflows/e2e.yaml
+++ b/.github/workflows/e2e.yaml
@@ -27,6 +27,8 @@ jobs:
           key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
           restore-keys: |
             ${{ runner.os }}-go-
+      - name: Run tests
+        run: make test
       - name: Setup Kubernetes
         uses: engineerd/setup-kind@v0.5.0
         with:
@@ -36,11 +38,6 @@ jobs:
         uses: fluxcd/pkg/actions/kustomize@main
       - name: Setup Helm
         uses: fluxcd/pkg/actions/helm@main
-      - name: Run tests
-        uses: ./.github/actions/run-tests
-        env:
-          GOROOT:
-          GOPATH: /github/home/go
       - name: Verify
         run: make verify
       - name: Run E2E tests
@@ -59,6 +56,8 @@ jobs:
         uses: actions/setup-go@v2
         with:
           go-version: 1.17.x
+      - name: Run tests
+        run: make test
       - name: Prepare
         id: prep
         run: |
diff --git a/Dockerfile b/Dockerfile
index ac8f06848..dae8fa5ae 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,14 +2,27 @@ ARG BASE_VARIANT=alpine
 ARG GO_VERSION=1.17
 ARG XX_VERSION=1.1.0
 
-ARG LIBGIT2_IMG=ghcr.io/fluxcd/golang-with-libgit2
-ARG LIBGIT2_TAG=libgit2-1.1.1-4
+ARG LIBGIT2_IMG
+ARG LIBGIT2_TAG
 
-FROM --platform=linux/amd64 ${LIBGIT2_IMG}:${LIBGIT2_TAG} as build-amd64
-FROM --platform=linux/arm64 ${LIBGIT2_IMG}:${LIBGIT2_TAG} as build-arm64
-FROM --platform=linux/arm/v7 ${LIBGIT2_IMG}:${LIBGIT2_TAG} as build-armv7
+FROM ${LIBGIT2_IMG}:${LIBGIT2_TAG} AS libgit2-libs
 
-FROM --platform=$BUILDPLATFORM build-$TARGETARCH$TARGETVARIANT AS build
+FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
+
+FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-${BASE_VARIANT} as gostable
+
+FROM gostable AS go-linux
+
+# Build-base consists of build platform dependencies and xx.
+# These will be used at current arch to yield execute the cross compilations.
+FROM go-${TARGETOS} AS build-base
+
+RUN apk add --no-cache clang lld pkgconfig
+
+COPY --from=xx / /
+
+# build-go-mod can still be cached at build platform architecture.
+FROM build-base as build-go-mod
 
 # Configure workspace
 WORKDIR /workspace
@@ -24,26 +37,35 @@ COPY go.sum go.sum
 # Cache modules
 RUN go mod download
 
-RUN apk add clang lld pkgconfig ca-certificates
+# Build stage install per target platform
+# dependency and effectively cross compile the application.
+FROM build-go-mod as build
 
-# Build the binary
-ENV CGO_ENABLED=1
 ARG TARGETPLATFORM
 
+COPY --from=libgit2-libs /usr/local/ /usr/local/
+
+# Some dependencies have to installed 
+# for the target platform: https://github.com/tonistiigi/xx#go--cgo
 RUN xx-apk add --no-cache \
         musl-dev gcc lld binutils-gold
 
-# Performance related changes:
-# - Use read-only bind instead of copying go source files.
-# - Cache go packages.
-RUN --mount=target=. \
-    --mount=type=cache,target=/root/.cache/go-build \
-    --mount=type=cache,target=/go/pkg \
-    export LIBRARY_PATH="/usr/local/$(xx-info triple)/lib:/usr/local/$(xx-info triple)/lib64:${LIBRARY_PATH}" && \
+RUN xx-apk add --no-cache musl-utils
+
+WORKDIR /workspace
+
+# Copy source code
+COPY main.go main.go
+COPY controllers/ controllers/
+COPY pkg/ pkg/
+COPY internal/ internal/
+
+ENV CGO_ENABLED=1
+RUN export LIBRARY_PATH="/usr/local/$(xx-info triple):/usr/local/$(xx-info triple)/lib64" && \
     export PKG_CONFIG_PATH="/usr/local/$(xx-info triple)/lib/pkgconfig:/usr/local/$(xx-info triple)/lib64/pkgconfig" && \
-	export FLAGS="$(pkg-config --static --libs --cflags libssh2 openssl libgit2)" && \
-    CGO_LDFLAGS="${FLAGS} -static" \
-	xx-go build \
+    export FLAGS="$(pkg-config --static --libs --cflags libssh2 openssl libgit2)" && \
+    export CGO_LDFLAGS="${FLAGS} -static" && \
+    xx-go build  \
         -ldflags "-s -w" \
         -tags 'netgo,osusergo,static_build' \
         -o /source-controller -trimpath main.go;
diff --git a/Makefile b/Makefile
index 546da8f3f..d0fd80a7f 100644
--- a/Makefile
+++ b/Makefile
@@ -18,33 +18,36 @@ CRD_OPTIONS ?= crd:crdVersions=v1
 # Repository root based on Git metadata
 REPOSITORY_ROOT := $(shell git rev-parse --show-toplevel)
 
-# Libgit2 version
-LIBGIT2_VERSION ?= 1.1.1
-
 # Other dependency versions
 ENVTEST_BIN_VERSION ?= 1.19.2
 
-# libgit2 related magical paths
-# These are used to determine if the target libgit2 version is already available on
-# the system, or where they should be installed to
-SYSTEM_LIBGIT2_VERSION := $(shell pkg-config --modversion libgit2 2>/dev/null)
-LIBGIT2_PATH := $(REPOSITORY_ROOT)/hack/libgit2
+# Caches libgit2 versions per tag, "forcing" rebuild only when needed.
+LIBGIT2_PATH := $(REPOSITORY_ROOT)/build/libgit2/$(LIBGIT2_TAG)
 LIBGIT2_LIB_PATH := $(LIBGIT2_PATH)/lib
-LIBGIT2 := $(LIBGIT2_LIB_PATH)/libgit2.so.$(LIBGIT2_VERSION)
+LIBGIT2_LIB64_PATH := $(LIBGIT2_PATH)/lib64
+LIBGIT2 := $(LIBGIT2_LIB_PATH)/libgit2.a
+MUSL-CC =
 
-ifneq ($(LIBGIT2_VERSION),$(SYSTEM_LIBGIT2_VERSION))
-	LIBGIT2_FORCE ?= 1
-endif
+export CGO_ENABLED=1
+export PKG_CONFIG_PATH=$(LIBGIT2_LIB_PATH)/pkgconfig:$(LIBGIT2_LIB64_PATH)/pkgconfig
+export LD_LIBRARY_PATH=$(LIBGIT2_LIB_PATH):$(LIBGIT2_LIB64_PATH)
+export CGO_CFLAGS=-I$(LIBGIT2_PATH)/include -I$(LIBGIT2_PATH)/include/openssl
 
 ifeq ($(shell uname -s),Darwin)
-	LIBGIT2 := $(LIBGIT2_LIB_PATH)/libgit2.$(LIBGIT2_VERSION).dylib
-	HAS_BREW := $(shell brew --version 2>/dev/null)
-ifdef HAS_BREW
-	HAS_OPENSSL := $(shell brew --prefix openssl@1.1)
-endif
+	export CGO_LDFLAGS=-L$(LIBGIT2_LIB_PATH) -lssh2 -lssl -lcrypto -lgit2
+else
+	export CGO_LDFLAGS=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --static --cflags libssh2 openssl libgit2)
 endif
 
 
+ifeq ($(shell uname -s),Linux)
+	MUSL-PREFIX=$(REPOSITORY_ROOT)/build/musl/$(shell uname -m)-linux-musl-native/bin/$(shell uname -m)-linux-musl
+	MUSL-CC=$(MUSL-PREFIX)-gcc
+	export CC=$(MUSL-PREFIX)-gcc
+	export CXX=$(MUSL-PREFIX)-g++
+	export AR=$(MUSL-PREFIX)-ar
+endif
+
 # API (doc) generation utilities
 CONTROLLER_GEN_VERSION ?= v0.7.0
 GEN_API_REF_DOCS_VERSION ?= v0.3.0
@@ -56,59 +59,32 @@ else
 GOBIN=$(shell go env GOBIN)
 endif
 
-ifeq ($(strip ${PKG_CONFIG_PATH}),)
-	MAKE_PKG_CONFIG_PATH = $(LIBGIT2_LIB_PATH)/pkgconfig
-else
-	MAKE_PKG_CONFIG_PATH = ${PKG_CONFIG_PATH}:$(LIBGIT2_LIB_PATH)/pkgconfig
-endif
-
-ifdef HAS_OPENSSL
-	MAKE_PKG_CONFIG_PATH := $(MAKE_PKG_CONFIG_PATH):$(HAS_OPENSSL)/lib/pkgconfig
-endif
 
 # Architecture to use envtest with
+ifeq ($(shell uname -m),x86_64)
 ENVTEST_ARCH ?= amd64
+else
+ENVTEST_ARCH ?= arm64
+endif
 
 all: build
 
 build: $(LIBGIT2) ## Build manager binary
-ifeq ($(shell uname -s),Darwin)
-	PKG_CONFIG_PATH=$(MAKE_PKG_CONFIG_PATH) \
-	CGO_LDFLAGS="-Wl,-rpath,$(LIBGIT2_LIB_PATH)" \
 	go build -o bin/manager main.go
-else
-	PKG_CONFIG_PATH=$(MAKE_PKG_CONFIG_PATH) \
-	go build -o bin/manager main.go
-endif
 
 KUBEBUILDER_ASSETS?="$(shell $(ENVTEST) --arch=$(ENVTEST_ARCH) use -i $(ENVTEST_KUBERNETES_VERSION) --bin-dir=$(ENVTEST_ASSETS_DIR) -p path)"
 test: $(LIBGIT2) install-envtest test-api  ## Run tests
-ifeq ($(shell uname -s),Darwin)
-	LD_LIBRARY_PATH=$(LIBGIT2_LIB_PATH) \
-	PKG_CONFIG_PATH=$(MAKE_PKG_CONFIG_PATH) \
-	CGO_LDFLAGS="-Wl,-rpath,$(LIBGIT2_LIB_PATH)" \
 	KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) \
-	go test ./... -coverprofile cover.out
-else
-	LD_LIBRARY_PATH=$(LIBGIT2_LIB_PATH) \
-	PKG_CONFIG_PATH=$(MAKE_PKG_CONFIG_PATH) \
-	KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) \
-	go test ./... -coverprofile cover.out
-endif
+	go test ./... \
+		-ldflags "-s -w" \
+		-coverprofile cover.out \
+	 	-tags 'netgo,osusergo,static_build'
 
 test-api: ## Run api tests
 	cd api; go test ./... -coverprofile cover.out
 
 run: $(LIBGIT2) generate fmt vet manifests  ## Run against the configured Kubernetes cluster in ~/.kube/config
-ifeq ($(shell uname -s),Darwin)
-	LD_LIBRARY_PATH=$(LIBGIT2_LIB_PATH) \
-	CGO_LDFLAGS="-Wl,-rpath,$(LIBGIT2_LIB_PATH)" \
 	go run ./main.go
-else
-	LD_LIBRARY_PATH=$(LIBGIT2_LIB_PATH) \
-	go run ./main.go
-endif
-
 
 install: manifests  ## Install CRDs into a cluster
 	kustomize build config/crd | kubectl apply -f -
@@ -142,16 +118,8 @@ fmt:  ## Run go fmt against code
 	cd api; go fmt ./...
 
 vet: $(LIBGIT2)	## Run go vet against code
-ifeq ($(shell uname -s),Darwin)
-	PKG_CONFIG_PATH=$(MAKE_PKG_CONFIG_PATH) \
-	CGO_LDFLAGS="-Wl,-rpath,$(LIBGIT2_LIB_PATH)" \
-	go vet ./...
-	cd api; go vet ./...
-else
-	PKG_CONFIG_PATH=$(MAKE_PKG_CONFIG_PATH) \
 	go vet ./...
 	cd api; go vet ./...
-endif
 
 generate: controller-gen  ## Generate API code
 	cd api; $(CONTROLLER_GEN) object:headerFile="../hack/boilerplate.go.txt" paths="./..."
@@ -192,14 +160,12 @@ install-envtest: setup-envtest ## Download envtest binaries locally.
 
 libgit2: $(LIBGIT2)  ## Detect or download libgit2 library
 
-$(LIBGIT2):
-ifeq (1, $(LIBGIT2_FORCE))
-	@{ \
-	set -e; \
-	mkdir -p $(LIBGIT2_PATH); \
-	curl -sL https://raw.githubusercontent.com/fluxcd/golang-with-libgit2/$(LIBGIT2_TAG)/hack/Makefile -o $(LIBGIT2_PATH)/Makefile; \
-	INSTALL_PREFIX=$(LIBGIT2_PATH) make -C $(LIBGIT2_PATH) libgit2; \
-	}
+$(LIBGIT2): $(MUSL-CC)
+	IMG=$(LIBGIT2_IMG) TAG=$(LIBGIT2_TAG) ./hack/install-libraries.sh
+
+$(MUSL-CC):
+ifneq ($(shell uname -s),Darwin)
+	./hack/download-musl.sh
 endif
 
 .PHONY: help
diff --git a/hack/download-musl.sh b/hack/download-musl.sh
new file mode 100755
index 000000000..de6b4a33f
--- /dev/null
+++ b/hack/download-musl.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+
+set -eoux pipefail
+
+MUSL_X86_64_FILENAME=x86_64-linux-musl-native.tgz
+MUSL_X86_64_SHA512=44d441ad9aa11a06feddf3daa4c9f53ad7d9ca37af1f5a61379aca07793703d179410cea723c1b7fca94c4de19a321228bdb3656bc5cbdb5e3bea8e2d6dac6c7
+MUSL_AARCH64_FILENAME=aarch64-linux-musl-native.tgz
+MUSL_AARCH64_SHA512=16d544e09845c9dbba50f29e0cb04dd661e17eb63c56acad6a67fd2a78aa7596b792477c7177d3cd56d408a27dc291a90507df882f2b099c0f25511ce08fd3b5
+
+MUSL_FILENAME="${MUSL_X86_64_FILENAME}"
+MUSL_SHA512="${MUSL_X86_64_SHA512}"
+if [ "$(uname -m)" = "arm64" ] || [ "$(uname -m)" = "aarch64" ]; then
+    MUSL_FILENAME="${MUSL_AARCH64_FILENAME}"
+    MUSL_SHA512="${MUSL_AARCH64_SHA512}"
+fi
+
+MUSL_AARCH64_URL="https://more.musl.cc/11.2.1/x86_64-linux-musl/${MUSL_FILENAME}"
+
+ROOT_DIR="$(git rev-parse --show-toplevel)"
+MUSL_DIR="${ROOT_DIR}/build/musl"
+
+if [ ! -f "${MUSL_DIR}/bin" ]; then
+    TARGET_FILE="${MUSL_DIR}/${MUSL_FILENAME}"
+    mkdir -p "${MUSL_DIR}"
+
+    echo "${MUSL_SHA512}  ${TARGET_FILE}"
+    curl -o "${TARGET_FILE}" -LO "${MUSL_AARCH64_URL}"
+    if ! echo "${MUSL_SHA512}  ${TARGET_FILE}" | sha512sum --check; then
+        echo "Checksum failed for ${MUSL_FILENAME}."
+        rm -rf "${MUSL_DIR}"
+        exit 1
+    fi
+
+    tar xzf "${TARGET_FILE}" -C "${MUSL_DIR}"
+    rm "${TARGET_FILE}"
+fi
diff --git a/hack/install-libraries.sh b/hack/install-libraries.sh
new file mode 100755
index 000000000..d312b958a
--- /dev/null
+++ b/hack/install-libraries.sh
@@ -0,0 +1,66 @@
+#!/usr/bin/env bash
+
+set -euxo pipefail
+
+IMG="${IMG:-}"
+TAG="${TAG:-}"
+IMG_TAG="${IMG}:${TAG}"
+
+function extract(){
+    PLATFORM=$1
+    DIR=$2
+
+    id=$(docker create --platform="${PLATFORM}" "${IMG_TAG}" sh)
+    docker cp "${id}":/usr/local - > output.tar.gz
+    docker rm -v "${id}"
+
+    tar -xf output.tar.gz "local/${DIR}"
+    rm output.tar.gz
+}
+
+function setup() {
+    PLATFORM=$1
+    DIR=$2
+
+    extract "${PLATFORM}" "${DIR}"
+   
+    NEW_DIR="$(/bin/pwd)/build/libgit2/${TAG}"
+    INSTALLED_DIR="/usr/local/${DIR}"
+
+    mkdir -p "./build/libgit2"
+
+    mv "local/${DIR}" "${TAG}"
+    rm -rf "local"
+    mv "${TAG}/" "./build/libgit2"
+
+    # Update the prefix paths included in the .pc files.
+    # This will make it easier to update to the location in which they will be used.
+    if [[ $OSTYPE == 'darwin'* ]]; then    
+        # sed has a sight different behaviour in MacOS
+        find "${NEW_DIR}" -type f -name "*.pc" | xargs -I {} sed -i "" "s;${INSTALLED_DIR};${NEW_DIR};g" {}
+    else
+        find "${NEW_DIR}" -type f -name "*.pc" | xargs -I {} sed -i "s;${INSTALLED_DIR};${NEW_DIR};g" {}
+    fi
+}
+
+function setup_current() {
+    if [ -d "./build/libgit2/${TAG}" ]; then
+        echo "Skipping libgit2 setup as it already exists"
+        exit 0
+    fi
+
+    DIR="x86_64-alpine-linux-musl"
+    PLATFORM="linux/amd64"
+
+    if [[ "$(uname -m)" == armv7* ]]; then 
+        DIR="armv7-alpine-linux-musleabihf"
+        PLATFORM="linux/arm/v7"
+    elif [ "$(uname -m)" = "arm64" ] || [ "$(uname -m)" = "aarch64" ]; then
+        DIR="aarch64-alpine-linux-musl"
+        PLATFORM="linux/arm64"
+    fi
+    
+    setup "${PLATFORM}" "${DIR}"
+}
+
+setup_current

From 62928217a03429be1ad8e3f1b5f778e0ae5379c8 Mon Sep 17 00:00:00 2001
From: Paulo Gomes <paulo.gomes@weave.works>
Date: Tue, 1 Feb 2022 07:53:41 +0000
Subject: [PATCH 2/7] Optimise cross compilation time

Signed-off-by: Paulo Gomes <paulo.gomes@weave.works>
---
 Dockerfile            | 33 +++++++++++++++++++-----
 hack/download-musl.sh | 59 ++++++++++++++++++++++++++++++++++---------
 2 files changed, 74 insertions(+), 18 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index dae8fa5ae..2fbf5a44d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -37,6 +37,23 @@ COPY go.sum go.sum
 # Cache modules
 RUN go mod download
 
+# The musl-tool-chain layer is an adhoc solution
+# for the problem in which xx gets confused during compilation
+# and a) looks for gold linker and then b) cannot find musl's dynamic linker.
+FROM --platform=$BUILDPLATFORM alpine as musl-tool-chain
+
+COPY --from=xx / /
+
+RUN apk add bash curl tar
+
+WORKDIR /workspace
+COPY hack/download-musl.sh .
+
+ARG TARGETPLATFORM
+ARG TARGETARCH
+RUN ROOT_DIR="$(pwd)" TARGET_ARCH="$(xx-info alpine-arch)" ENV_FILE=true \
+        ./download-musl.sh
+
 # Build stage install per target platform
 # dependency and effectively cross compile the application.
 FROM build-go-mod as build
@@ -47,10 +64,7 @@ COPY --from=libgit2-libs /usr/local/ /usr/local/
 
 # Some dependencies have to installed 
 # for the target platform: https://github.com/tonistiigi/xx#go--cgo
-RUN xx-apk add --no-cache \
-        musl-dev gcc lld binutils-gold
-
-RUN xx-apk add --no-cache musl-utils
+RUN xx-apk add musl-dev gcc lld
 
 WORKDIR /workspace
 
@@ -60,12 +74,19 @@ COPY controllers/ controllers/
 COPY pkg/ pkg/
 COPY internal/ internal/
 
+COPY --from=musl-tool-chain /workspace/build /workspace/build
+
+ARG TARGETPLATFORM
+ARG TARGETARCH
 ENV CGO_ENABLED=1
-RUN export LIBRARY_PATH="/usr/local/$(xx-info triple):/usr/local/$(xx-info triple)/lib64" && \
+
+# Instead of using xx-go, (cross) compile with vanilla go leveraging musl tool chain.
+RUN export $(cat build/musl/$(xx-info alpine-arch).env | xargs) && \
+    export LIBRARY_PATH="/usr/local/$(xx-info triple):/usr/local/$(xx-info triple)/lib64" && \
     export PKG_CONFIG_PATH="/usr/local/$(xx-info triple)/lib/pkgconfig:/usr/local/$(xx-info triple)/lib64/pkgconfig" && \
     export FLAGS="$(pkg-config --static --libs --cflags libssh2 openssl libgit2)" && \
     export CGO_LDFLAGS="${FLAGS} -static" && \
-    xx-go build  \
+    GOARCH=$TARGETARCH go build  \
         -ldflags "-s -w" \
         -tags 'netgo,osusergo,static_build' \
         -o /source-controller -trimpath main.go;
diff --git a/hack/download-musl.sh b/hack/download-musl.sh
index de6b4a33f..e1e518566 100755
--- a/hack/download-musl.sh
+++ b/hack/download-musl.sh
@@ -6,26 +6,61 @@ MUSL_X86_64_FILENAME=x86_64-linux-musl-native.tgz
 MUSL_X86_64_SHA512=44d441ad9aa11a06feddf3daa4c9f53ad7d9ca37af1f5a61379aca07793703d179410cea723c1b7fca94c4de19a321228bdb3656bc5cbdb5e3bea8e2d6dac6c7
 MUSL_AARCH64_FILENAME=aarch64-linux-musl-native.tgz
 MUSL_AARCH64_SHA512=16d544e09845c9dbba50f29e0cb04dd661e17eb63c56acad6a67fd2a78aa7596b792477c7177d3cd56d408a27dc291a90507df882f2b099c0f25511ce08fd3b5
+MUSL_XX86_64_FILENAME=x86_64-linux-musl-cross.tgz
+MUSL_XX86_64_SHA512=52abd1a56e670952116e35d1a62e048a9b6160471d988e16fa0e1611923dd108a581d2e00874af5eb04e4968b1ba32e0eb449a1f15c3e4d5240ebe09caf5a9f3
+MUSL_XAARCH64_FILENAME=aarch64-linux-musl-cross.tgz
+MUSL_XAARCH64_SHA512=8695ff86979cdf30fbbcd33061711f5b1ebc3c48a87822b9ca56cde6d3a22abd4dab30fdcd1789ac27c6febbaeb9e5bde59d79d66552fae53d54cc1377a19272
+MUSL_XARMV7_FILENAME=armv7l-linux-musleabihf-cross.tgz
+MUSL_XARMV7_SHA512=1bb399a61da425faac521df9b8d303e60ad101f6c7827469e0b4bc685ce1f3dedc606ac7b1e8e34d79f762a3bfe3e8ab479a97e97d9f36fbd9fc5dc9d7ed6fd1
 
-MUSL_FILENAME="${MUSL_X86_64_FILENAME}"
-MUSL_SHA512="${MUSL_X86_64_SHA512}"
-if [ "$(uname -m)" = "arm64" ] || [ "$(uname -m)" = "aarch64" ]; then
-    MUSL_FILENAME="${MUSL_AARCH64_FILENAME}"
-    MUSL_SHA512="${MUSL_AARCH64_SHA512}"
-fi
+TARGET_ARCH="${TARGET_ARCH:-$(uname -m)}"
+ENV_FILE="${ENV_FILE:-false}"
 
-MUSL_AARCH64_URL="https://more.musl.cc/11.2.1/x86_64-linux-musl/${MUSL_FILENAME}"
+MUSL_FILENAME=""
+MUSL_SHA512=""
 
-ROOT_DIR="$(git rev-parse --show-toplevel)"
+ROOT_DIR="${ROOT_DIR:-$(git rev-parse --show-toplevel)}"
 MUSL_DIR="${ROOT_DIR}/build/musl"
 
+
+if [ "${TARGET_ARCH}" = "$(uname -m)" ]; then
+    MUSL_FILENAME="${MUSL_X86_64_FILENAME}"
+    MUSL_SHA512="${MUSL_X86_64_SHA512}"
+    MUSL_PREFIX=$(xx-info alpine-arch)-linux-musl-native/bin/$(xx-info alpine-arch)-linux-musl
+    if [ "${TARGET_ARCH}" = "arm64" ] || [ "${TARGET_ARCH}" = "aarch64" ]; then
+        MUSL_FILENAME="${MUSL_AARCH64_FILENAME}"
+        MUSL_SHA512="${MUSL_AARCH64_SHA512}"
+    fi
+else
+    MUSL_FILENAME="${MUSL_XX86_64_FILENAME}"
+    MUSL_SHA512="${MUSL_XX86_64_SHA512}"
+    MUSL_PREFIX=$(xx-info alpine-arch)-linux-musl-cross/bin/$(xx-info alpine-arch)-linux-musl
+    if [ "${TARGET_ARCH}" = "arm64" ] || [ "${TARGET_ARCH}" = "aarch64" ]; then
+        MUSL_FILENAME="${MUSL_XAARCH64_FILENAME}"
+        MUSL_SHA512="${MUSL_XAARCH64_SHA512}"
+    elif [ "${TARGET_ARCH}" = "arm" ] || [ "${TARGET_ARCH}" = "armv7" ]; then
+        MUSL_FILENAME="${MUSL_XARMV7_FILENAME}"
+        MUSL_SHA512="${MUSL_XARMV7_SHA512}"
+        MUSL_PREFIX=armv7l-linux-musleabihf-cross/bin/armv7l-linux-musleabihf
+    fi
+fi
+
+mkdir -p "${MUSL_DIR}"
+
+if "${ENV_FILE}"; then
+    cat<<EOF > "${MUSL_DIR}/${TARGET_ARCH}.env"
+CC="$(pwd)/build/musl/${MUSL_PREFIX}-gcc"
+CXX="$(pwd)/build/musl/${MUSL_PREFIX}-g++"
+AR="$(pwd)/build/musl/${MUSL_PREFIX}-ar"
+EOF
+fi
+
+MUSL_AARCH64_URL="https://more.musl.cc/11.2.1/x86_64-linux-musl/${MUSL_FILENAME}"
+
 if [ ! -f "${MUSL_DIR}/bin" ]; then
     TARGET_FILE="${MUSL_DIR}/${MUSL_FILENAME}"
-    mkdir -p "${MUSL_DIR}"
-
-    echo "${MUSL_SHA512}  ${TARGET_FILE}"
     curl -o "${TARGET_FILE}" -LO "${MUSL_AARCH64_URL}"
-    if ! echo "${MUSL_SHA512}  ${TARGET_FILE}" | sha512sum --check; then
+    if ! echo "${MUSL_SHA512}  ${TARGET_FILE}" | sha512sum; then
         echo "Checksum failed for ${MUSL_FILENAME}."
         rm -rf "${MUSL_DIR}"
         exit 1

From 60c98b5471fe82378e05e900b247a90e5c7af363 Mon Sep 17 00:00:00 2001
From: Paulo Gomes <paulo.gomes@weave.works>
Date: Thu, 3 Feb 2022 13:31:28 +0000
Subject: [PATCH 3/7] Update libgit2 to 1.1.1-6 Fix issues developing in amd64,
 arm64 and apple silicon

Signed-off-by: Paulo Gomes <paulo.gomes@weave.works>
---
 .gitignore                |  3 --
 Dockerfile                |  3 +-
 Makefile                  | 66 +++++++++++++++++++++++++--------------
 hack/download-musl.sh     |  4 +--
 hack/install-libraries.sh | 53 ++++++++++++++++++++-----------
 5 files changed, 80 insertions(+), 49 deletions(-)

diff --git a/.gitignore b/.gitignore
index f935d4a38..327ff117d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,8 +17,5 @@ bin/
 testbin/
 config/release/
 
-# Exclude all libgit2 related files
-hack/libgit2/
-
 # Exclude temporary build files
 build/
diff --git a/Dockerfile b/Dockerfile
index 2fbf5a44d..ca9289fef 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -84,8 +84,7 @@ ENV CGO_ENABLED=1
 RUN export $(cat build/musl/$(xx-info alpine-arch).env | xargs) && \
     export LIBRARY_PATH="/usr/local/$(xx-info triple):/usr/local/$(xx-info triple)/lib64" && \
     export PKG_CONFIG_PATH="/usr/local/$(xx-info triple)/lib/pkgconfig:/usr/local/$(xx-info triple)/lib64/pkgconfig" && \
-    export FLAGS="$(pkg-config --static --libs --cflags libssh2 openssl libgit2)" && \
-    export CGO_LDFLAGS="${FLAGS} -static" && \
+    export CGO_LDFLAGS="$(pkg-config --static --libs --cflags libssh2 openssl libgit2) -static" && \
     GOARCH=$TARGETARCH go build  \
         -ldflags "-s -w" \
         -tags 'netgo,osusergo,static_build' \
diff --git a/Makefile b/Makefile
index d0fd80a7f..5649aaf2f 100644
--- a/Makefile
+++ b/Makefile
@@ -17,48 +17,60 @@ CRD_OPTIONS ?= crd:crdVersions=v1
 
 # Repository root based on Git metadata
 REPOSITORY_ROOT := $(shell git rev-parse --show-toplevel)
+BUILD_DIR := $(REPOSITORY_ROOT)/build
 
 # Other dependency versions
 ENVTEST_BIN_VERSION ?= 1.19.2
 
 # Caches libgit2 versions per tag, "forcing" rebuild only when needed.
-LIBGIT2_PATH := $(REPOSITORY_ROOT)/build/libgit2/$(LIBGIT2_TAG)
+LIBGIT2_PATH := $(BUILD_DIR)/libgit2/$(LIBGIT2_TAG)
 LIBGIT2_LIB_PATH := $(LIBGIT2_PATH)/lib
 LIBGIT2_LIB64_PATH := $(LIBGIT2_PATH)/lib64
 LIBGIT2 := $(LIBGIT2_LIB_PATH)/libgit2.a
 MUSL-CC =
 
 export CGO_ENABLED=1
-export PKG_CONFIG_PATH=$(LIBGIT2_LIB_PATH)/pkgconfig:$(LIBGIT2_LIB64_PATH)/pkgconfig
-export LD_LIBRARY_PATH=$(LIBGIT2_LIB_PATH):$(LIBGIT2_LIB64_PATH)
+export PKG_CONFIG_PATH=$(LIBGIT2_LIB_PATH)/pkgconfig
+export LIBRARY_PATH=$(LIBGIT2_LIB_PATH)
 export CGO_CFLAGS=-I$(LIBGIT2_PATH)/include -I$(LIBGIT2_PATH)/include/openssl
 
+
 ifeq ($(shell uname -s),Darwin)
-	export CGO_LDFLAGS=-L$(LIBGIT2_LIB_PATH) -lssh2 -lssl -lcrypto -lgit2
+export CGO_LDFLAGS=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --static --cflags libssh2 openssl libgit2)
+GO_STATIC_FLAGS=-ldflags "-s -w" -tags 'netgo,osusergo,static_build'
 else
-	export CGO_LDFLAGS=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --static --cflags libssh2 openssl libgit2)
+export PKG_CONFIG_PATH:=$(PKG_CONFIG_PATH):$(LIBGIT2_LIB64_PATH)/pkgconfig
+export LIBRARY_PATH:=$(LIBRARY_PATH):$(LIBGIT2_LIB64_PATH)
+export CGO_LDFLAGS=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --static --cflags libssh2 openssl libgit2)
 endif
 
 
 ifeq ($(shell uname -s),Linux)
-	MUSL-PREFIX=$(REPOSITORY_ROOT)/build/musl/$(shell uname -m)-linux-musl-native/bin/$(shell uname -m)-linux-musl
+ifeq ($(shell uname -m),x86_64)
+# Linux x86_64 seem to be able to cope with the static libraries 
+# by having only musl-dev installed, without the need of using musl toolchain.
+	GO_STATIC_FLAGS=-ldflags "-s -w" -tags 'netgo,osusergo,static_build'
+else
+	MUSL-PREFIX=$(BUILD_DIR)/musl/$(shell uname -m)-linux-musl-native/bin/$(shell uname -m)-linux-musl
 	MUSL-CC=$(MUSL-PREFIX)-gcc
 	export CC=$(MUSL-PREFIX)-gcc
 	export CXX=$(MUSL-PREFIX)-g++
 	export AR=$(MUSL-PREFIX)-ar
+	GO_STATIC_FLAGS=-ldflags "-s -w -extldflags \"-static\"" -tags 'netgo,osusergo,static_build'
+endif
 endif
 
 # API (doc) generation utilities
 CONTROLLER_GEN_VERSION ?= v0.7.0
 GEN_API_REF_DOCS_VERSION ?= v0.3.0
 
-# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
+# If gobin not set, create one on ./build and add to path.
 ifeq (,$(shell go env GOBIN))
-GOBIN=$(shell go env GOPATH)/bin
+export GOBIN=$(BUILD_DIR)/gobin
 else
-GOBIN=$(shell go env GOBIN)
+export GOBIN=$(shell go env GOBIN)
 endif
-
+export PATH:=${GOBIN}:${PATH}
 
 # Architecture to use envtest with
 ifeq ($(shell uname -m),x86_64)
@@ -67,24 +79,31 @@ else
 ENVTEST_ARCH ?= arm64
 endif
 
+ifeq ($(shell uname -s),Darwin)
+# Envtest only supports darwin-amd64
+ENVTEST_ARCH=amd64
+endif
+
 all: build
 
-build: $(LIBGIT2) ## Build manager binary
-	go build -o bin/manager main.go
+build: check-deps $(LIBGIT2) ## Build manager binary
+	go build $(GO_STATIC_FLAGS) -o $(BUILD_DIR)/bin/manager main.go
 
 KUBEBUILDER_ASSETS?="$(shell $(ENVTEST) --arch=$(ENVTEST_ARCH) use -i $(ENVTEST_KUBERNETES_VERSION) --bin-dir=$(ENVTEST_ASSETS_DIR) -p path)"
-test: $(LIBGIT2) install-envtest test-api  ## Run tests
+test: $(LIBGIT2) install-envtest test-api check-deps ## Run tests
 	KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) \
-	go test ./... \
-		-ldflags "-s -w" \
-		-coverprofile cover.out \
-	 	-tags 'netgo,osusergo,static_build'
+	go test $(GO_STATIC_FLAGS) ./... -coverprofile cover.out
+
+check-deps:
+ifeq ($(shell uname -s),Darwin)
+	if ! command -v pkg-config &> /dev/null; then echo "pkg-config is required"; exit 1; fi
+endif
 
 test-api: ## Run api tests
 	cd api; go test ./... -coverprofile cover.out
 
 run: $(LIBGIT2) generate fmt vet manifests  ## Run against the configured Kubernetes cluster in ~/.kube/config
-	go run ./main.go
+	go run $(GO_STATIC_FLAGS) ./main.go
 
 install: manifests  ## Install CRDs into a cluster
 	kustomize build config/crd | kubectl apply -f -
@@ -136,23 +155,23 @@ docker-push:  ## Push Docker image
 	docker push $(IMG):$(TAG)
 
 # Find or download controller-gen
-CONTROLLER_GEN = $(shell pwd)/bin/controller-gen
+CONTROLLER_GEN = $(GOBIN)/controller-gen
 .PHONY: controller-gen
 controller-gen: ## Download controller-gen locally if necessary.
 	$(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.7.0)
 
 # Find or download gen-crd-api-reference-docs
-GEN_CRD_API_REFERENCE_DOCS = $(shell pwd)/bin/gen-crd-api-reference-docs
+GEN_CRD_API_REFERENCE_DOCS = $(GOBIN)/gen-crd-api-reference-docs
 .PHONY: gen-crd-api-reference-docs
 gen-crd-api-reference-docs: ## Download gen-crd-api-reference-docs locally if necessary
 	$(call go-install-tool,$(GEN_CRD_API_REFERENCE_DOCS),github.com/ahmetb/gen-crd-api-reference-docs@v0.3.0)
 
-ENVTEST = $(shell pwd)/bin/setup-envtest
+ENVTEST = $(GOBIN)/setup-envtest
 .PHONY: envtest
 setup-envtest: ## Download setup-envtest locally if necessary.
 	$(call go-install-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest@latest)
 
-ENVTEST_ASSETS_DIR=$(shell pwd)/testbin
+ENVTEST_ASSETS_DIR=$(BUILD_DIR)/testbin
 ENVTEST_KUBERNETES_VERSION?=latest
 install-envtest: setup-envtest ## Download envtest binaries locally.
 	mkdir -p ${ENVTEST_ASSETS_DIR}
@@ -188,7 +207,6 @@ ifneq (, $(shell git status --porcelain --untracked-files=no))
 endif
 
 # go-install-tool will 'go install' any package $2 and install it to $1.
-PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
 define go-install-tool
 @[ -f $(1) ] || { \
 set -e ;\
@@ -196,7 +214,7 @@ TMP_DIR=$$(mktemp -d) ;\
 cd $$TMP_DIR ;\
 go mod init tmp ;\
 echo "Downloading $(2)" ;\
-GOBIN=$(PROJECT_DIR)/bin go install $(2) ;\
+go install $(2) ;\
 rm -rf $$TMP_DIR ;\
 }
 endef
diff --git a/hack/download-musl.sh b/hack/download-musl.sh
index e1e518566..3f5b527d2 100755
--- a/hack/download-musl.sh
+++ b/hack/download-musl.sh
@@ -26,7 +26,7 @@ MUSL_DIR="${ROOT_DIR}/build/musl"
 if [ "${TARGET_ARCH}" = "$(uname -m)" ]; then
     MUSL_FILENAME="${MUSL_X86_64_FILENAME}"
     MUSL_SHA512="${MUSL_X86_64_SHA512}"
-    MUSL_PREFIX=$(xx-info alpine-arch)-linux-musl-native/bin/$(xx-info alpine-arch)-linux-musl
+    MUSL_PREFIX="${TARGET_ARCH}-linux-musl-native/bin/${TARGET_ARCH}-linux-musl"
     if [ "${TARGET_ARCH}" = "arm64" ] || [ "${TARGET_ARCH}" = "aarch64" ]; then
         MUSL_FILENAME="${MUSL_AARCH64_FILENAME}"
         MUSL_SHA512="${MUSL_AARCH64_SHA512}"
@@ -34,7 +34,7 @@ if [ "${TARGET_ARCH}" = "$(uname -m)" ]; then
 else
     MUSL_FILENAME="${MUSL_XX86_64_FILENAME}"
     MUSL_SHA512="${MUSL_XX86_64_SHA512}"
-    MUSL_PREFIX=$(xx-info alpine-arch)-linux-musl-cross/bin/$(xx-info alpine-arch)-linux-musl
+    MUSL_PREFIX="${TARGET_ARCH}-linux-musl-cross/bin/${TARGET_ARCH}-linux-musl"
     if [ "${TARGET_ARCH}" = "arm64" ] || [ "${TARGET_ARCH}" = "aarch64" ]; then
         MUSL_FILENAME="${MUSL_XAARCH64_FILENAME}"
         MUSL_SHA512="${MUSL_XAARCH64_SHA512}"
diff --git a/hack/install-libraries.sh b/hack/install-libraries.sh
index d312b958a..cc5615c3d 100755
--- a/hack/install-libraries.sh
+++ b/hack/install-libraries.sh
@@ -27,20 +27,13 @@ function setup() {
     NEW_DIR="$(/bin/pwd)/build/libgit2/${TAG}"
     INSTALLED_DIR="/usr/local/${DIR}"
 
-    mkdir -p "./build/libgit2"
-
     mv "local/${DIR}" "${TAG}"
     rm -rf "local"
     mv "${TAG}/" "./build/libgit2"
 
     # Update the prefix paths included in the .pc files.
     # This will make it easier to update to the location in which they will be used.
-    if [[ $OSTYPE == 'darwin'* ]]; then    
-        # sed has a sight different behaviour in MacOS
-        find "${NEW_DIR}" -type f -name "*.pc" | xargs -I {} sed -i "" "s;${INSTALLED_DIR};${NEW_DIR};g" {}
-    else
-        find "${NEW_DIR}" -type f -name "*.pc" | xargs -I {} sed -i "s;${INSTALLED_DIR};${NEW_DIR};g" {}
-    fi
+    find "${NEW_DIR}" -type f -name "*.pc" | xargs -I {} sed -i "s;${INSTALLED_DIR};${NEW_DIR};g" {}
 }
 
 function setup_current() {
@@ -49,18 +42,42 @@ function setup_current() {
         exit 0
     fi
 
-    DIR="x86_64-alpine-linux-musl"
-    PLATFORM="linux/amd64"
+    mkdir -p "./build/libgit2"
+    if [[ $OSTYPE == 'darwin'* ]]; then
+        # For MacOS development environments, download the amd64 static libraries released from from golang-with-libgit2.
+
+        #TODO: update URL with official URL + TAG:
+        curl -o output.tar.gz -LO "https://github.com/pjbgf/golang-with-libgit2/releases/download/1.1.1-6/darwin-libs.tar.gz"
+       
+        DIR=libgit2-darwin
+        NEW_DIR="$(/bin/pwd)/build/libgit2/${TAG}"
+        INSTALLED_DIR="/Users/runner/work/golang-with-libgit2/golang-with-libgit2/build/${DIR}-amd64"
+
+        tar -xf output.tar.gz
+        mv "${DIR}" "${TAG}"
+        mv "${TAG}/" "./build/libgit2"
+
+        sed -i "" "s;-L/Applications/Xcode_12.4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/usr/lib ;;g" "$(/bin/pwd)/build/libgit2/${TAG}/lib/pkgconfig/libgit2.pc"
+
+        # Update the prefix paths included in the .pc files.
+        # This will make it easier to update to the location in which they will be used.
+        # sed has a sight different behaviour in MacOS
+        find "${NEW_DIR}" -type f -name "*.pc" | xargs -I {} sed -i "" "s;${INSTALLED_DIR};${NEW_DIR};g" {}
+    else
+        # for linux development environments, use the static libraries from the official container images.
+        DIR="x86_64-alpine-linux-musl"
+        PLATFORM="linux/amd64"
 
-    if [[ "$(uname -m)" == armv7* ]]; then 
-        DIR="armv7-alpine-linux-musleabihf"
-        PLATFORM="linux/arm/v7"
-    elif [ "$(uname -m)" = "arm64" ] || [ "$(uname -m)" = "aarch64" ]; then
-        DIR="aarch64-alpine-linux-musl"
-        PLATFORM="linux/arm64"
+        if [[ "$(uname -m)" == armv7* ]]; then 
+            DIR="armv7-alpine-linux-musleabihf"
+            PLATFORM="linux/arm/v7"
+        elif [ "$(uname -m)" = "arm64" ] || [ "$(uname -m)" = "aarch64" ]; then
+            DIR="aarch64-alpine-linux-musl"
+            PLATFORM="linux/arm64"
+        fi
+        
+        setup "${PLATFORM}" "${DIR}"
     fi
-    
-    setup "${PLATFORM}" "${DIR}"
 }
 
 setup_current

From 21e71c3750ffbca575376237647bbcaea8dc88fa Mon Sep 17 00:00:00 2001
From: Paulo Gomes <paulo.gomes@weave.works>
Date: Mon, 7 Feb 2022 13:00:03 +0000
Subject: [PATCH 4/7] Set u+w to envtest folders

Signed-off-by: Paulo Gomes <paulo.gomes@weave.works>
---
 Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Makefile b/Makefile
index 5649aaf2f..552007dd1 100644
--- a/Makefile
+++ b/Makefile
@@ -176,6 +176,8 @@ ENVTEST_KUBERNETES_VERSION?=latest
 install-envtest: setup-envtest ## Download envtest binaries locally.
 	mkdir -p ${ENVTEST_ASSETS_DIR}
 	$(ENVTEST) use $(ENVTEST_KUBERNETES_VERSION) --arch=$(ENVTEST_ARCH) --bin-dir=$(ENVTEST_ASSETS_DIR)
+# setup-envtest sets anything below k8s to 0555
+	chmod -R u+w $(BUILD_DIR)
 
 libgit2: $(LIBGIT2)  ## Detect or download libgit2 library
 

From fa00ec8fc796c6578645ac012d7b14a625a08c3d Mon Sep 17 00:00:00 2001
From: Paulo Gomes <paulo.gomes@weave.works>
Date: Mon, 7 Feb 2022 15:08:03 +0000
Subject: [PATCH 5/7] Migrate from deprecated ginkgo async testing
 https://github.com/onsi/ginkgo/blob/ver2/docs/MIGRATING_TO_V2.md\#removed-async-testing

Signed-off-by: Paulo Gomes <paulo.gomes@weave.works>
---
 controllers/suite_test.go | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/controllers/suite_test.go b/controllers/suite_test.go
index 9520bcbb6..f0c411702 100644
--- a/controllers/suite_test.go
+++ b/controllers/suite_test.go
@@ -56,6 +56,8 @@ var exampleCA []byte
 var ctx context.Context
 var cancel context.CancelFunc
 
+const timeout = time.Second * 30
+
 func TestAPIs(t *testing.T) {
 	RegisterFailHandler(Fail)
 
@@ -64,7 +66,12 @@ func TestAPIs(t *testing.T) {
 		[]Reporter{printer.NewlineReporter{}})
 }
 
-var _ = BeforeSuite(func(done Done) {
+var _ = BeforeSuite(func() {
+	done := make(chan interface{})
+	go func() {
+		close(done)
+	}()
+
 	logf.SetLogger(
 		zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)),
 	)
@@ -153,7 +160,7 @@ var _ = BeforeSuite(func(done Done) {
 	k8sClient = k8sManager.GetClient()
 	Expect(k8sClient).ToNot(BeNil())
 
-	close(done)
+	Eventually(done, timeout).Should(BeClosed())
 }, 60)
 
 var _ = AfterSuite(func() {

From c5e2e5e30bf2a19e8a3f5ae97eb06a98391d36b4 Mon Sep 17 00:00:00 2001
From: Paulo Gomes <paulo.gomes@weave.works>
Date: Mon, 7 Feb 2022 18:36:18 +0000
Subject: [PATCH 6/7] Add make test execution for macos-10.15

Signed-off-by: Paulo Gomes <paulo.gomes@weave.works>
---
 .github/workflows/e2e.yaml | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml
index 1c230115c..33ee1ca4c 100644
--- a/.github/workflows/e2e.yaml
+++ b/.github/workflows/e2e.yaml
@@ -79,3 +79,24 @@ jobs:
         run: |
           kind delete cluster --name ${{ steps.prep.outputs.CLUSTER }}
           rm /tmp/${{ steps.prep.outputs.CLUSTER }}
+
+  # Runs 'make test' on macos-10.15 to assure development environment for 
+  # contributors using MacOS.
+  darwin-amd64:
+    runs-on: macos-10.15
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+      - name: Setup Go
+        uses: actions/setup-go@v2
+        with:
+          go-version: 1.17.x
+      - name: Restore Go cache
+        uses: actions/cache@v1
+        with:
+          path: /home/runner/work/_temp/_github_home/go/pkg/mod
+          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
+          restore-keys: |
+            ${{ runner.os }}-go-
+      - name: Run tests
+        run: make test

From 80e1d243e641b8cf30868ac4a81b367e266b2bc8 Mon Sep 17 00:00:00 2001
From: Paulo Gomes <paulo.gomes@weave.works>
Date: Tue, 8 Feb 2022 10:51:20 +0000
Subject: [PATCH 7/7] Upgrade to libgit2-1.1.1-6

Signed-off-by: Paulo Gomes <paulo.gomes@weave.works>
---
 .github/workflows/e2e.yaml |  6 +++++-
 Makefile                   |  7 ++++---
 hack/install-libraries.sh  | 29 ++++++++++++++++++++++-------
 3 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml
index 33ee1ca4c..482e7cacb 100644
--- a/.github/workflows/e2e.yaml
+++ b/.github/workflows/e2e.yaml
@@ -57,7 +57,11 @@ jobs:
         with:
           go-version: 1.17.x
       - name: Run tests
-        run: make test
+        run: |
+          mkdir tmp-download; cd tmp-download; go mod init go-download;
+          GOBIN="${GITHUB_WORKSPACE}/build/gobin" go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
+          cd ..; rm -rf tmp-download
+          make test
       - name: Prepare
         id: prep
         run: |
diff --git a/Makefile b/Makefile
index 552007dd1..b6f636bda 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ TAG ?= latest
 
 # Base image used to build the Go binary
 LIBGIT2_IMG ?= ghcr.io/fluxcd/golang-with-libgit2
-LIBGIT2_TAG ?= libgit2-1.1.1-4
+LIBGIT2_TAG ?= libgit2-1.1.1-6
 
 # Allows for defining additional Docker buildx arguments,
 # e.g. '--push'.
@@ -35,13 +35,14 @@ export LIBRARY_PATH=$(LIBGIT2_LIB_PATH)
 export CGO_CFLAGS=-I$(LIBGIT2_PATH)/include -I$(LIBGIT2_PATH)/include/openssl
 
 
+# The pkg-config command will yield warning messages until libgit2 is downloaded.
 ifeq ($(shell uname -s),Darwin)
-export CGO_LDFLAGS=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --static --cflags libssh2 openssl libgit2)
+export CGO_LDFLAGS=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --static --cflags libssh2 openssl libgit2 2>/dev/null)
 GO_STATIC_FLAGS=-ldflags "-s -w" -tags 'netgo,osusergo,static_build'
 else
 export PKG_CONFIG_PATH:=$(PKG_CONFIG_PATH):$(LIBGIT2_LIB64_PATH)/pkgconfig
 export LIBRARY_PATH:=$(LIBRARY_PATH):$(LIBGIT2_LIB64_PATH)
-export CGO_LDFLAGS=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --static --cflags libssh2 openssl libgit2)
+export CGO_LDFLAGS=$(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs --static --cflags libssh2 openssl libgit2 2>/dev/null)
 endif
 
 
diff --git a/hack/install-libraries.sh b/hack/install-libraries.sh
index cc5615c3d..270ce1915 100755
--- a/hack/install-libraries.sh
+++ b/hack/install-libraries.sh
@@ -47,22 +47,37 @@ function setup_current() {
         # For MacOS development environments, download the amd64 static libraries released from from golang-with-libgit2.
 
         #TODO: update URL with official URL + TAG:
-        curl -o output.tar.gz -LO "https://github.com/pjbgf/golang-with-libgit2/releases/download/1.1.1-6/darwin-libs.tar.gz"
+        curl -o output.tar.gz -LO "https://github.com/fluxcd/golang-with-libgit2/releases/download/${TAG}/darwin-libs.tar.gz"
        
         DIR=libgit2-darwin
         NEW_DIR="$(/bin/pwd)/build/libgit2/${TAG}"
         INSTALLED_DIR="/Users/runner/work/golang-with-libgit2/golang-with-libgit2/build/${DIR}-amd64"
 
         tar -xf output.tar.gz
+        rm output.tar.gz
         mv "${DIR}" "${TAG}"
         mv "${TAG}/" "./build/libgit2"
 
-        sed -i "" "s;-L/Applications/Xcode_12.4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/usr/lib ;;g" "$(/bin/pwd)/build/libgit2/${TAG}/lib/pkgconfig/libgit2.pc"
-
-        # Update the prefix paths included in the .pc files.
-        # This will make it easier to update to the location in which they will be used.
-        # sed has a sight different behaviour in MacOS
-        find "${NEW_DIR}" -type f -name "*.pc" | xargs -I {} sed -i "" "s;${INSTALLED_DIR};${NEW_DIR};g" {}
+        LIBGIT2_SED="s;-L/Applications/Xcode_.* ;;g"
+        LIBGIT2PC="$(/bin/pwd)/build/libgit2/${TAG}/lib/pkgconfig/libgit2.pc"
+        # Some macOS users may override their sed with gsed. If gsed is the PATH, use that instead.
+        if command -v gsed &> /dev/null; then 
+            # Removes abs path from build machine, and let iconv be resolved automatically by default search paths.
+            gsed -i "${LIBGIT2_SED}" "${LIBGIT2PC}"
+
+            # Update the prefix paths included in the .pc files.
+            # This will make it easier to update to the location in which they will be used.
+            # sed has a sight different behaviour in MacOS
+            find "${NEW_DIR}" -type f -name "*.pc" | xargs -I {} gsed -i "s;${INSTALLED_DIR};${NEW_DIR};g" {}
+        else
+            # Removes abs path from build machine, and let iconv be resolved automatically by default search paths.
+            sed -i "" "${LIBGIT2_SED}" "${LIBGIT2PC}"
+
+            # Update the prefix paths included in the .pc files.
+            # This will make it easier to update to the location in which they will be used.
+            # sed has a sight different behaviour in MacOS
+            find "${NEW_DIR}" -type f -name "*.pc" | xargs -I {} sed -i "" "s;${INSTALLED_DIR};${NEW_DIR};g" {}
+        fi
     else
         # for linux development environments, use the static libraries from the official container images.
         DIR="x86_64-alpine-linux-musl"