# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/release-go-task/DistTasks.yml
version: "3"

# This taskfile is ideally meant to be project agnostic and could be dropped in
# on other Go projects with minimal or no changes.
#
# To use it simply add the following lines to your main taskfile:
#   includes:
#     dist: ./DistTasks.yml
#
# The following variables must be declared in the including taskfile for the
# build process to work correctly:
# * DIST_DIR: the folder that will contain the final binaries and packages
# * PROJECT_NAME: the name of the project, used in package name
# * VERSION: the version of the project, used in package name and checksum file
# * LD_FLAGS: flags used at build time
#
# The project MUST contain a LICENSE.txt file in the root folder or packaging will fail.

vars:
  CONTAINER: "docker.elastic.co/beats-dev/golang-crossbuild"
  GO_VERSION: "1.17.8"
  CHECKSUM_FILE: "{{.VERSION}}-checksums.txt"

tasks:
  all:
    desc: Build for distribution for all platforms
    cmds:
      - task: Windows_32bit
      - task: Windows_64bit
      - task: Linux_32bit
      - task: Linux_64bit
      - task: Linux_ARMv6
      - task: Linux_ARMv7
      - task: Linux_ARM64
      - task: macOS_64bit
      - task: macOS_ARM64

  Windows_32bit:
    desc: Builds Windows 32 bit binaries
    dir: "{{.DIST_DIR}}"
    cmds:
      - |
        docker run -v `pwd`/..:/home/build -w /home/build \
        -e CGO_ENABLED=0 \
        {{.CONTAINER}}:{{.CONTAINER_TAG}} \
        --build-cmd "{{.BUILD_COMMAND}}" \
        -p "{{.BUILD_PLATFORM}}"

        zip {{.PACKAGE_NAME}} {{.PLATFORM_DIR}}/{{.PROJECT_NAME}}.exe ../LICENSE.txt -j
        sha256sum {{.PACKAGE_NAME}} >> {{.CHECKSUM_FILE}}

    vars:
      PLATFORM_DIR: "{{.PROJECT_NAME}}_windows_386"
      BUILD_COMMAND: "go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}}.exe {{.LDFLAGS}}"
      BUILD_PLATFORM: "windows/386"
      CONTAINER_TAG: "{{.GO_VERSION}}-main"
      PACKAGE_PLATFORM: "Windows_32bit"
      PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.zip"

  Windows_64bit:
    desc: Builds Windows 64 bit binaries
    dir: "{{.DIST_DIR}}"
    cmds:
      - |
        docker run -v `pwd`/..:/home/build -w /home/build \
        -e CGO_ENABLED=0 \
        {{.CONTAINER}}:{{.CONTAINER_TAG}} \
        --build-cmd "{{.BUILD_COMMAND}}" \
        -p "{{.BUILD_PLATFORM}}"

        zip {{.PACKAGE_NAME}} {{.PLATFORM_DIR}}/{{.PROJECT_NAME}}.exe ../LICENSE.txt -j
        sha256sum {{.PACKAGE_NAME}} >> {{.CHECKSUM_FILE}}

    vars:
      PLATFORM_DIR: "{{.PROJECT_NAME}}_windows_amd64"
      BUILD_COMMAND: "go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}}.exe {{.LDFLAGS}}"
      BUILD_PLATFORM: "windows/amd64"
      CONTAINER_TAG: "{{.GO_VERSION}}-main"
      PACKAGE_PLATFORM: "Windows_64bit"
      PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.zip"

  Linux_32bit:
    desc: Builds Linux 32 bit binaries
    dir: "{{.DIST_DIR}}"
    cmds:
      - |
        docker run -v `pwd`/..:/home/build -w /home/build \
        -e CGO_ENABLED=0 \
        {{.CONTAINER}}:{{.CONTAINER_TAG}} \
        --build-cmd "{{.BUILD_COMMAND}}" \
        -p "{{.BUILD_PLATFORM}}"

        tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt  -f {{.PACKAGE_NAME}}
        sha256sum {{.PACKAGE_NAME}} >> {{.CHECKSUM_FILE}}

    vars:
      PLATFORM_DIR: "{{.PROJECT_NAME}}_linux_amd32"
      BUILD_COMMAND: "go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}}"
      BUILD_PLATFORM: "linux/386"
      CONTAINER_TAG: "{{.GO_VERSION}}-main"
      PACKAGE_PLATFORM: "Linux_32bit"
      PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz"

  Linux_64bit:
    desc: Builds Linux 64 bit binaries
    dir: "{{.DIST_DIR}}"
    cmds:
      - |
        docker run -v `pwd`/..:/home/build -w /home/build \
        -e CGO_ENABLED=0 \
        {{.CONTAINER}}:{{.CONTAINER_TAG}} \
        --build-cmd "{{.BUILD_COMMAND}}" \
        -p "{{.BUILD_PLATFORM}}"

        tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt  -f {{.PACKAGE_NAME}}
        sha256sum {{.PACKAGE_NAME}} >> {{.CHECKSUM_FILE}}

    vars:
      PLATFORM_DIR: "{{.PROJECT_NAME}}_linux_amd64"
      BUILD_COMMAND: "go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}}"
      BUILD_PLATFORM: "linux/amd64"
      CONTAINER_TAG: "{{.GO_VERSION}}-main"
      PACKAGE_PLATFORM: "Linux_64bit"
      PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz"

  Linux_ARMv7:
    desc: Builds Linux ARMv7 binaries
    dir: "{{.DIST_DIR}}"
    cmds:
      - |
        docker run -v `pwd`/..:/home/build -w /home/build \
        -e CGO_ENABLED=0 \
        {{.CONTAINER}}:{{.CONTAINER_TAG}} \
        --build-cmd "{{.BUILD_COMMAND}}" \
        -p "{{.BUILD_PLATFORM}}"

        tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt  -f {{.PACKAGE_NAME}}
        sha256sum {{.PACKAGE_NAME}} >> {{.CHECKSUM_FILE}}

    vars:
      PLATFORM_DIR: "{{.PROJECT_NAME}}_linux_arm_7"
      BUILD_COMMAND: "go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}}"
      BUILD_PLATFORM: "linux/armv7"
      CONTAINER_TAG: "{{.GO_VERSION}}-armhf"
      PACKAGE_PLATFORM: "Linux_ARMv7"
      PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz"

  Linux_ARMv6:
    desc: Builds Linux ARMv6 binaries
    dir: "{{.DIST_DIR}}"
    cmds:
      - |
        docker run -v `pwd`/..:/home/build -w /home/build \
        -e CGO_ENABLED=0 \
        {{.CONTAINER}}:{{.CONTAINER_TAG}} \
        --build-cmd "{{.BUILD_COMMAND}}" \
        -p "{{.BUILD_PLATFORM}}"

        tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt  -f {{.PACKAGE_NAME}}
        sha256sum {{.PACKAGE_NAME}} >> {{.CHECKSUM_FILE}}

    vars:
      PLATFORM_DIR: "{{.PROJECT_NAME}}_linux_arm_6"
      BUILD_COMMAND: "go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}}"
      BUILD_PLATFORM: "linux/armv6"
      # We are experiencing the following error with ARMv6 build:
      #
      #   # github.com/arduino/arduino-cli
      #   net(.text): unexpected relocation type 296 (R_ARM_V4BX)
      #   panic: runtime error: invalid memory address or nil pointer dereference
      #   [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x51ae53]
      #
      #   goroutine 1 [running]:
      #   cmd/link/internal/loader.(*Loader).SymName(0xc000095c00, 0x0, 0xc0000958d8, 0x5a0ac)
      #           /usr/local/go/src/cmd/link/internal/loader/loader.go:684 +0x53
      #   cmd/link/internal/ld.dynrelocsym2(0xc000095880, 0x5a0ac)
      #           /usr/local/go/src/cmd/link/internal/ld/data.go:777 +0x295
      #   cmd/link/internal/ld.(*dodataState).dynreloc2(0xc007df9800, 0xc000095880)
      #           /usr/local/go/src/cmd/link/internal/ld/data.go:794 +0x89
      #   cmd/link/internal/ld.(*Link).dodata2(0xc000095880, 0xc007d00000, 0x60518, 0x60518)
      #           /usr/local/go/src/cmd/link/internal/ld/data.go:1434 +0x4d4
      #   cmd/link/internal/ld.Main(0x8729a0, 0x4, 0x8, 0x1, 0xd, 0xe, 0x0, 0x0, 0x6d7737, 0x12, ...)
      #           /usr/local/go/src/cmd/link/internal/ld/main.go:302 +0x123a
      #   main.main()
      #           /usr/local/go/src/cmd/link/main.go:68 +0x1dc
      #   Error: failed building for linux/armv6: exit status 2
      #
      # This seems to be a problem in the go builder 1.16.x that removed support for the R_ARM_V4BX instruction:
      #    https://github.com/golang/go/pull/44998
      #    https://groups.google.com/g/golang-codereviews/c/yzN80xxwu2E
      #
      # Until there is a fix released we must use a recent gcc for Linux_ARMv6 build, so for this
      # build we select the debian10 based container.
      CONTAINER_TAG: "{{.GO_VERSION}}-armel-debian10"
      PACKAGE_PLATFORM: "Linux_ARMv6"
      PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz"

  Linux_ARM64:
    desc: Builds Linux ARM64 binaries
    dir: "{{.DIST_DIR}}"
    cmds:
      - |
        docker run -v `pwd`/..:/home/build -w /home/build \
        -e CGO_ENABLED=0 \
        {{.CONTAINER}}:{{.CONTAINER_TAG}} \
        --build-cmd "{{.BUILD_COMMAND}}" \
        -p "{{.BUILD_PLATFORM}}"

        tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt  -f {{.PACKAGE_NAME}}
        sha256sum {{.PACKAGE_NAME}} >> {{.CHECKSUM_FILE}}

    vars:
      PLATFORM_DIR: "{{.PROJECT_NAME}}_linux_arm_6"
      BUILD_COMMAND: "go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}}"
      BUILD_PLATFORM: "linux/arm64"
      CONTAINER_TAG: "{{.GO_VERSION}}-arm"
      PACKAGE_PLATFORM: "Linux_ARM64"
      PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz"

  macOS_64bit:
    desc: Builds Mac OS X 64 bit binaries
    dir: "{{.DIST_DIR}}"
    cmds:
      - |
        docker run -v `pwd`/..:/home/build -w /home/build \
        -e CGO_ENABLED=1 \
        {{.CONTAINER}}:{{.CONTAINER_TAG}} \
        --build-cmd "{{.BUILD_COMMAND}}" \
        -p "{{.BUILD_PLATFORM}}"

        tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt  -f {{.PACKAGE_NAME}}
        sha256sum {{.PACKAGE_NAME}} >> {{.CHECKSUM_FILE}}

    vars:
      PLATFORM_DIR: "{{.PROJECT_NAME}}_osx_darwin_amd64"
      BUILD_COMMAND: "go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}}"
      BUILD_PLATFORM: "darwin/amd64"
      # We are experiencing the following error with macOS_64bit build:
      #
      #   Undefined symbols for architecture x86_64:
      #     "_clock_gettime", referenced from:
      #         _runtime.walltime_trampoline in go.o
      #   ld: symbol(s) not found for architecture x86_64
      #   clang: error: linker command failed with exit code 1 (use -v to see invocation)
      #
      # The reason seems that go 1.16.x use a macos API which is available since 10.12
      #    https://github.com/techknowlogick/xgo/issues/100#issuecomment-780894190
      #
      # To compile it we need an SDK >=10.12 so we use the debian10 based container that
      # has the SDK 10.14 installed.
      CONTAINER_TAG: "{{.GO_VERSION}}-darwin-debian10"
      PACKAGE_PLATFORM: "macOS_64bit"
      PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz"

  macOS_ARM64:
    desc: Builds Mac OS X ARM64 binaries
    dir: "{{.DIST_DIR}}"
    cmds:
      - |
        docker run -v `pwd`/..:/home/build -w /home/build \
        -e CGO_ENABLED=1 \
        {{.CONTAINER}}:{{.CONTAINER_TAG}} \
        --build-cmd "{{.BUILD_COMMAND}}" \
        -p "{{.BUILD_PLATFORM}}"

        tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt  -f {{.PACKAGE_NAME}}
        sha256sum {{.PACKAGE_NAME}} >> {{.CHECKSUM_FILE}}

    vars:
      PLATFORM_DIR: "{{.PROJECT_NAME}}_osx_darwin_arm64"
      BUILD_COMMAND: "go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}}"
      BUILD_PLATFORM: "darwin/arm64"
      CONTAINER_TAG: "{{.GO_VERSION}}-darwin-arm64-debian10"
      PACKAGE_PLATFORM: "macOS_ARM64"
      PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz"
