diff --git a/docs/releasing.md b/docs/releasing.md index feff91d87..44a1afaaa 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -64,6 +64,16 @@ whose glyph-coverage test checks the characters in available faces. `CRAFT_FONTS the native build fail if the pinned manifest lacks Noto Sans CJK SC Regular (`Hans`) or BIZ UDPGothic Regular; the web build requires BIZ UDPGothic Regular and packages Noto Sans CJK SC as a separate asset. +Local macOS, Linux and Windows packaging scripts automatically use the sibling `../craft-fonts` +checkout. If it is absent, they clone it at revision +`8dcdacd5153e64560d109541a47d806f26f048c0` (keep the pins in `packaging/fonts.sh` and +`packaging/windows/fonts.ps1` in sync with the release workflow). Existing checkouts are left untouched. +Set `CRAFT_FONTS_DIR` to use another +checkout; relative paths resolve from the workspace root. The script requires the Chinese and Japanese +UI faces and includes their OFL licences in the package. Download failures or incomplete checkouts +stop packaging with an error. `--skip-build` (`-SkipBuild` on Windows) packages existing binaries without downloading fonts or +changing what they embed; pass the same `CRAFT_FONTS_DIR` used to compile them so their licences ship. + ## Signing credentials All credentials are stored as secrets in the GitHub `release` environment. Signing is optional: diff --git a/packaging/fonts.sh b/packaging/fonts.sh new file mode 100644 index 000000000..61dc913f4 --- /dev/null +++ b/packaging/fonts.sh @@ -0,0 +1,31 @@ +# shellcheck shell=bash +# Font setup for local packaging; sourced after packaging/env.sh. +prepare_fonts() { + local font_dir="${CRAFT_FONTS_DIR:-$ROOT/../craft-fonts}" + # Relative overrides are documented relative to the workspace, regardless of the caller's cwd. + case "$font_dir" in + /*) ;; + *) font_dir="$ROOT/$font_dir" ;; + esac + + if [ -z "${CRAFT_FONTS_DIR:-}" ] && [ ! -e "$font_dir" ]; then + # Same revision as release.yml. Never update or reset an existing checkout. + local revision=8dcdacd5153e64560d109541a47d806f26f048c0 + echo "==> downloading craft-fonts ($revision) to $font_dir" + if ! git clone --no-checkout https://github.com/storytold/craft-fonts "$font_dir" || + ! git -C "$font_dir" checkout --detach "$revision"; then + echo "error: could not prepare craft-fonts; provide a complete checkout with CRAFT_FONTS_DIR" >&2 + return 1 + fi + fi + + if [ ! -f "$font_dir/fonts/manifest.txt" ]; then + echo "error: missing $font_dir/fonts/manifest.txt; set CRAFT_FONTS_DIR to a complete craft-fonts checkout" >&2 + return 1 + fi + CRAFT_FONTS_DIR="$(cd "$font_dir" && pwd)" || return 1 + export CRAFT_FONTS_DIR + # Fail the build if required faces are missing, rather than ship empty glyph boxes. + export CRAFT_FONTS_REQUIRED=1 + echo "==> embedding fonts from $CRAFT_FONTS_DIR" +} diff --git a/packaging/linux/package.sh b/packaging/linux/package.sh index b5e1d9457..383c20f07 100755 --- a/packaging/linux/package.sh +++ b/packaging/linux/package.sh @@ -8,6 +8,7 @@ # $DIST/lightcraft--linux-.tar.gz plain FHS-style tree (bin/, share/) # # Usage: packaging/linux/package.sh [--skip-build] [--formats "appimage deb rpm tar"] +# Fonts: use CRAFT_FONTS_DIR or ../craft-fonts; download the pinned checkout if absent. # # Needs: cargo; nfpm for deb/rpm (https://nfpm.goreleaser.com); appimagetool for the AppImage # (downloaded into $CARGO_TARGET_DIR if missing). Build on an old distro (CI: Ubuntu 22.04, @@ -45,6 +46,9 @@ BASENAME="lightcraft-$VERSION-linux-$ARCH" echo "==> LightCraft $VERSION for Linux $ARCH ($FORMATS)" if [ "$SKIP_BUILD" = 0 ]; then + # shellcheck source=../fonts.sh + . "$ROOT/packaging/fonts.sh" + prepare_fonts (cd "$ROOT" && cargo build --release --locked -p lightcraft -p lightcraft-cli --features lightcraft/heif,lightcraft-cli/heif \ ${CROSS_TARGET:+--target "$CROSS_TARGET"}) fi diff --git a/packaging/macos/package.sh b/packaging/macos/package.sh index b26aa96d6..f26237a4c 100755 --- a/packaging/macos/package.sh +++ b/packaging/macos/package.sh @@ -5,6 +5,7 @@ # $DIST/lightcraft-cli--macos-.zip the headless CLI # # Usage: packaging/macos/package.sh [--arch universal|aarch64|x86_64] [--skip-build] +# Fonts: use CRAFT_FONTS_DIR or ../craft-fonts; download the pinned checkout if absent. # # Signing (env): # MACOS_SIGN_IDENTITY codesign identity (name or SHA-1). Default "-" = ad-hoc (local testing; @@ -56,6 +57,9 @@ echo "==> LightCraft $VERSION for macOS ($ARCH), identity: $IDENTITY, notarize: # ---- build ------------------------------------------------------------------------------------- if [ "$SKIP_BUILD" = 0 ]; then + # shellcheck source=../fonts.sh + . "$ROOT/packaging/fonts.sh" + prepare_fonts args=() for t in "${TARGETS[@]}"; do args+=(--target "$t"); done (cd "$ROOT" && cargo build --release --locked -p lightcraft -p lightcraft-cli --features lightcraft/heif,lightcraft-cli/heif "${args[@]}") diff --git a/packaging/windows/fonts.ps1 b/packaging/windows/fonts.ps1 new file mode 100644 index 000000000..c927fbb7a --- /dev/null +++ b/packaging/windows/fonts.ps1 @@ -0,0 +1,24 @@ +# Font setup for local packaging; dot-sourced by package.ps1. +function Initialize-CraftFonts([string] $WorkspaceRoot) { + $fontDir = $env:CRAFT_FONTS_DIR + if (-not $fontDir) { $fontDir = Join-Path $WorkspaceRoot '../craft-fonts' } + if (-not [IO.Path]::IsPathRooted($fontDir)) { $fontDir = Join-Path $WorkspaceRoot $fontDir } + + if (-not $env:CRAFT_FONTS_DIR -and -not (Test-Path -LiteralPath $fontDir)) { + # Same revision as release.yml and packaging/fonts.sh. Existing checkouts stay untouched. + $revision = '8dcdacd5153e64560d109541a47d806f26f048c0' + Write-Output "==> downloading craft-fonts ($revision) to $fontDir" + & git clone --no-checkout https://github.com/storytold/craft-fonts $fontDir + if ($LASTEXITCODE -ne 0) { throw 'Could not download craft-fonts; provide a complete checkout with CRAFT_FONTS_DIR' } + & git -C $fontDir checkout --detach $revision + if ($LASTEXITCODE -ne 0) { throw 'Could not check out craft-fonts; provide a complete checkout with CRAFT_FONTS_DIR' } + } + + $manifest = Join-Path $fontDir 'fonts/manifest.txt' + if (-not (Test-Path -LiteralPath $manifest -PathType Leaf)) { + throw "Missing $manifest; set CRAFT_FONTS_DIR to a complete craft-fonts checkout" + } + $env:CRAFT_FONTS_DIR = (Resolve-Path -LiteralPath $fontDir).Path + $env:CRAFT_FONTS_REQUIRED = '1' + Write-Output "==> embedding fonts from $env:CRAFT_FONTS_DIR" +} diff --git a/packaging/windows/package.ps1 b/packaging/windows/package.ps1 index e2cd2a8e7..27e0f0a03 100644 --- a/packaging/windows/package.ps1 +++ b/packaging/windows/package.ps1 @@ -11,6 +11,8 @@ zip needs the Visual C++ redistributable. Signing is delegated to sign.ps1 (skipped with a warning when no signing secrets are set). + Fonts: uses CRAFT_FONTS_DIR or ../craft-fonts; downloads the pinned checkout if absent. + Needs: Rust (MSVC toolchain + the target), the Windows SDK (rc.exe, signtool.exe), and WiX v5: dotnet tool install --global wix --version 5.0.2 The WiX UI and Util extensions (installer dialogs, "Launch LightCraft" on Finish) are added to @@ -81,6 +83,8 @@ if (-not $env:LIGHTCRAFT_BUILD_DATE) { $env:LIGHTCRAFT_BUILD_DATE = (Get-Date).T Write-Output "LightCraft $Version for Windows $Arch ($Target)" if (-not $SkipBuild) { + . (Join-Path $PSScriptRoot 'fonts.ps1') + Initialize-CraftFonts $Root # Static CRT: no VC++ redistributable needed. Scoped to the target so host build scripts and # proc-macros are unaffected. $flagVar = 'CARGO_TARGET_' + ($Target.ToUpper() -replace '-', '_') + '_RUSTFLAGS'