From 980372f6d03dfc566c57f1f3cfaedd9607932986 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Mon, 5 Oct 2026 09:25:46 -0400 Subject: [PATCH] FreeBSD: release package and a packaging check in CI - packaging/freebsd/package.sh builds vectorcraft and vectorcraft-cli and writes vectorcraft--freebsd-x86_64.tar.gz, a /usr/local-style tree (bin/, the freedesktop desktop entry, MIME type and metainfo, hicolor icons, licences, NOTICE and ASSETS.md). FreeBSD's install(1) has no -D and uname -m says amd64. - release.yml: a FreeBSD x86_64 job in the same FreeBSD 14.3 VM; the version, date and SHA reach the VM through `envs:`. The draft release waits for it. - freebsd.yml: vmactions/freebsd-vm pinned by commit (v1.5.9), git safe.directory for the copied checkout, CARGO_BUILD_JOBS=4, and a `package` job that runs the script on PRs touching FreeBSD packaging and on demand. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/freebsd.yml | 49 +++++++++++++++++++++--- .github/workflows/release.yml | 43 ++++++++++++++++++++- packaging/freebsd/package.sh | 70 +++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+), 6 deletions(-) create mode 100755 packaging/freebsd/package.sh diff --git a/.github/workflows/freebsd.yml b/.github/workflows/freebsd.yml index 5f93f997..d443b4e4 100644 --- a/.github/workflows/freebsd.yml +++ b/.github/workflows/freebsd.yml @@ -1,5 +1,6 @@ # Builds and tests the workspace on FreeBSD, inside a FreeBSD VM on a Linux runner # (GitHub has no FreeBSD runners). GPU tests skip themselves when the VM has no adapter. +# The `package` job checks packaging/freebsd/package.sh (the release job runs it for real). name: FreeBSD on: @@ -11,6 +12,8 @@ on: - Cargo.lock - "**/Cargo.toml" - .github/workflows/freebsd.yml + - packaging/freebsd/** + - packaging/env.sh workflow_dispatch: concurrency: @@ -28,7 +31,8 @@ jobs: steps: - uses: actions/checkout@v4 - name: Build and test in a FreeBSD VM - uses: vmactions/freebsd-vm@v1 + # v1.5.9, pinned by commit. + uses: vmactions/freebsd-vm@c46abacb49f09938ca4e1702d15d836285d694cc with: release: "14.3" usesh: true @@ -36,10 +40,45 @@ jobs: # Nothing to bring back; copying the target dir out of the VM fails on large builds. copyback: false prepare: | - pkg install -y curl pkgconf cmake python3 libxkbcommon wayland libX11 libXcursor libXrandr libXi libxcb mesa-libs vulkan-loader gtk3 fontconfig freetype2 alsa-lib - curl -fsSL https://sh.rustup.rs | sh -s -- -y --profile minimal + pkg install -y bash curl git pkgconf cmake python3 libxkbcommon wayland libX11 libXcursor libXrandr libXi libxcb mesa-libs vulkan-loader gtk3 fontconfig freetype2 alsa-lib + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain stable run: | . "$HOME/.cargo/env" + # The checkout copied into the VM belongs to another user. + git config --global --add safe.directory "$PWD" rustc --version - CARGO_PROFILE_DEV_DEBUG=0 cargo build --workspace --all-targets --locked - CARGO_PROFILE_DEV_DEBUG=0 cargo test --workspace --locked + # Linking many test binaries at once can run the VM out of memory. + export CARGO_PROFILE_DEV_DEBUG=0 CARGO_PROFILE_TEST_DEBUG=0 CARGO_BUILD_JOBS=4 + cargo build --workspace --all-targets --locked + cargo test --workspace --locked + + package: + name: FreeBSD 14 (package) + # The release build takes a while: only for PRs that touch FreeBSD packaging (or dependencies) + # and on demand, not on every push to main. + if: github.event_name != 'push' + runs-on: ubuntu-latest + timeout-minutes: 150 + steps: + - uses: actions/checkout@v4 + - name: Package in a FreeBSD VM + uses: vmactions/freebsd-vm@c46abacb49f09938ca4e1702d15d836285d694cc + with: + release: "14.3" + usesh: true + mem: 12288 + prepare: | + pkg install -y bash curl git pkgconf cmake python3 libxkbcommon wayland libX11 libXcursor libXrandr libXi libxcb mesa-libs vulkan-loader gtk3 fontconfig freetype2 alsa-lib + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain stable + run: | + . "$HOME/.cargo/env" + git config --global --add safe.directory "$PWD" + # Build outside the checkout so only dist/ is copied back out of the VM. + export CARGO_TARGET_DIR=/var/tmp/vectorcraft-target CARGO_BUILD_JOBS=4 + bash packaging/freebsd/package.sh + tar -tzf dist/release/vectorcraft-*-freebsd-x86_64.tar.gz | grep -E '/bin/vectorcraft$|/bin/vectorcraft-cli$|/share/applications/|/share/icons/hicolor/|/share/doc/vectorcraft/NOTICE' + - uses: actions/upload-artifact@v4 + with: + name: freebsd-package + path: dist/release/* + if-no-files-found: error diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 70ebb9c6..f103e8c2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -201,6 +201,47 @@ jobs: path: dist/release/* if-no-files-found: error + freebsd: + name: FreeBSD x86_64 + needs: version + # GitHub has no FreeBSD runners: build in a FreeBSD 14.3 VM (same image as freebsd.yml). + runs-on: ubuntu-latest + timeout-minutes: 150 + environment: release + env: + VECTORCRAFT_VERSION: ${{ needs.version.outputs.version }} + VECTORCRAFT_BUILD_DATE: ${{ needs.version.outputs.date }} + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + if: inputs.version != '' + - name: Apply version override + if: inputs.version != '' + run: cargo xtask version set "$VECTORCRAFT_VERSION" + - name: Build and package in a FreeBSD VM + # v1.5.9, pinned by commit. + uses: vmactions/freebsd-vm@c46abacb49f09938ca4e1702d15d836285d694cc + with: + release: "14.3" + usesh: true + mem: 12288 + # Passed through by name; never templated into the script. + envs: "VECTORCRAFT_VERSION VECTORCRAFT_BUILD_DATE VECTORCRAFT_BUILD_SHA" + prepare: | + pkg install -y bash curl git pkgconf cmake python3 libxkbcommon wayland libX11 libXcursor libXrandr libXi libxcb mesa-libs vulkan-loader gtk3 fontconfig freetype2 alsa-lib + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain stable + run: | + . "$HOME/.cargo/env" + git config --global --add safe.directory "$PWD" + # Build outside the checkout so only dist/ is copied back out of the VM. + export CARGO_TARGET_DIR=/var/tmp/vectorcraft-target CARGO_BUILD_JOBS=4 + bash packaging/freebsd/package.sh + - uses: actions/upload-artifact@v4 + with: + name: release-freebsd + path: dist/release/* + if-no-files-found: error + web: name: Web (wasm) needs: version @@ -236,7 +277,7 @@ jobs: release: name: Draft GitHub Release - needs: [version, macos, windows, linux, web] + needs: [version, macos, windows, linux, freebsd, web] runs-on: ubuntu-latest environment: release permissions: diff --git a/packaging/freebsd/package.sh b/packaging/freebsd/package.sh new file mode 100755 index 00000000..3e25edc1 --- /dev/null +++ b/packaging/freebsd/package.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +# Build and package VectorCraft for FreeBSD: +# +# $DIST/vectorcraft--freebsd-x86_64.tar.gz a /usr/local-style tree: +# vectorcraft--freebsd-x86_64/{bin, share/applications, share/icons, share/mime, +# share/metainfo, share/doc/vectorcraft} +# +# Install by copying the tree's contents into /usr/local, e.g. +# tar -xzf vectorcraft-*-freebsd-x86_64.tar.gz --strip-components 1 -C /usr/local +# +# Usage: packaging/freebsd/package.sh [--skip-build] +# +# Needs: bash, cargo and the build dependencies listed in .github/workflows/freebsd.yml. FreeBSD's +# install(1) has no -D, so directories are created first. +set -euo pipefail +# shellcheck source=../env.sh +. "$(dirname "${BASH_SOURCE[0]}")/../env.sh" +LINUX="$ROOT/packaging/linux" +APP_ID=ai.storyteller.vectorcraft + +SKIP_BUILD=0 +while [ $# -gt 0 ]; do + case "$1" in + --skip-build) SKIP_BUILD=1; shift ;; + -h | --help) sed -n '2,13p' "$0"; exit 0 ;; + *) echo "unknown argument: $1" >&2; exit 2 ;; + esac +done + +# FreeBSD calls x86_64 "amd64"; release names use the Rust/Linux spelling. +case "$(uname -m)" in + amd64 | x86_64) ARCH=x86_64 ;; + arm64 | aarch64) ARCH=aarch64 ;; + *) echo "unsupported architecture $(uname -m)" >&2; exit 2 ;; +esac +BASENAME="vectorcraft-$VERSION-freebsd-$ARCH" + +echo "==> VectorCraft $VERSION for FreeBSD $ARCH" + +if [ "$SKIP_BUILD" = 0 ]; then + (cd "$ROOT" && cargo build --release --locked -p vectorcraft -p vectorcraft-cli) +fi +BIN="$CARGO_TARGET_DIR/release" +WORK="$CARGO_TARGET_DIR/freebsd-package" +STAGE="$WORK/$BASENAME" +rm -rf "$WORK" + +# ---- stage a /usr/local-style tree --------------------------------------------------------------- +mkdir -p "$STAGE/bin" "$STAGE/share/applications" "$STAGE/share/mime/packages" "$STAGE/share/metainfo" \ + "$STAGE/share/icons" "$STAGE/share/doc/vectorcraft" +install -m 755 "$BIN/vectorcraft" "$BIN/vectorcraft-cli" "$STAGE/bin/" +strip "$STAGE/bin/vectorcraft" "$STAGE/bin/vectorcraft-cli" 2>/dev/null || true +# The desktop entry, MIME type and metainfo are the freedesktop files the Linux packages use. +install -m 644 "$LINUX/$APP_ID.desktop" "$STAGE/share/applications/$APP_ID.desktop" +install -m 644 "$LINUX/$APP_ID.mime.xml" "$STAGE/share/mime/packages/$APP_ID.xml" +sed -e "s/@VERSION@/$VERSION/g" -e "s/@DATE@/$VECTORCRAFT_BUILD_DATE/g" \ + "$LINUX/$APP_ID.metainfo.xml.in" >"$STAGE/share/metainfo/$APP_ID.metainfo.xml" +cp -R "$ROOT/assets/app-icon/hicolor" "$STAGE/share/icons/" +copy_docs "$STAGE/share/doc/vectorcraft" +for f in NOTICE ASSETS.md; do + if [ -f "$ROOT/$f" ]; then cp "$ROOT/$f" "$STAGE/share/doc/vectorcraft/"; fi +done + +# ---- .tar.gz ------------------------------------------------------------------------------------- +tar -C "$WORK" -czf "$DIST/$BASENAME.tar.gz" "$BASENAME" +echo "wrote $DIST/$BASENAME.tar.gz" + +"$STAGE/bin/vectorcraft-cli" --version +echo "==> done" +ls -lh "$DIST"