mirror of https://github.com/coder/coder.git
230 lines
6.1 KiB
Bash
Executable File
230 lines
6.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# This script builds multiple Go binaries for Coder with the given OS and
|
|
# architecture combinations.
|
|
#
|
|
# Usage: ./build_go_matrix.sh [--version 1.2.3-devel+abcdef] [--output dist/] [--slim] [--sign-darwin] [--archive] [--package-linux] os1:arch1,arch2 os2:arch1 os1:arch3
|
|
#
|
|
# If no OS:arch combinations are provided, nothing will happen and no error will
|
|
# be returned. Slim builds are disabled by default. If no version is specified,
|
|
# defaults to the version from ./version.sh
|
|
#
|
|
# The --output parameter must be a directory with a trailing slash where all
|
|
# files will be dropped with the default name scheme
|
|
# `coder_$version_$os_$arch(.exe)?`, or must contain the `{os}` and `{arch}`
|
|
# template variables. You may also use `{version}`. Note that for windows builds
|
|
# the `.exe` suffix will be appended automatically.
|
|
#
|
|
# Unless overridden via --output, the built binary will be dropped in
|
|
# "$repo_root/dist/coder_$version_$os_$arch" (with a ".exe" suffix for windows
|
|
# builds).
|
|
#
|
|
# If the --sign-darwin parameter is specified, all darwin binaries will be
|
|
# signed using the `codesign` utility. $AC_APPLICATION_IDENTITY must be set and
|
|
# the signing certificate must be imported for this to work.
|
|
#
|
|
# If the --archive parameter is specified, all binaries will be archived using
|
|
# ./archive.sh. The --sign-darwin parameter will be carried through, and all
|
|
# archive files will be dropped in the output directory with the same name as
|
|
# the binary and the .zip (for windows and darwin) or .tar.gz extension.
|
|
#
|
|
# If the --package-linux parameter is specified, all linux binaries will be
|
|
# packaged using ./package.sh. Requires the nfpm binary.
|
|
|
|
set -euo pipefail
|
|
# shellcheck source=scripts/lib.sh
|
|
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
|
|
version=""
|
|
output_path=""
|
|
slim=0
|
|
sign_darwin=0
|
|
archive=0
|
|
package_linux=0
|
|
|
|
args="$(getopt -o "" -l version:,output:,slim,sign-darwin,archive,package-linux -- "$@")"
|
|
eval set -- "$args"
|
|
while true; do
|
|
case "$1" in
|
|
--version)
|
|
version="$2"
|
|
shift 2
|
|
;;
|
|
--output)
|
|
output_path="$2"
|
|
shift 2
|
|
;;
|
|
--slim)
|
|
slim=1
|
|
shift
|
|
;;
|
|
--sign-darwin)
|
|
if [[ "${AC_APPLICATION_IDENTITY:-}" == "" ]]; then
|
|
error "AC_APPLICATION_IDENTITY must be set when --sign-darwin is supplied"
|
|
fi
|
|
sign_darwin=1
|
|
shift
|
|
;;
|
|
--archive)
|
|
archive=1
|
|
shift
|
|
;;
|
|
--package-linux)
|
|
package_linux=1
|
|
shift
|
|
;;
|
|
--)
|
|
shift
|
|
break
|
|
;;
|
|
*)
|
|
error "Unrecognized option: $1"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Verify the output path template.
|
|
if [[ "$output_path" == "" ]]; then
|
|
# Input paths are relative, so we don't cdroot at the top, but for this case
|
|
# we want it to be relative to the root.
|
|
cdroot
|
|
mkdir -p dist
|
|
output_path="$(realpath "dist/coder_{version}_{os}_{arch}")"
|
|
elif [[ "$output_path" == */ ]]; then
|
|
output_path="${output_path}coder_{version}_{os}_{arch}"
|
|
elif [[ "$output_path" != *"{os}"* ]] || [[ "$output_path" != *"{arch}"* ]]; then
|
|
# If the output path isn't a directory (ends with /) then it must have
|
|
# template variables.
|
|
error "Templated output path '$output_path' must contain {os} and {arch}"
|
|
fi
|
|
|
|
mkdir -p "$(dirname "$output_path")"
|
|
output_path="$(realpath "$output_path")"
|
|
|
|
# Remove the "v" prefix.
|
|
version="${version#v}"
|
|
if [[ "$version" == "" ]]; then
|
|
version="$(execrelative ./version.sh)"
|
|
fi
|
|
|
|
# Parse the os:arch specs into an array.
|
|
specs=()
|
|
may_zip=0
|
|
may_tar=0
|
|
for spec in "$@"; do
|
|
spec_os="$(echo "$spec" | cut -d ":" -f 1)"
|
|
if [[ "$spec_os" == "" ]] || [[ "$spec_os" == *" "* ]]; then
|
|
error "Could not parse matrix build spec '$spec': invalid OS '$spec_os'"
|
|
fi
|
|
|
|
# Determine which dependencies we need.
|
|
if [[ "$spec_os" == "windows" ]] || [[ "$spec_os" == "darwin" ]]; then
|
|
may_zip=1
|
|
else
|
|
may_tar=1
|
|
fi
|
|
|
|
# No quoting is important here.
|
|
for spec_arch in $(echo "$spec" | cut -d ":" -f 2 | tr "," "\n"); do
|
|
if [[ "$spec_arch" == "" ]] || [[ "$spec_os" == *" "* ]]; then
|
|
error "Could not parse matrix build spec '$spec': invalid architecture '$spec_arch'"
|
|
fi
|
|
|
|
specs+=("$spec_os:$spec_arch")
|
|
done
|
|
done
|
|
|
|
# Remove duplicate specs while maintaining the same order.
|
|
specs_str="${specs[*]}"
|
|
specs=()
|
|
for s in $(echo "$specs_str" | tr " " "\n" | awk '!a[$0]++'); do
|
|
specs+=("$s")
|
|
done
|
|
|
|
# Check dependencies
|
|
dependencies go
|
|
if [[ "$sign_darwin" == 1 ]]; then
|
|
dependencies jq codesign gon
|
|
fi
|
|
if [[ "$archive" == 1 ]]; then
|
|
if [[ "$may_zip" == 1 ]]; then
|
|
dependencies zip
|
|
fi
|
|
if [[ "$may_tar" == 1 ]]; then
|
|
dependencies tar
|
|
fi
|
|
fi
|
|
if [[ "$package_linux" == 1 ]]; then
|
|
dependencies nfpm
|
|
fi
|
|
|
|
bin_name="coder"
|
|
build_args=()
|
|
if [[ "$slim" == 1 ]]; then
|
|
bin_name+="-slim"
|
|
build_args+=(--slim)
|
|
fi
|
|
if [[ "$sign_darwin" == 1 ]]; then
|
|
build_args+=(--sign-darwin)
|
|
fi
|
|
|
|
# Build each spec.
|
|
for spec in "${specs[@]}"; do
|
|
spec_os="$(echo "$spec" | cut -d ":" -f 1)"
|
|
spec_arch="$(echo "$spec" | cut -d ":" -f 2)"
|
|
|
|
# Craft output path from the template.
|
|
spec_output="$output_path"
|
|
spec_output="${spec_output//\{os\}/"$spec_os"}"
|
|
spec_output="${spec_output//\{arch\}/"$spec_arch"}"
|
|
spec_output="${spec_output//\{version\}/"$version"}"
|
|
|
|
spec_output_binary="$spec_output"
|
|
if [[ "$spec_os" == "windows" ]]; then
|
|
spec_output_binary+=".exe"
|
|
fi
|
|
|
|
# Ensure parent dir.
|
|
mkdir -p "$(dirname "$spec_output")"
|
|
|
|
log "--- Building $bin_name for $spec_os $spec_arch ($spec_output_binary)"
|
|
execrelative ./build_go.sh \
|
|
--version "$version" \
|
|
--os "$spec_os" \
|
|
--arch "$spec_arch" \
|
|
--output "$spec_output_binary" \
|
|
"${build_args[@]}"
|
|
log
|
|
log
|
|
|
|
if [[ "$archive" == 1 ]]; then
|
|
spec_archive_format="tar.gz"
|
|
if [[ "$spec_os" == "windows" ]] || [[ "$spec_os" == "darwin" ]]; then
|
|
spec_archive_format="zip"
|
|
fi
|
|
spec_output_archive="$spec_output.$spec_archive_format"
|
|
|
|
archive_args=()
|
|
if [[ "$sign_darwin" == 1 ]] && [[ "$spec_os" == "darwin" ]]; then
|
|
archive_args+=(--sign-darwin)
|
|
fi
|
|
|
|
log "--- Creating archive for $spec_os $spec_arch ($spec_output_archive)"
|
|
execrelative ./archive.sh \
|
|
--format "$spec_archive_format" \
|
|
--output "$spec_output_archive" \
|
|
"${archive_args[@]}" \
|
|
"$spec_output_binary"
|
|
log
|
|
log
|
|
fi
|
|
|
|
if [[ "$package_linux" == 1 ]] && [[ "$spec_os" == "linux" ]]; then
|
|
execrelative ./package.sh \
|
|
--arch "$spec_arch" \
|
|
--version "$version" \
|
|
"$spec_output_binary"
|
|
log
|
|
fi
|
|
done
|