corso/build/build.sh
Abin Simon a9acbc28f5
Rework build.sh script (#1167)
## Description

While trying to work on https://github.com/alcionai/corso/issues/1166, I ended up reworking parts of the build script ~, but I'm running into some issues with building it on CI. Pushing it here just for reference.~

The new one combines both `build.sh` and `build-container.sh` into a single script where you can specify what to build. Also, inorder setup a proper multi arch, build system locally, we will have to properly setup buildx which is explained in https://docs.docker.com/build/building/multi-platform/ or https://stackoverflow.com/a/70837025/2724649 . I'll add this instructions to docs.

The new build script looks something like this:

```
Usage: build.sh <binary|image> [--platforms ...] [--tag ...]

OPTIONS
 -p|--platforms  Platforms to build for (default: linux/amd64)
                 Specify multiple platforms using ',' (eg: linux/amd64,darwin/arm)
 -t|--tag        Tag for container image (default: alcionai/corso)
```

---
I've made sure the image and binary has the proper architecure and that the amd64 one runs properly in my system. It would be helpful if someone who has access to arm system can validate the arm image. You can use https://github.com/alcionai/corso/pkgs/container/corso/45878348?tag=84fc9d4 image to verify.

```
$ cat check-image.sh
imgid="$(docker create "$1")"
docker cp "$imgid:corso" /tmp/corso

echo Image: "$(docker inspect "$1" | jq '.[0].Architecture')"
echo Binary: "$(file /tmp/corso)"

$ ./check-image.sh ghcr.io/alcionai/corso:84fc9d4@sha256:2278a2b4f108e5dd2ae545f53da1d151b77171f969ffd9718e4bb9886e332ee2
WARNING: The requested image's platform (linux/arm64) does not match the detected host platform (linux/amd64) and no specific platform was requested
Image: "arm64"
Binary: /tmp/corso: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-aarch64.so.1, Go BuildID=7iTBXW0reyfIOS-b-ciS/a5K0Q1IjuA0m9DJxmuNk/Ju1lI6bUZeKn6M_xqon6/KNXwYSnL7e5RVtjAKW9A, not stripped

$ ./check-image.sh ghcr.io/alcionai/corso:84fc9d4@sha256:6320b95470014ca07b9cf1db98b73f5672870c2c53c22c3d13223d88fa621ee0
Image: "amd64"
Binary: /tmp/corso: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, Go BuildID=sBziMHPFI9K-G0et0WjJ/Pe9A2Vy8_xpV3FEDJUMo/p4UeMEzgheASvylZ1N3j/fnwmDeVif4rhneou-S6O, not stripped

$ docker run -it --rm ghcr.io/alcionai/corso:84fc9d4@sha256:6320b95470014ca07b9cf1db98b73f5672870c2c53c22c3d13223d88fa621ee0
[...help message...]
```

## Type of change

<!--- Please check the type of change your PR introduces: --->
- [ ] 🌻 Feature
- [ ] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Test
- [x] 💻 CI/Deployment
- [ ] 🐹 Trivial/Minor

## Issue(s)

<!-- Can reference multiple issues. Use one of the following "magic words" - "closes, fixes" to auto-close the Github issue. -->
* https://github.com/alcionai/corso/issues/1166

## Test Plan

<!-- How will this be tested prior to merging.-->
- [x] 💪 Manual
- [ ]  Unit test
- [ ] 💚 E2E
2022-10-18 05:28:44 +00:00

82 lines
2.3 KiB
Bash
Executable File

#!/bin/bash
set -e
ROOT=$(dirname $(dirname $(readlink -f $0)))
GOVER=1.18 # go version
CORSO_BUILD_CACHE="/tmp/.corsobuild" # shared persistent cache
# Figure out os and architecture
case "$(uname -m)" in
x86_64) GOARCH="amd64" ;;
aarch64) GOARCH="arm64" ;;
arm) GOARCH="arm" ;;
i386) GOARCH="386" ;;
*) echo "Unknown architecture" && exit 0 ;;
esac
case "$(uname)" in
Linux) GOOS="linux" ;;
Darwin) GOOS="darwin" ;; # TODO: verify this
*) echo "Unknown OS" && exit 0 ;;
esac
PLATFORMS="$GOOS/$GOARCH" # default platform
TAG="alcionai/corso" # default image tag
usage() {
echo "Usage: $(basename $0) <binary|image> [--platforms ...] [--tag ...]"
echo ""
echo "OPTIONS"
echo " -p|--platforms Platforms to build for (default: $PLATFORMS)"
echo " Specify multiple platforms using ',' (eg: linux/amd64,darwin/arm)"
echo " -t|--tag Tag for container image (default: $TAG)"
}
MODE="binary"
case "$1" in
binary) MODE="binary" && shift ;;
image) MODE="image" && shift ;;
-h | --help) usage && exit 0 ;;
*) usage && exit 1 ;;
esac
while [ "$#" -gt 0 ]; do
case "$1" in
-p | --platforms) PLATFORMS="$2" && shift ;;
-t | --tag) TAG="$2" && shift ;;
*) echo "Invalid argument $1" && usage && exit 1 ;;
esac
shift
done
if [ "$MODE" == "binary" ]; then
mkdir -p ${CORSO_BUILD_CACHE} # prep env
for platform in ${PLATFORMS/,/ }; do
IFS='/' read -r -a platform_split <<<"$platform"
GOOS=${platform_split[0]}
GOARCH=${platform_split[1]}
printf "Building for %s...\r" "$platform"
docker run --rm \
--mount type=bind,src=${ROOT},dst="/app" \
--mount type=bind,src=${CORSO_BUILD_CACHE},dst=${CORSO_BUILD_CACHE} \
--env GOMODCACHE=${CORSO_BUILD_CACHE}/mod --env GOCACHE=${CORSO_BUILD_CACHE}/cache \
--env GOOS=${GOOS} --env GOARCH=${GOARCH} \
--workdir "/app/src" \
golang:${GOVER} \
go build -o corso -ldflags "${CORSO_BUILD_LDFLAGS}"
mkdir -p ${ROOT}/bin/${GOOS}-${GOARCH}
mv ${ROOT}/src/corso ${ROOT}/bin/${GOOS}-${GOARCH}/corso
echo Corso $platform binary available in ${ROOT}/bin/${GOOS}-${GOARCH}/corso
done
else
echo Building "$TAG" image for "$PLATFORMS"
docker buildx build --tag ${TAG} \
--platform ${PLATFORMS} \
--file ${ROOT}/build/Dockerfile \
--build-arg CORSO_BUILD_LDFLAGS="$CORSO_BUILD_LDFLAGS" \
--load ${ROOT}
echo Built container image "$TAG"
fi