mirror of
https://seed.radicle.dev/rad:z39mP9rQAaGmERfUMPULfPUi473tY.git
synced 2026-10-18 19:10:36 +08:00
chore: Move to local release builds
Introduce a new local build system based on `cargo zigbuild`. It's a generalized version of the heartwood build system, which aims to be moved into its own repository at some point.
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
[target.aarch64-unknown-linux-gnu]
|
||||
linker = "aarch64-linux-gnu-gcc"
|
||||
@@ -1,93 +0,0 @@
|
||||
name: Binaries
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
tags: ["*"]
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
release-linux-binaries:
|
||||
permissions:
|
||||
contents: "read"
|
||||
id-token: "write"
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
target: [x86_64-unknown-linux-gnu, x86_64-unknown-linux-musl, aarch64-unknown-linux-gnu, aarch64-unknown-linux-musl]
|
||||
include:
|
||||
- target: x86_64-unknown-linux-gnu
|
||||
- target: aarch64-unknown-linux-gnu
|
||||
dependencies: gcc-aarch64-linux-gnu
|
||||
- target: x86_64-unknown-linux-musl
|
||||
dependencies: musl-tools
|
||||
docker: registry.gitlab.com/rust_musl_docker/image:stable-latest
|
||||
options: -v /home/runner/work/radicle-tui/radicle-tui:/workdir -v /home/runner/.cargo/git:/root/.cargo/git -v /home/runner/.cargo/registry:/root/.cargo/registry
|
||||
- target: aarch64-unknown-linux-musl
|
||||
docker: messense/rust-musl-cross:aarch64-musl
|
||||
options: -v /home/runner/work/radicle-tui/radicle-tui:/home/rust/src -v /home/runner/.cargo/git:/root/.cargo/git -v /home/runner/.cargo/registry:/root/.cargo/registry
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v4
|
||||
- name: Configure build cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
key: cargo-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
- uses: dtolnay/rust-toolchain@1.80
|
||||
- name: Build release binaries
|
||||
if: contains(matrix.target, 'gnu')
|
||||
run: |
|
||||
sudo apt-get update --yes && sudo apt-get install --yes ${{ matrix.dependencies }}
|
||||
rustup target add "${{ matrix.target }}"
|
||||
cargo build --release --target "${{ matrix.target }}"
|
||||
- name: Build release binaries (statically linked)
|
||||
if: contains(matrix.target, 'musl')
|
||||
uses: addnab/docker-run-action@v3
|
||||
with:
|
||||
image: ${{ matrix.docker }}
|
||||
options: ${{ matrix.options }}
|
||||
run: |
|
||||
rustup target add "${{ matrix.target }}"
|
||||
cargo build --release --target "${{ matrix.target }}"
|
||||
- name: Upload release binaries
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: radicle-tui_${{ github.ref_name }}_${{ matrix.target }}
|
||||
path: target/${{ matrix.target }}/release/rad-tui
|
||||
|
||||
release-macos-binaries:
|
||||
permissions:
|
||||
contents: "read"
|
||||
id-token: "write"
|
||||
runs-on: macos-13
|
||||
strategy:
|
||||
matrix:
|
||||
target:
|
||||
- aarch64-apple-darwin
|
||||
- x86_64-apple-darwin
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Configure build cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
key: cargo-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
- uses: dtolnay/rust-toolchain@1.77
|
||||
- name: Build release binaries
|
||||
run: |
|
||||
rustup target add "${{ matrix.target }}"
|
||||
cargo build --release --target "${{ matrix.target }}"
|
||||
- name: Upload release binaries
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: radicle-tui_${{ github.ref_name }}_${{ matrix.target }}
|
||||
path: target/${{ matrix.target }}/release/rad-tui
|
||||
@@ -3,3 +3,6 @@
|
||||
|
||||
# Nix
|
||||
/result
|
||||
|
||||
# Release
|
||||
build/artifacts
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
x86_64-unknown-linux-musl
|
||||
aarch64-unknown-linux-musl
|
||||
x86_64-apple-darwin
|
||||
aarch64-apple-darwin
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
main() {
|
||||
export PACKAGE_NAME="radicle-tui"
|
||||
export BINARY_NAME="rad-tui"
|
||||
export CONFIG_PATH="build/config.toml"
|
||||
export TARGETS_PATH="build/TARGETS"
|
||||
export OUTDIR="build/artifacts"
|
||||
export VERSION_CMD_ARGS="--no-forward"
|
||||
|
||||
build/radicle-build/build
|
||||
}
|
||||
|
||||
# Run build.
|
||||
main "$@"
|
||||
@@ -0,0 +1,13 @@
|
||||
[target.x86_64-unknown-linux-musl]
|
||||
rustflags = [
|
||||
"-C", "codegen-units=1",
|
||||
"-C", "incremental=false",
|
||||
"-C", "opt-level=3",
|
||||
]
|
||||
|
||||
[target.aarch64-unknown-linux-musl]
|
||||
rustflags = [
|
||||
"-C", "codegen-units=1",
|
||||
"-C", "incremental=false",
|
||||
"-C", "opt-level=3",
|
||||
]
|
||||
@@ -0,0 +1,91 @@
|
||||
# Builds release binaries for Radicle.
|
||||
ARG RUST_VERSION="1.85"
|
||||
ARG ALPINE_VERSION="3.20"
|
||||
|
||||
FROM rust:${RUST_VERSION}-alpine${ALPINE_VERSION} as builder
|
||||
LABEL maintainer="Erik Kundt <erik@zirkular.io>"
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
|
||||
ARG TZ
|
||||
ARG LC_ALL
|
||||
ARG SOURCE_DATE_EPOCH
|
||||
ARG PACKAGE_NAME
|
||||
ARG BINARY_NAME
|
||||
ARG VERSION
|
||||
ARG GIT_HEAD
|
||||
ARG SDK_PATH
|
||||
ARG CONFIG_PATH
|
||||
|
||||
# Copy cargo configuration we're going to use to specify compiler options.
|
||||
RUN mkdir -p .cargo && cp "$CONFIG_PATH" .cargo/config.toml
|
||||
# Install dependencies.
|
||||
RUN apk update && apk add --no-cache git musl-dev xz zig
|
||||
# Add cargo targets.
|
||||
RUN rustup target add \
|
||||
x86_64-unknown-linux-musl \
|
||||
aarch64-unknown-linux-musl \
|
||||
x86_64-apple-darwin \
|
||||
aarch64-apple-darwin
|
||||
|
||||
# Install dependencies for cross-compiling to macOS.
|
||||
# We use Zig as the linker to perform the compilation from a Linux host.
|
||||
# Zig is not yet available on Debian, so we download the official binary.
|
||||
# Compilation is done via `cargo-zigbuild` which is a wrapper around `zig`.
|
||||
RUN cargo install --locked cargo-zigbuild@0.20.0
|
||||
|
||||
|
||||
# Parts of the macOS SDK are required to build Radicle, we make these available
|
||||
# here. So far only `CoreFoundation` and `Security` frameworks are needed.
|
||||
RUN xz -d -c "$SDK_PATH" | tar -x
|
||||
# This env var is used by `cargo-zigbuild` to find the SDK.
|
||||
ENV SDKROOT /src/macos-sdk-11.3
|
||||
|
||||
# Build binaries.
|
||||
RUN cargo zigbuild --locked --release \
|
||||
--target=x86_64-apple-darwin \
|
||||
--target=aarch64-apple-darwin \
|
||||
--target=aarch64-unknown-linux-musl \
|
||||
--target=x86_64-unknown-linux-musl \
|
||||
-p "$PACKAGE_NAME"
|
||||
|
||||
# Now copy the files to a new image without all the intermediary artifacts to
|
||||
# save some space.
|
||||
FROM alpine:3.20 as packager
|
||||
|
||||
ARG VERSION
|
||||
ARG SOURCE_DATE_EPOCH
|
||||
ARG PACKAGE_NAME
|
||||
ARG BINARY_NAME
|
||||
|
||||
COPY --from=builder \
|
||||
/src/target/x86_64-unknown-linux-musl/release/${BINARY_NAME} \
|
||||
/builds/x86_64-unknown-linux-musl/bin/
|
||||
COPY --from=builder \
|
||||
/src/target/aarch64-unknown-linux-musl/release/${BINARY_NAME} \
|
||||
/builds/aarch64-unknown-linux-musl/bin/
|
||||
COPY --from=builder \
|
||||
/src/target/aarch64-apple-darwin/release/${BINARY_NAME} \
|
||||
/builds/aarch64-apple-darwin/bin/
|
||||
COPY --from=builder \
|
||||
/src/target/x86_64-apple-darwin/release/${BINARY_NAME} \
|
||||
/builds/x86_64-apple-darwin/bin/
|
||||
|
||||
# Create and compress reproducible archive.
|
||||
WORKDIR /builds
|
||||
RUN apk update && apk add --no-cache tar xz
|
||||
RUN find * -maxdepth 0 -type d -exec mv '{}' "$PACKAGE_NAME-$VERSION-{}" \; && \
|
||||
find * -maxdepth 0 -type d -exec tar \
|
||||
--sort=name \
|
||||
--verbose \
|
||||
--mtime="@$SOURCE_DATE_EPOCH" \
|
||||
--owner=0 \
|
||||
--group=0 \
|
||||
--numeric-owner \
|
||||
--format=posix \
|
||||
--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime \
|
||||
--mode='go+u,go-w' \
|
||||
--remove-files \
|
||||
--create --xz \
|
||||
--file="{}.tar.xz" \
|
||||
'{}' \;
|
||||
Executable
+100
@@ -0,0 +1,100 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
main() {
|
||||
# Use UTC time for everything.
|
||||
export TZ=UTC0
|
||||
# Set minimal locale.
|
||||
export LC_ALL=C
|
||||
# Set source date. This is honored by `asciidoctor` and other tools.
|
||||
SOURCE_DATE_EPOCH="$(git log -1 --pretty=%ct)"
|
||||
export SOURCE_DATE_EPOCH
|
||||
|
||||
if ! command -v rad > /dev/null; then
|
||||
echo "fatal: rad is not installed" >&2 ; exit 1
|
||||
fi
|
||||
|
||||
if ! command -v podman > /dev/null; then
|
||||
echo "fatal: podman is not installed" >&2 ; exit 1
|
||||
fi
|
||||
|
||||
if ! command -v sha256sum > /dev/null; then
|
||||
echo "fatal: sha256sum is not installed" >&2 ; exit 1
|
||||
fi
|
||||
|
||||
dir=$(dirname "${BASH_SOURCE[0]}")
|
||||
version="$("$dir/version")"
|
||||
rev="$(git rev-parse HEAD)"
|
||||
gitarchive="$OUTDIR/$PACKAGE_NAME-$rev.tar.gz"
|
||||
keypath="$(rad path)/keys/radicle.pub"
|
||||
image=radicle-build-$version
|
||||
rust_version="$("$dir/rust-version")"
|
||||
sdk_path="$dir/macos-sdk-11.3.tar.xz"
|
||||
|
||||
if [ ! -f "$keypath" ]; then
|
||||
echo "fatal: no key found at $keypath" >&2 ; exit 1
|
||||
fi
|
||||
# Authenticate user for signing
|
||||
rad auth
|
||||
|
||||
# Create output directory
|
||||
mkdir -p $OUTDIR
|
||||
|
||||
echo "Building $PACKAGE_NAME $version.."
|
||||
echo "Creating archive of repository at $rev in $gitarchive.."
|
||||
git archive --format tar.gz -o "$gitarchive" HEAD
|
||||
|
||||
echo "Building image ($image).."
|
||||
podman --cgroup-manager=cgroupfs build \
|
||||
--build-arg "RUST_VERSION=$rust_version" \
|
||||
--build-arg SOURCE_DATE_EPOCH \
|
||||
--build-arg TZ \
|
||||
--build-arg LC_ALL \
|
||||
--build-arg "PACKAGE_NAME=$PACKAGE_NAME" \
|
||||
--build-arg "BINARY_NAME=$BINARY_NAME" \
|
||||
--build-arg "VERSION=$version" \
|
||||
--build-arg "VERSION_CMD_ARGS=$VERSION_CMD_ARGS" \
|
||||
--build-arg "GIT_HEAD=$rev" \
|
||||
--build-arg "SDK_PATH=$sdk_path" \
|
||||
--build-arg "CONFIG_PATH=$CONFIG_PATH" \
|
||||
--arch amd64 --tag "$image" -f "$dir/Dockerfile" - < "$gitarchive"
|
||||
|
||||
echo "Creating container (radicle-build-container).."
|
||||
podman --cgroup-manager=cgroupfs create --ulimit=host --replace --name radicle-build-container "$image"
|
||||
|
||||
# Copy build artifacts to output folder.
|
||||
podman cp --overwrite radicle-build-container:/builds/. $OUTDIR/
|
||||
|
||||
while IFS= read -r target
|
||||
do
|
||||
echo "Signing artifacts for $target.."
|
||||
|
||||
filename="$PACKAGE_NAME-$version-$target.tar.xz"
|
||||
filepath="$OUTDIR/$filename"
|
||||
|
||||
# Output SHA256 digest of archive.
|
||||
checksum="$(cd $OUTDIR && sha256sum "$filename")"
|
||||
echo "Checksum of $filepath is $(echo "$checksum" | cut -d' ' -f1)"
|
||||
echo "$checksum" > "${filepath}.sha256"
|
||||
|
||||
# Sign archive and verify archive.
|
||||
rm -f "${filepath}.sig" # Delete existing signature
|
||||
ssh-keygen -Y sign -n file -f "$keypath" "$filepath"
|
||||
ssh-keygen -Y check-novalidate -n file -s "$filepath.sig" < "$filepath"
|
||||
done < "$TARGETS_PATH"
|
||||
|
||||
# Remove build artifacts that aren't needed anymore.
|
||||
podman rm radicle-build-container > /dev/null
|
||||
podman rmi --ignore "localhost/$image"
|
||||
}
|
||||
|
||||
# Run build.
|
||||
echo "Running build.."
|
||||
main "$@"
|
||||
|
||||
# Show artifact checksums.
|
||||
echo
|
||||
$dir/checksums
|
||||
echo
|
||||
|
||||
echo "Build successful."
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
find "$OUTDIR" -type f -name '*.sha256' -exec cat {} +
|
||||
Binary file not shown.
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#! /usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
if ! version=$(grep -m 1 -oP '^\s*channel\s*=\s*"?\K([\d\.]+)' rust-toolchain.toml)
|
||||
then
|
||||
echo "fatal: no rust version found via rust-toolchain.toml" >&2
|
||||
exit 1
|
||||
else
|
||||
echo "$version"
|
||||
fi
|
||||
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
if ! version="$(git describe --match='releases/*' --candidates=1 2>/dev/null)"; then
|
||||
echo "fatal: no version tag found by 'git describe'" >&2 ; exit 1
|
||||
fi
|
||||
# Remove the `releases/` prefix from version.
|
||||
version=${version#releases/}
|
||||
|
||||
echo "$version"
|
||||
Reference in New Issue
Block a user