139 lines
4.7 KiB
Bash
Executable File
139 lines
4.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
# Builds release artefacts: static binaries for each target platform, one
|
|
# tarball per binary and platform (binary, its systemd unit for
|
|
# /usr/local/bin, LICENSE and LICENSES/), and SHA256SUMS.
|
|
#
|
|
# Usage: scripts/build-release.sh [-o OUTDIR] [-p "linux/amd64 linux/arm64"]
|
|
#
|
|
# Names and version come from the environment (set by the Makefile, ADR 0018):
|
|
# VERSION, COMMIT, BUILD_DATE, PRODUCT, DISPLAY_NAME,
|
|
# BIN_SERVER, BIN_AGENT_DNS, BIN_AGENT_DHCP, KEYGEN_ACCOUNT_ID, KEYGEN_PUBLIC_KEY
|
|
# The web UI must be built beforehand (make web); the script refuses to build
|
|
# a server release without it.
|
|
|
|
set -euo pipefail
|
|
|
|
readonly MODULE="git.beugsiud.de/beug.k/DDI"
|
|
|
|
PRODUCT="${PRODUCT:-ddi-suite}"
|
|
DISPLAY_NAME="${DISPLAY_NAME:-DDI-Suite}"
|
|
BIN_SERVER="${BIN_SERVER:-ddi-server}"
|
|
BIN_AGENT_DNS="${BIN_AGENT_DNS:-ddi-agent-dns}"
|
|
BIN_AGENT_DHCP="${BIN_AGENT_DHCP:-ddi-agent-dhcp}"
|
|
KEYGEN_ACCOUNT_ID="${KEYGEN_ACCOUNT_ID:?KEYGEN_ACCOUNT_ID must be set (see Makefile)}"
|
|
KEYGEN_PUBLIC_KEY="${KEYGEN_PUBLIC_KEY:?KEYGEN_PUBLIC_KEY must be set (see Makefile)}"
|
|
|
|
outdir="dist"
|
|
platforms="linux/amd64 linux/arm64"
|
|
|
|
usage() {
|
|
sed -n '4,14p' "$0" | sed 's/^# \{0,1\}//'
|
|
}
|
|
|
|
while getopts ":o:p:h" opt; do
|
|
case "$opt" in
|
|
o) outdir="$OPTARG" ;;
|
|
p) platforms="$OPTARG" ;;
|
|
h)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
usage >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
done
|
|
|
|
cd "$(git rev-parse --show-toplevel)"
|
|
|
|
VERSION="${VERSION:-$(git describe --tags --always --dirty 2>/dev/null || echo dev)}"
|
|
COMMIT="${COMMIT:-$(git rev-parse HEAD 2>/dev/null || echo unknown)}"
|
|
# Commit time keeps builds reproducible.
|
|
BUILD_DATE="${BUILD_DATE:-$(git log -1 --format=%cI 2>/dev/null || date -u +%Y-%m-%dT%H:%M:%SZ)}"
|
|
|
|
if [[ ! -f web/dist/index.html ]]; then
|
|
echo "web/dist/index.html missing: build the web UI first (make web)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
for value in "$VERSION" "$COMMIT" "$BUILD_DATE" "$PRODUCT" "$DISPLAY_NAME" \
|
|
"$BIN_SERVER" "$BIN_AGENT_DNS" "$BIN_AGENT_DHCP"; do
|
|
if [[ "$value" == *"'"* ]]; then
|
|
echo "build variables must not contain single quotes: ${value}" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
# -X values are single-quoted so that names may contain spaces; go build
|
|
# splits -ldflags with shell-like quoting.
|
|
ldflags="-s -w"
|
|
add_x() { ldflags+=" -X '${MODULE}/$1=$2'"; }
|
|
add_x internal/buildinfo.Version "$VERSION"
|
|
add_x internal/buildinfo.Commit "$COMMIT"
|
|
add_x internal/buildinfo.Date "$BUILD_DATE"
|
|
add_x internal/brand.Product "$PRODUCT"
|
|
add_x internal/brand.DisplayName "$DISPLAY_NAME"
|
|
add_x internal/brand.ServerBinary "$BIN_SERVER"
|
|
add_x internal/brand.AgentDNSBinary "$BIN_AGENT_DNS"
|
|
add_x internal/brand.AgentDHCPBinary "$BIN_AGENT_DHCP"
|
|
add_x internal/brand.ConfigDir "/etc/${PRODUCT}"
|
|
add_x internal/brand.StateDir "/var/lib/${PRODUCT}"
|
|
add_x internal/brand.LogDir "/var/log/${PRODUCT}"
|
|
# Only the server links the license package; the agents ignore these flags.
|
|
add_x server/internal/license.EmbeddedAccountID "$KEYGEN_ACCOUNT_ID"
|
|
add_x server/internal/license.EmbeddedPublicKey "$KEYGEN_PUBLIC_KEY"
|
|
|
|
# binary name -> package
|
|
declare -A packages=(
|
|
["$BIN_SERVER"]="./server/cmd/ddi-server"
|
|
["$BIN_AGENT_DNS"]="./agent/cmd/ddi-agent-dns"
|
|
["$BIN_AGENT_DHCP"]="./agent/cmd/ddi-agent-dhcp"
|
|
)
|
|
|
|
workdir="$(mktemp -d)"
|
|
trap 'rm -rf "$workdir"' EXIT
|
|
|
|
rm -rf "$outdir"
|
|
mkdir -p "$outdir"
|
|
|
|
# systemd units for binaries in /usr/local/bin (ADR 0024); each tarball
|
|
# carries the unit of its binary.
|
|
units="${workdir}/units"
|
|
scripts/render-units.sh /usr/local/bin "$units"
|
|
|
|
for platform in $platforms; do
|
|
goos="${platform%/*}"
|
|
goarch="${platform#*/}"
|
|
for bin in "$BIN_SERVER" "$BIN_AGENT_DNS" "$BIN_AGENT_DHCP"; do
|
|
name="${bin}_${VERSION}_${goos}_${goarch}"
|
|
stage="${workdir}/${name}"
|
|
mkdir -p "$stage"
|
|
|
|
echo "building ${name}"
|
|
CGO_ENABLED=0 GOOS="$goos" GOARCH="$goarch" \
|
|
go build -trimpath -buildvcs=false -ldflags "$ldflags" \
|
|
-o "${stage}/${bin}" "${packages[$bin]}"
|
|
|
|
# Unit and license texts: LICENSE says which license covers what
|
|
# (the server is proprietary, the unit files are Apache-2.0).
|
|
cp "${units}/${bin}.service" "${stage}/${bin}.service"
|
|
cp LICENSE "${stage}/LICENSE"
|
|
mkdir -p "${stage}/LICENSES"
|
|
cp LICENSES/*.txt "${stage}/LICENSES/"
|
|
chmod 0755 "${stage}" "${stage}/LICENSES" "${stage}/${bin}"
|
|
chmod 0644 "${stage}/${bin}.service" "${stage}/LICENSE" "${stage}/LICENSES/"*.txt
|
|
|
|
# Reproducible tarball: fixed order, owner and timestamps.
|
|
tar --sort=name --owner=0 --group=0 --numeric-owner \
|
|
--mtime="$BUILD_DATE" -C "$workdir" -cf - "$name" |
|
|
gzip -n -9 >"${outdir}/${name}.tar.gz"
|
|
done
|
|
done
|
|
|
|
(cd "$outdir" && sha256sum -- *.tar.gz >SHA256SUMS)
|
|
echo "artefacts in ${outdir}:"
|
|
cat "${outdir}/SHA256SUMS"
|