Radish alpha
r
rad:z39mP9rQAaGmERfUMPULfPUi473tY
Radicle terminal user interface
Radicle
Git
chore: Move to local release builds
Erik Kundt committed 5 months ago
commit 954d7bfbea16015cb047f2e8c8b7d0531fec8142
parent ee20b95
12 files changed +249 -95
deleted .cargo/config.toml
@@ -1,2 +0,0 @@
-
[target.aarch64-unknown-linux-gnu]
-
linker = "aarch64-linux-gnu-gcc"
deleted .github/workflows/binaries.yml
@@ -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
modified .gitignore
@@ -3,3 +3,6 @@

# Nix
/result
+

+
# Release
+
build/artifacts
added build/TARGETS
@@ -0,0 +1,4 @@
+
x86_64-unknown-linux-musl
+
aarch64-unknown-linux-musl
+
x86_64-apple-darwin
+
aarch64-apple-darwin
added build/build
@@ -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 "$@"
added build/config.toml
@@ -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",
+
]
added build/radicle-build/Dockerfile
@@ -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" \
+
    '{}' \;
added build/radicle-build/build
@@ -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."
added build/radicle-build/checksums
@@ -0,0 +1,2 @@
+
#!/bin/sh
+
find "$OUTDIR" -type f -name '*.sha256' -exec cat {} +
added build/radicle-build/macos-sdk-11.3.tar.xz
added build/radicle-build/rust-version
@@ -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
+

added build/radicle-build/version
@@ -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"