Build, test and release with cargo: CI, release workflow, cross-build and packaging scripts, Homebrew
This commit is contained in:
Executable
+77
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build mapsize release binaries for the supported operating systems and
|
||||
# CPU architectures.
|
||||
#
|
||||
# scripts/build.sh # every target this host can build, into dist/
|
||||
# TARGETS="linux/amd64 darwin/arm64" scripts/build.sh
|
||||
# OUT=/tmp/bins scripts/build.sh
|
||||
#
|
||||
# Binaries are named mapsize-OS-ARCH[.exe]: stripped release builds from the
|
||||
# locked dependencies (Cargo.lock), with build paths remapped so the output
|
||||
# does not depend on where the tree lives. Linux binaries are static (musl).
|
||||
#
|
||||
# How each target is built, and what the host needs:
|
||||
# zig cargo-zigbuild and zig on PATH (Linux, Windows)
|
||||
# mac a Mac, or cargo-zigbuild and zig (macOS)
|
||||
# cross `cross` and Docker (FreeBSD, NetBSD)
|
||||
# A requested target the host cannot build is reported, the others are still
|
||||
# built, and the script exits non-zero. The release workflow
|
||||
# (.github/workflows/release.yml) builds every target on GitHub's runners.
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
root=$PWD
|
||||
|
||||
table() {
|
||||
# os/arch Rust target method
|
||||
cat <<-'EOF2'
|
||||
linux/amd64 x86_64-unknown-linux-musl zig
|
||||
linux/arm64 aarch64-unknown-linux-musl zig
|
||||
linux/386 i686-unknown-linux-musl zig
|
||||
linux/arm armv7-unknown-linux-musleabihf zig
|
||||
linux/riscv64 riscv64gc-unknown-linux-musl zig
|
||||
windows/amd64 x86_64-pc-windows-gnu zig
|
||||
windows/arm64 aarch64-pc-windows-gnullvm zig
|
||||
darwin/amd64 x86_64-apple-darwin mac
|
||||
darwin/arm64 aarch64-apple-darwin mac
|
||||
freebsd/amd64 x86_64-unknown-freebsd cross
|
||||
netbsd/amd64 x86_64-unknown-netbsd cross
|
||||
EOF2
|
||||
}
|
||||
|
||||
out=${OUT:-dist}
|
||||
targets=${TARGETS:-$(table | awk '{print $1}')}
|
||||
mkdir -p -- "$out"
|
||||
out=$(cd -- "$out" && pwd -P)
|
||||
case $out in
|
||||
/ | "$(cd ~ && pwd -P)" | "$root") echo "refusing OUT=$out: use a dedicated directory" >&2; exit 2 ;;
|
||||
esac
|
||||
export RUSTFLAGS="${RUSTFLAGS:-} --remap-path-prefix=$root=mapsize --remap-path-prefix=${CARGO_HOME:-$HOME/.cargo}=cargo"
|
||||
have() { command -v "$1" >/dev/null; }
|
||||
|
||||
status=0
|
||||
for want in $targets; do
|
||||
row=$(table | awk -v t="$want" '$1 == t')
|
||||
[[ -n $row ]] || { echo "UNKNOWN $want" >&2; status=1; continue; }
|
||||
read -r _ triple method <<<"$row"
|
||||
ext=; [[ $want == windows/* ]] && ext=.exe
|
||||
name=mapsize-${want/\//-}$ext
|
||||
case $method in
|
||||
zig) have cargo-zigbuild && have zig && cmd=(cargo zigbuild) ||
|
||||
{ echo "SKIPPED $want: needs cargo-zigbuild and zig" >&2; status=1; continue; } ;;
|
||||
mac)
|
||||
if [[ $(uname -s) == Darwin ]]; then cmd=(cargo build)
|
||||
elif have cargo-zigbuild && have zig; then cmd=(cargo zigbuild)
|
||||
else echo "SKIPPED $want: needs a Mac, or cargo-zigbuild and zig" >&2; status=1; continue; fi ;;
|
||||
cross) have cross && have docker && cmd=(cross build) ||
|
||||
{ echo "SKIPPED $want: needs cross and docker" >&2; status=1; continue; } ;;
|
||||
esac
|
||||
if ! "${cmd[@]}" --quiet --release --locked --target "$triple"; then
|
||||
echo "FAILED $want ($triple)" >&2; status=1; continue
|
||||
fi
|
||||
cp -- "target/$triple/release/mapsize$ext" "$out/$name"
|
||||
if [[ $triple == *-musl* ]] && have file; then
|
||||
file -L "$out/$name" | grep -q 'static' || { echo "FAILED $want: not statically linked" >&2; status=1; continue; }
|
||||
fi
|
||||
echo "built $name ($triple)"
|
||||
done
|
||||
exit $status
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run the pinned nfpm packager, downloading and checksumming it on first use
|
||||
# (into target/tools). Linux x86-64 and ARM64 hosts only.
|
||||
set -euo pipefail
|
||||
version=2.41.1
|
||||
case $(uname -m) in
|
||||
x86_64) arch=x86_64 sum=b3cf95aa6dabed836d09ad7f0c190a13c74c5b1304db60846f0f702ee407f430 ;;
|
||||
aarch64) arch=arm64 sum=17350a838c8e2c422c6e573ed379b18424565d2de8a2b1cb1b20211976124eb5 ;;
|
||||
*) echo "nfpm.sh: unsupported host $(uname -m)" >&2; exit 1 ;;
|
||||
esac
|
||||
dir=$(cd "$(dirname "$0")/.." && pwd)/target/tools/nfpm-$version
|
||||
if [[ ! -x $dir/nfpm ]]; then
|
||||
mkdir -p "$dir"
|
||||
tgz=$dir/nfpm.tar.gz
|
||||
curl -fsSL -o "$tgz" "https://github.com/goreleaser/nfpm/releases/download/v$version/nfpm_${version}_Linux_$arch.tar.gz"
|
||||
echo "$sum $tgz" | sha256sum -c --quiet
|
||||
tar -xzf "$tgz" -C "$dir" nfpm
|
||||
rm -f "$tgz"
|
||||
fi
|
||||
exec "$dir/nfpm" "$@"
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env bash
|
||||
# Turn the binaries from scripts/build.sh into release assets: one archive
|
||||
# per binary (with README, CHANGELOG, LICENSE and the manual page), .deb,
|
||||
# .rpm, .apk and Arch packages for the Linux binaries, and SHA256SUMS.
|
||||
#
|
||||
# scripts/release.sh VERSION [BIN_DIR [OUT_DIR]] # defaults: dist, dist/release
|
||||
#
|
||||
# VERSION (e.g. 1.3.0 or v1.3.0) must match Cargo.toml, which is what the
|
||||
# binaries report.
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
root=$PWD
|
||||
version=${1:?usage: scripts/release.sh VERSION [BIN_DIR [OUT_DIR]]}
|
||||
version=${version#v}
|
||||
bins=$(cd "${2:-dist}" && pwd)
|
||||
out=${3:-dist/release}
|
||||
cargo_version=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -1)
|
||||
[[ $version == "$cargo_version" ]] || { echo "release: VERSION $version does not match Cargo.toml ($cargo_version)" >&2; exit 1; }
|
||||
rm -rf -- "$out" && mkdir -p -- "$out"
|
||||
out=$(cd "$out" && pwd)
|
||||
work=$(mktemp -d)
|
||||
trap 'rm -rf -- "$work"' EXIT
|
||||
|
||||
shopt -s nullglob
|
||||
for bin in "$bins"/mapsize-*; do
|
||||
b=$(basename "$bin")
|
||||
osarch=${b#mapsize-}
|
||||
osarch=${osarch%.exe}
|
||||
os=${osarch%-*} arch=${osarch#*-}
|
||||
ext=; [[ $os == windows ]] && ext=.exe
|
||||
name=mapsize-$version-$os-$arch
|
||||
mkdir -p "$work/$name"
|
||||
install -m 0755 "$bin" "$work/$name/mapsize$ext"
|
||||
cp README.md CHANGELOG.md LICENSE docs/mapsize.1 "$work/$name/"
|
||||
if [[ $os == windows ]]; then (cd "$work" && zip -qr "$out/$name.zip" "$name")
|
||||
else tar -C "$work" -czf "$out/$name.tar.gz" "$name"; fi
|
||||
if [[ $os == linux ]]; then
|
||||
nfarch=$arch; [[ $arch == arm ]] && nfarch=arm7
|
||||
cat >"$work/nfpm-$arch.yaml" <<-EOF2
|
||||
name: mapsize
|
||||
arch: $nfarch
|
||||
platform: linux
|
||||
version: $version
|
||||
release: 1
|
||||
maintainer: Andy Dixon <andy@dixon.cx>
|
||||
description: Interactive full-terminal disk usage analyser with a live treemap.
|
||||
homepage: https://github.com/andydixon/mapsize
|
||||
license: GPL-3.0-or-later
|
||||
contents:
|
||||
- src: $work/$name/mapsize
|
||||
dst: /usr/bin/mapsize
|
||||
file_info: {mode: 0755}
|
||||
- src: $root/docs/mapsize.1
|
||||
dst: /usr/share/man/man1/mapsize.1
|
||||
file_info: {mode: 0644}
|
||||
EOF2
|
||||
for fmt in deb rpm apk archlinux; do
|
||||
scripts/nfpm.sh pkg -f "$work/nfpm-$arch.yaml" -p $fmt -t "$out/" >/dev/null
|
||||
done
|
||||
fi
|
||||
done
|
||||
(cd "$out" && sha256sum -- * >SHA256SUMS)
|
||||
echo "$(($(ls "$out" | wc -l) - 1)) assets and SHA256SUMS in $out"
|
||||
Reference in New Issue
Block a user