Rename PrintCraft to PdfCraft (#174)

The app, crates, binaries, bundle id, packaging, icons, screenshots and docs are now
PdfCraft / pdfcraft (repo storytold/pdfcraft). On first launch the desktop app moves the
PrintCraft settings and crash-recovery folders to the new name, and both apps read settings
saved under the old storage key, so upgrades keep recent files, preferences and unsaved work.
The signing test fixtures keep their PrintCraft subject names (they are binary).

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon Thomas
2026-10-07 16:03:57 -04:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 1c78ff479c
commit d3db99818f
351 changed files with 3218 additions and 3216 deletions
+8 -8
View File
@@ -3,10 +3,10 @@
#
# Exports:
# ROOT workspace root
# VERSION [workspace.package] version from Cargo.toml (override: PRINTCRAFT_VERSION)
# VERSION [workspace.package] version from Cargo.toml (override: PDFCRAFT_VERSION)
# DIST output directory for release artifacts (default: $ROOT/dist/release)
# PRINTCRAFT_BUILD_SHA git commit, recorded in the macOS Info.plist (PrintCraftBuildCommit)
# PRINTCRAFT_BUILD_DATE UTC build date, YYYY-MM-DD
# PDFCRAFT_BUILD_SHA git commit, recorded in the macOS Info.plist (PdfCraftBuildCommit)
# PDFCRAFT_BUILD_DATE UTC build date, YYYY-MM-DD
# CARGO_TARGET_DIR cargo's target dir (default: $ROOT/target)
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
@@ -21,7 +21,7 @@ workspace_version() {
' "$ROOT/Cargo.toml"
}
VERSION="${PRINTCRAFT_VERSION:-$(workspace_version)}"
VERSION="${PDFCRAFT_VERSION:-$(workspace_version)}"
if [ -z "$VERSION" ]; then
echo "error: could not read [workspace.package] version from $ROOT/Cargo.toml" >&2
exit 1
@@ -32,11 +32,11 @@ DIST="${DIST:-$ROOT/dist/release}"
mkdir -p "$DIST"
export DIST
if [ -z "${PRINTCRAFT_BUILD_SHA:-}" ]; then
PRINTCRAFT_BUILD_SHA="$(git -C "$ROOT" rev-parse HEAD 2>/dev/null || true)"
if [ -z "${PDFCRAFT_BUILD_SHA:-}" ]; then
PDFCRAFT_BUILD_SHA="$(git -C "$ROOT" rev-parse HEAD 2>/dev/null || true)"
fi
export PRINTCRAFT_BUILD_SHA
export PRINTCRAFT_BUILD_DATE="${PRINTCRAFT_BUILD_DATE:-$(date -u +%Y-%m-%d)}"
export PDFCRAFT_BUILD_SHA
export PDFCRAFT_BUILD_DATE="${PDFCRAFT_BUILD_DATE:-$(date -u +%Y-%m-%d)}"
export CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-$ROOT/target}"
# Emit a GitHub Actions warning (plain stderr outside Actions).
+13 -13
View File
@@ -1,8 +1,8 @@
#!/usr/bin/env bash
# Build PrintCraft for FreeBSD and package it:
# $DIST/printcraft-<version>-freebsd-<arch>.tar.gz a /usr/local-style tree (bin/, share/)
# Build PdfCraft for FreeBSD and package it:
# $DIST/pdfcraft-<version>-freebsd-<arch>.tar.gz a /usr/local-style tree (bin/, share/)
#
# Extract it into /usr/local (or anywhere, and run bin/printcraft from there). The desktop entry,
# Extract it into /usr/local (or anywhere, and run bin/pdfcraft from there). The desktop entry,
# MIME type, AppStream metadata and icons are the freedesktop ones Linux uses.
#
# Usage: packaging/freebsd/package.sh [--skip-build]
@@ -11,7 +11,7 @@ set -euo pipefail
# shellcheck source=../env.sh
. "$(dirname "${BASH_SOURCE[0]}")/../env.sh"
LINUX="$ROOT/packaging/linux"
APP_ID=ai.storyteller.printcraft
APP_ID=ai.storyteller.pdfcraft
SKIP_BUILD=0
while [ $# -gt 0 ]; do
@@ -28,12 +28,12 @@ case "$ARCH" in
arm64 | aarch64) ARCH=aarch64 ;;
*) echo "unsupported architecture $ARCH" >&2; exit 2 ;;
esac
BASENAME="printcraft-$VERSION-freebsd-$ARCH"
BASENAME="pdfcraft-$VERSION-freebsd-$ARCH"
echo "==> PrintCraft $VERSION for FreeBSD $ARCH"
echo "==> PdfCraft $VERSION for FreeBSD $ARCH"
if [ "$SKIP_BUILD" = 0 ]; then
(cd "$ROOT" && cargo build --release --locked -p printcraft -p printcraft-cli)
(cd "$ROOT" && cargo build --release --locked -p pdfcraft -p pdfcraft-cli)
fi
BIN="$CARGO_TARGET_DIR/release"
WORK="$CARGO_TARGET_DIR/freebsd-package"
@@ -42,17 +42,17 @@ rm -rf "$WORK"
# FreeBSD's install(1) has no -D: create the directories first.
mkdir -p "$STAGE/bin" "$STAGE/share/applications" "$STAGE/share/mime/packages" "$STAGE/share/metainfo" \
"$STAGE/share/icons" "$STAGE/share/doc/printcraft"
install -m 755 "$BIN/printcraft" "$BIN/printcraft-cli" "$STAGE/bin/"
strip "$STAGE/bin/printcraft" "$STAGE/bin/printcraft-cli" 2>/dev/null || true
"$STAGE/share/icons" "$STAGE/share/doc/pdfcraft"
install -m 755 "$BIN/pdfcraft" "$BIN/pdfcraft-cli" "$STAGE/bin/"
strip "$STAGE/bin/pdfcraft" "$STAGE/bin/pdfcraft-cli" 2>/dev/null || true
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@/$PRINTCRAFT_BUILD_DATE/g" \
sed -e "s/@VERSION@/$VERSION/g" -e "s/@DATE@/$PDFCRAFT_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/printcraft"
copy_docs "$STAGE/share/doc/pdfcraft"
"$STAGE/bin/printcraft" --version
"$STAGE/bin/pdfcraft" --version
mkdir -p "$DIST"
tar -C "$WORK" -czf "$DIST/$BASENAME.tar.gz" "$BASENAME"
echo "wrote $DIST/$BASENAME.tar.gz"
+9 -9
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# Regenerate every app icon from assets/app-icon/printcraft.svg (the master vector).
# Regenerate every app icon from assets/app-icon/pdfcraft.svg (the master vector).
#
# Needs: resvg (brew install resvg / cargo install resvg) and python3 (stdlib only, for the .ico).
# On macOS, iconutil also writes the .icns. The outputs are committed, so building and packaging
@@ -10,8 +10,8 @@
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
DIR="$ROOT/assets/app-icon"
SVG="$DIR/printcraft.svg"
ID="ai.storyteller.printcraft"
SVG="$DIR/pdfcraft.svg"
ID="ai.storyteller.pdfcraft"
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
@@ -28,8 +28,8 @@ MAC="$TMP/macos.svg"
render() { resvg -w "$2" -h "$2" "$1" "$3" </dev/null; }
# 1024 px PNG on Apple's grid (also the runtime Dock icon on macOS, see apps/printcraft/src/main.rs).
render "$MAC" 1024 "$DIR/printcraft-1024.png"
# 1024 px PNG on Apple's grid (also the runtime Dock icon on macOS, see apps/pdfcraft/src/main.rs).
render "$MAC" 1024 "$DIR/pdfcraft-1024.png"
# Linux hicolor theme (full bleed; hicolor/256x256 is also the runtime icon on Windows and Linux).
for s in 16 24 32 48 64 128 256 512; do
@@ -45,7 +45,7 @@ for s in 16 20 24 32 40 48 64 128 256; do
render "$SVG" "$s" "$TMP/ico-$s.png"
ICO_PNGS+=("$TMP/ico-$s.png")
done
python3 - "$DIR/printcraft.ico" "${ICO_PNGS[@]}" <<'PY'
python3 - "$DIR/pdfcraft.ico" "${ICO_PNGS[@]}" <<'PY'
import struct, sys
out, pngs = sys.argv[1], sys.argv[2:]
blobs = [open(p, "rb").read() for p in pngs]
@@ -61,14 +61,14 @@ PY
# macOS .icns.
if command -v iconutil >/dev/null; then
SET="$TMP/printcraft.iconset"
SET="$TMP/pdfcraft.iconset"
mkdir -p "$SET"
for s in 16 32 128 256 512; do
render "$MAC" "$s" "$SET/icon_${s}x${s}.png"
render "$MAC" $((s * 2)) "$SET/icon_${s}x${s}@2x.png"
done
iconutil -c icns -o "$DIR/printcraft.icns" "$SET"
iconutil -c icns -o "$DIR/pdfcraft.icns" "$SET"
else
echo "warning: iconutil not found (macOS only); printcraft.icns not regenerated" >&2
echo "warning: iconutil not found (macOS only); pdfcraft.icns not regenerated" >&2
fi
echo "icons written to $DIR"
@@ -1,14 +1,14 @@
[Desktop Entry]
Type=Application
Name=PrintCraft
Name=PdfCraft
GenericName=PDF Editor
Comment=Read, organize, combine, split and secure PDFs
Exec=printcraft %F
TryExec=printcraft
Icon=ai.storyteller.printcraft
Exec=pdfcraft %F
TryExec=pdfcraft
Icon=ai.storyteller.pdfcraft
Terminal=false
StartupNotify=true
StartupWMClass=printcraft
StartupWMClass=pdfcraft
Categories=Office;Viewer;Graphics;
Keywords=pdf;viewer;editor;annotate;sign;forms;merge;split;
MimeType=application/pdf;
@@ -2,26 +2,26 @@
<!-- AppStream metadata (software centres, Flathub). Template: package.sh and the Flatpak
manifest substitute @VERSION@ and @DATE@ from Cargo.toml and the build date. -->
<component type="desktop-application">
<id>ai.storyteller.printcraft</id>
<id>ai.storyteller.pdfcraft</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>MIT OR Apache-2.0</project_license>
<name>PrintCraft</name>
<name>PdfCraft</name>
<summary>Read, organize, combine, split and secure PDFs</summary>
<developer id="ai.storyteller">
<name>Learning Machines LLC</name>
</developer>
<description>
<p>
PrintCraft is an open-source PDF workbench. Read, comment on, fill in and sign PDFs;
PdfCraft is an open-source PDF workbench. Read, comment on, fill in and sign PDFs;
organize, combine and split pages; edit, redact, protect and export documents.
</p>
</description>
<launchable type="desktop-id">ai.storyteller.printcraft.desktop</launchable>
<icon type="stock">ai.storyteller.printcraft</icon>
<launchable type="desktop-id">ai.storyteller.pdfcraft.desktop</launchable>
<icon type="stock">ai.storyteller.pdfcraft</icon>
<!-- Only url types known to appstream 0.15 (Ubuntu 22.04, where CI validates): no vcs-browser. -->
<url type="homepage">https://getartcraft.com/apps/printcraft</url>
<url type="bugtracker">https://github.com/storytold/printcraft/issues</url>
<url type="help">https://github.com/storytold/printcraft</url>
<url type="homepage">https://getartcraft.com/apps/pdfcraft</url>
<url type="bugtracker">https://github.com/storytold/pdfcraft/issues</url>
<url type="help">https://github.com/storytold/pdfcraft</url>
<url type="contact">https://discord.gg/artcraft</url>
<categories>
<category>Office</category>
@@ -36,7 +36,7 @@
<screenshots>
<screenshot type="default">
<caption>A PDF open with its threaded comments</caption>
<image>https://raw.githubusercontent.com/storytold/printcraft/main/docs/images/printcraft-viewer.png</image>
<image>https://raw.githubusercontent.com/storytold/pdfcraft/main/docs/images/pdfcraft-viewer.png</image>
</screenshot>
</screenshots>
<branding>
@@ -52,7 +52,7 @@
<control>tablet</control>
</supports>
<provides>
<binary>printcraft</binary>
<binary>pdfcraft</binary>
<mediatype>application/pdf</mediatype>
</provides>
<content_rating type="oars-1.1"/>
@@ -1,20 +1,20 @@
# Flatpak manifest for PrintCraft, ready for a Flathub submission.
# Flatpak manifest for PdfCraft, ready for a Flathub submission.
#
# Flatpak builds run offline, so the crate sources must be vendored first. From the repo root:
#
# curl -fsSLO https://raw.githubusercontent.com/flatpak/flatpak-builder-tools/master/cargo/flatpak-cargo-generator.py
# python3 flatpak-cargo-generator.py Cargo.lock -o packaging/linux/flatpak/cargo-sources.json
# flatpak-builder --user --install --force-clean build-flatpak packaging/linux/flatpak/ai.storyteller.printcraft.yml
# flatpak run ai.storyteller.printcraft
# flatpak-builder --user --install --force-clean build-flatpak packaging/linux/flatpak/ai.storyteller.pdfcraft.yml
# flatpak run ai.storyteller.pdfcraft
#
# For Flathub, replace the `dir` source with a `git` source pinned to a release tag and commit.
id: ai.storyteller.printcraft
id: ai.storyteller.pdfcraft
runtime: org.freedesktop.Platform
runtime-version: '25.08'
sdk: org.freedesktop.Sdk
sdk-extensions:
- org.freedesktop.Sdk.Extension.rust-stable
command: printcraft
command: pdfcraft
finish-args:
- --share=ipc
- --socket=wayland
@@ -27,23 +27,23 @@ finish-args:
build-options:
append-path: /usr/lib/sdk/rust-stable/bin
modules:
- name: printcraft
- name: pdfcraft
buildsystem: simple
build-options:
env:
CARGO_HOME: /run/build/printcraft/cargo
CARGO_HOME: /run/build/pdfcraft/cargo
CARGO_NET_OFFLINE: 'true'
build-commands:
- cargo --offline build --release --locked -p printcraft
- install -Dm755 target/release/printcraft /app/bin/printcraft
- install -Dm644 packaging/linux/ai.storyteller.printcraft.desktop /app/share/applications/ai.storyteller.printcraft.desktop
- install -Dm644 packaging/linux/ai.storyteller.printcraft.mime.xml /app/share/mime/packages/ai.storyteller.printcraft.xml
- cargo --offline build --release --locked -p pdfcraft
- install -Dm755 target/release/pdfcraft /app/bin/pdfcraft
- install -Dm644 packaging/linux/ai.storyteller.pdfcraft.desktop /app/share/applications/ai.storyteller.pdfcraft.desktop
- install -Dm644 packaging/linux/ai.storyteller.pdfcraft.mime.xml /app/share/mime/packages/ai.storyteller.pdfcraft.xml
- mkdir -p /app/share/icons && cp -R assets/app-icon/hicolor /app/share/icons/
- >-
version=$(awk '/^\[/{p=($0=="[workspace.package]");next} p&&$1=="version"{gsub(/[" ]/,"",$3);print $3;exit}' Cargo.toml);
install -d /app/share/metainfo;
sed -e "s/@VERSION@/$version/" -e "s/@DATE@/$(date -u +%Y-%m-%d)/"
packaging/linux/ai.storyteller.printcraft.metainfo.xml.in > /app/share/metainfo/ai.storyteller.printcraft.metainfo.xml
packaging/linux/ai.storyteller.pdfcraft.metainfo.xml.in > /app/share/metainfo/ai.storyteller.pdfcraft.metainfo.xml
sources:
- type: dir
path: ../../..
+8 -8
View File
@@ -3,7 +3,7 @@
# exports VERSION and NFPM_ARCH.
#
# nfpm package -f packaging/linux/nfpm.yaml -p deb -t dist/release/
name: printcraft
name: pdfcraft
arch: ${NFPM_ARCH}
platform: linux
version: ${VERSION}
@@ -12,14 +12,14 @@ version_schema: semver
release: 1
section: graphics
priority: optional
maintainer: ${PRINTCRAFT_MAINTAINER}
maintainer: ${PDFCRAFT_MAINTAINER}
vendor: Learning Machines LLC
homepage: https://getartcraft.com/apps/printcraft
homepage: https://getartcraft.com/apps/pdfcraft
license: MIT OR Apache-2.0
description: |-
Open-source, native PDF workbench: read, comment, fill and sign forms,
organize, combine, split, edit, redact, protect and export PDFs.
Includes printcraft-cli, a headless command runner and opt-in MCP server.
Includes pdfcraft-cli, a headless command runner and opt-in MCP server.
# The binaries link only glibc and libgcc_s directly. Windowing (X11/Wayland, xkbcommon) and the
# GPU (Vulkan, EGL/GL) are loaded at runtime, so they are dependencies/recommendations here
@@ -54,11 +54,11 @@ overrides:
- xdg-desktop-portal
contents:
- src: ${STAGE}/usr/bin/printcraft
dst: /usr/bin/printcraft
- src: ${STAGE}/usr/bin/pdfcraft
dst: /usr/bin/pdfcraft
file_info: { mode: 0755 }
- src: ${STAGE}/usr/bin/printcraft-cli
dst: /usr/bin/printcraft-cli
- src: ${STAGE}/usr/bin/pdfcraft-cli
dst: /usr/bin/pdfcraft-cli
file_info: { mode: 0755 }
- src: ${STAGE}/usr/share/
dst: /usr/share/
+19 -19
View File
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
# Build and package PrintCraft for Linux (<arch> is x86_64 or aarch64):
# Build and package PdfCraft for Linux (<arch> is x86_64 or aarch64):
#
# $DIST/printcraft-<version>-linux-<arch>.AppImage any distro with glibc >= the build host's
# $DIST/printcraft-<version>-linux-<arch>.deb Debian, Ubuntu, Mint, Pop!_OS, ...
# $DIST/printcraft-<version>-linux-<arch>.rpm Fedora, openSUSE, RHEL, ...
# $DIST/printcraft-<version>-linux-<arch>.tar.gz plain FHS-style tree (bin/, share/)
# $DIST/pdfcraft-<version>-linux-<arch>.AppImage any distro with glibc >= the build host's
# $DIST/pdfcraft-<version>-linux-<arch>.deb Debian, Ubuntu, Mint, Pop!_OS, ...
# $DIST/pdfcraft-<version>-linux-<arch>.rpm Fedora, openSUSE, RHEL, ...
# $DIST/pdfcraft-<version>-linux-<arch>.tar.gz plain FHS-style tree (bin/, share/)
#
# Usage: packaging/linux/package.sh [--skip-build] [--formats "appimage deb rpm tar"]
#
@@ -15,7 +15,7 @@ set -euo pipefail
# shellcheck source=../env.sh
. "$(dirname "${BASH_SOURCE[0]}")/../env.sh"
HERE="$ROOT/packaging/linux"
APP_ID=ai.storyteller.printcraft
APP_ID=ai.storyteller.pdfcraft
SKIP_BUILD=0
FORMATS="appimage deb rpm tar"
@@ -34,13 +34,13 @@ case "$ARCH" in
aarch64 | arm64) ARCH=aarch64; DEB_ARCH=arm64 ;;
*) echo "unsupported architecture $ARCH" >&2; exit 2 ;;
esac
export PRINTCRAFT_MAINTAINER="${PRINTCRAFT_MAINTAINER:-PrintCraft maintainers <printcraft@storyteller.ai>}"
BASENAME="printcraft-$VERSION-linux-$ARCH"
export PDFCRAFT_MAINTAINER="${PDFCRAFT_MAINTAINER:-PdfCraft maintainers <pdfcraft@storyteller.ai>}"
BASENAME="pdfcraft-$VERSION-linux-$ARCH"
echo "==> PrintCraft $VERSION for Linux $ARCH ($FORMATS)"
echo "==> PdfCraft $VERSION for Linux $ARCH ($FORMATS)"
if [ "$SKIP_BUILD" = 0 ]; then
(cd "$ROOT" && cargo build --release --locked -p printcraft -p printcraft-cli)
(cd "$ROOT" && cargo build --release --locked -p pdfcraft -p pdfcraft-cli)
fi
BIN="$CARGO_TARGET_DIR/release"
WORK="$CARGO_TARGET_DIR/linux-package"
@@ -48,18 +48,18 @@ STAGE="$WORK/root"
rm -rf "$WORK"
# ---- stage an FHS tree (shared by every format) -------------------------------------------------
install -Dm755 "$BIN/printcraft" "$STAGE/usr/bin/printcraft"
install -Dm755 "$BIN/printcraft-cli" "$STAGE/usr/bin/printcraft-cli"
strip "$STAGE/usr/bin/printcraft" "$STAGE/usr/bin/printcraft-cli" 2>/dev/null || true
install -Dm755 "$BIN/pdfcraft" "$STAGE/usr/bin/pdfcraft"
install -Dm755 "$BIN/pdfcraft-cli" "$STAGE/usr/bin/pdfcraft-cli"
strip "$STAGE/usr/bin/pdfcraft" "$STAGE/usr/bin/pdfcraft-cli" 2>/dev/null || true
install -Dm644 "$HERE/$APP_ID.desktop" "$STAGE/usr/share/applications/$APP_ID.desktop"
install -Dm644 "$HERE/$APP_ID.mime.xml" "$STAGE/usr/share/mime/packages/$APP_ID.xml"
mkdir -p "$STAGE/usr/share/metainfo"
sed -e "s/@VERSION@/$VERSION/g" -e "s/@DATE@/$PRINTCRAFT_BUILD_DATE/g" \
sed -e "s/@VERSION@/$VERSION/g" -e "s/@DATE@/$PDFCRAFT_BUILD_DATE/g" \
"$HERE/$APP_ID.metainfo.xml.in" >"$STAGE/usr/share/metainfo/$APP_ID.metainfo.xml"
mkdir -p "$STAGE/usr/share/icons"
cp -R "$ROOT/assets/app-icon/hicolor" "$STAGE/usr/share/icons/"
mkdir -p "$STAGE/usr/share/doc/printcraft"
copy_docs "$STAGE/usr/share/doc/printcraft"
mkdir -p "$STAGE/usr/share/doc/pdfcraft"
copy_docs "$STAGE/usr/share/doc/pdfcraft"
if command -v desktop-file-validate >/dev/null; then
desktop-file-validate "$STAGE/usr/share/applications/$APP_ID.desktop"
@@ -92,10 +92,10 @@ fi
# ---- AppImage -----------------------------------------------------------------------------------
if has appimage; then
APPDIR="$WORK/PrintCraft.AppDir"
APPDIR="$WORK/PdfCraft.AppDir"
cp -R "$STAGE" "$APPDIR"
mv "$APPDIR/usr/share/doc" "$WORK/doc-unused"
ln -s usr/bin/printcraft "$APPDIR/AppRun"
ln -s usr/bin/pdfcraft "$APPDIR/AppRun"
cp "$HERE/$APP_ID.desktop" "$APPDIR/$APP_ID.desktop"
cp "$ROOT/assets/app-icon/hicolor/256x256/apps/$APP_ID.png" "$APPDIR/$APP_ID.png"
ln -s "$APP_ID.png" "$APPDIR/.DirIcon"
@@ -115,6 +115,6 @@ if has appimage; then
echo "wrote $OUT"
fi
"$STAGE/usr/bin/printcraft-cli" --version
"$STAGE/usr/bin/pdfcraft-cli" --version
echo "==> done"
ls -lh "$DIST"
+10 -10
View File
@@ -7,13 +7,13 @@
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>PrintCraft</string>
<string>PdfCraft</string>
<key>CFBundleName</key>
<string>PrintCraft</string>
<string>PdfCraft</string>
<key>CFBundleExecutable</key>
<string>PrintCraft</string>
<string>PdfCraft</string>
<key>CFBundleIdentifier</key>
<string>ai.storyteller.printcraft</string>
<string>ai.storyteller.pdfcraft</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
@@ -24,12 +24,12 @@
<string>@SHORT_VERSION@</string>
<key>CFBundleVersion</key>
<string>@SHORT_VERSION@</string>
<key>PrintCraftVersion</key>
<key>PdfCraftVersion</key>
<string>@VERSION@</string>
<key>PrintCraftBuildCommit</key>
<key>PdfCraftBuildCommit</key>
<string>@BUILD_SHA@</string>
<key>CFBundleIconFile</key>
<string>PrintCraft</string>
<string>PdfCraft</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.graphics-design</string>
<!-- Must match MACOSX_DEPLOYMENT_TARGET in package.sh. Big Sur is the first release on
@@ -43,12 +43,12 @@
<key>NSRequiresAquaSystemAppearance</key>
<false/>
<key>NSHumanReadableCopyright</key>
<string>Copyright © the PrintCraft authors. MIT OR Apache-2.0.</string>
<string>Copyright © the PdfCraft authors. MIT OR Apache-2.0.</string>
<!-- Documents PrintCraft opens (#73): it is offered under Open With and can be made the default
<!-- Documents PdfCraft opens (#73): it is offered under Open With and can be made the default
for PDFs, without taking over from the system's viewer on install ("Alternate"). Declared by
extension and MIME type; LaunchServices maps them to the system's PDF type. Finder hands the
file over as an Apple event, which apps/printcraft/src/apple_events.rs receives. -->
file over as an Apple event, which apps/pdfcraft/src/apple_events.rs receives. -->
<key>CFBundleDocumentTypes</key>
<array>
<dict>
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!-- Hardened-runtime entitlements for Printcraft. Deliberately empty: the app is pure Rust,
<!-- Hardened-runtime entitlements for Pdfcraft. Deliberately empty: the app is pure Rust,
loads no unsigned code, needs no JIT, and is not sandboxed (it opens files by path, from the
command line and drag-and-drop). Add exceptions here only with a reason in a comment. -->
<plist version="1.0">
+2 -2
View File
@@ -18,8 +18,8 @@ if [ -z "${APPLE_CERTIFICATE:-}" ]; then
fi
TMP="${RUNNER_TEMP:-${TMPDIR:-/tmp}}"
KEYCHAIN="$TMP/printcraft-signing.keychain-db"
CERT="$TMP/printcraft-signing.p12"
KEYCHAIN="$TMP/pdfcraft-signing.keychain-db"
CERT="$TMP/pdfcraft-signing.p12"
KC_PASS="${KEYCHAIN_PASSWORD:-$(openssl rand -hex 24)}"
trap 'rm -f "$CERT"' EXIT
+22 -22
View File
@@ -1,8 +1,8 @@
#!/usr/bin/env bash
# Build, sign and (optionally) notarize the macOS release artifacts:
#
# $DIST/printcraft-<version>-macos-<arch>.dmg PrintCraft.app on a drag-to-Applications DMG
# $DIST/printcraft-cli-<version>-macos-<arch>.zip the headless CLI
# $DIST/pdfcraft-<version>-macos-<arch>.dmg PdfCraft.app on a drag-to-Applications DMG
# $DIST/pdfcraft-cli-<version>-macos-<arch>.zip the headless CLI
#
# Usage: packaging/macos/package.sh [--arch universal|aarch64|x86_64] [--skip-build]
#
@@ -39,9 +39,9 @@ export MACOSX_DEPLOYMENT_TARGET=11.0
IDENTITY="${MACOS_SIGN_IDENTITY:--}"
SHORT_VERSION="${VERSION%%-*}"
WORK="$CARGO_TARGET_DIR/macos-package"
APP="$WORK/PrintCraft.app"
DMG="$DIST/printcraft-$VERSION-macos-$ARCH.dmg"
CLI_ZIP="$DIST/printcraft-cli-$VERSION-macos-$ARCH.zip"
APP="$WORK/PdfCraft.app"
DMG="$DIST/pdfcraft-$VERSION-macos-$ARCH.dmg"
CLI_ZIP="$DIST/pdfcraft-cli-$VERSION-macos-$ARCH.zip"
NOTARIZE=0
if [ "$IDENTITY" = "-" ]; then
@@ -52,18 +52,18 @@ else
warn "macOS: APPLE_ID / APPLE_PASSWORD / APPLE_TEAM_ID incomplete; signed but not notarized"
fi
echo "==> PrintCraft $VERSION for macOS ($ARCH), identity: $IDENTITY, notarize: $NOTARIZE"
echo "==> PdfCraft $VERSION for macOS ($ARCH), identity: $IDENTITY, notarize: $NOTARIZE"
# ---- build -------------------------------------------------------------------------------------
if [ "$SKIP_BUILD" = 0 ]; then
args=()
for t in "${TARGETS[@]}"; do args+=(--target "$t"); done
(cd "$ROOT" && cargo build --release --locked -p printcraft -p printcraft-cli "${args[@]}")
(cd "$ROOT" && cargo build --release --locked -p pdfcraft -p pdfcraft-cli "${args[@]}")
fi
rm -rf "$WORK"
mkdir -p "$WORK/bin"
for bin in printcraft printcraft-cli; do
for bin in pdfcraft pdfcraft-cli; do
inputs=()
for t in "${TARGETS[@]}"; do inputs+=("$CARGO_TARGET_DIR/$t/release/$bin"); done
lipo -create -output "$WORK/bin/$bin" "${inputs[@]}"
@@ -97,28 +97,28 @@ notarize() {
fi
}
# ---- PrintCraft.app ----------------------------------------------------------------------------
# ---- PdfCraft.app ----------------------------------------------------------------------------
echo "==> assembling $APP"
mkdir -p "$APP/Contents/MacOS" "$APP/Contents/Resources"
# Executable and icon carry the display name (CFBundleExecutable / CFBundleIconFile).
cp "$WORK/bin/printcraft" "$APP/Contents/MacOS/PrintCraft"
cp "$ROOT/assets/app-icon/printcraft.icns" "$APP/Contents/Resources/PrintCraft.icns"
cp "$WORK/bin/pdfcraft" "$APP/Contents/MacOS/PdfCraft"
cp "$ROOT/assets/app-icon/pdfcraft.icns" "$APP/Contents/Resources/PdfCraft.icns"
copy_font_licences "$APP/Contents/Resources"
sed -e "s/@VERSION@/$VERSION/g" -e "s/@SHORT_VERSION@/$SHORT_VERSION/g" \
-e "s/@BUILD_SHA@/${PRINTCRAFT_BUILD_SHA:-unknown}/g" \
-e "s/@BUILD_SHA@/${PDFCRAFT_BUILD_SHA:-unknown}/g" \
"$HERE/Info.plist.in" >"$APP/Contents/Info.plist"
plutil -lint "$APP/Contents/Info.plist"
printf 'APPL????' >"$APP/Contents/PkgInfo"
# Sign inside-out: nested code first, then the bundle itself (no --deep on the final signature).
# Today the only nested code is the main executable; frameworks/helpers would be signed here too.
sign --options runtime --entitlements "$HERE/entitlements.plist" "$APP/Contents/MacOS/PrintCraft"
sign --options runtime --entitlements "$HERE/entitlements.plist" "$APP/Contents/MacOS/PdfCraft"
sign --options runtime --entitlements "$HERE/entitlements.plist" "$APP"
codesign --verify --strict --deep --verbose=2 "$APP"
if [ "$NOTARIZE" = 1 ]; then
ditto -c -k --keepParent "$APP" "$WORK/PrintCraft-notarize.zip"
notarize "$WORK/PrintCraft-notarize.zip"
ditto -c -k --keepParent "$APP" "$WORK/PdfCraft-notarize.zip"
notarize "$WORK/PdfCraft-notarize.zip"
xcrun stapler staple "$APP"
xcrun stapler validate "$APP"
spctl --assess --type execute -vvv "$APP"
@@ -128,12 +128,12 @@ fi
echo "==> building $DMG"
STAGE="$WORK/dmg"
mkdir -p "$STAGE"
ditto "$APP" "$STAGE/PrintCraft.app"
ditto "$APP" "$STAGE/PdfCraft.app"
ln -s /Applications "$STAGE/Applications"
rm -f "$DMG" "$WORK/raw.dmg"
# makehybrid + convert builds the image without attaching a device, unlike `create -srcfolder`,
# which is flaky on CI runners ("Resource busy") and hangs in sandboxed sessions.
hdiutil makehybrid -hfs -hfs-volume-name "PrintCraft $VERSION" -hfs-openfolder "$STAGE" -o "$WORK/raw.dmg" "$STAGE"
hdiutil makehybrid -hfs -hfs-volume-name "PdfCraft $VERSION" -hfs-openfolder "$STAGE" -o "$WORK/raw.dmg" "$STAGE"
hdiutil convert "$WORK/raw.dmg" -format UDZO -imagekey zlib-level=9 -o "$DMG"
rm -f "$WORK/raw.dmg"
sign "$DMG"
@@ -147,17 +147,17 @@ fi
# ---- CLI ---------------------------------------------------------------------------------------
echo "==> building $CLI_ZIP"
CLI_DIR="$WORK/printcraft-cli-$VERSION-macos-$ARCH"
CLI_DIR="$WORK/pdfcraft-cli-$VERSION-macos-$ARCH"
mkdir -p "$CLI_DIR"
cp "$WORK/bin/printcraft-cli" "$CLI_DIR/"
cp "$WORK/bin/pdfcraft-cli" "$CLI_DIR/"
copy_docs "$CLI_DIR"
sign --options runtime "$CLI_DIR/printcraft-cli"
codesign --verify --strict --verbose=2 "$CLI_DIR/printcraft-cli"
sign --options runtime "$CLI_DIR/pdfcraft-cli"
codesign --verify --strict --verbose=2 "$CLI_DIR/pdfcraft-cli"
rm -f "$CLI_ZIP"
ditto -c -k --keepParent "$CLI_DIR" "$CLI_ZIP"
# A bare Mach-O can't carry a stapled ticket; Gatekeeper looks the notarization up online.
if [ "$NOTARIZE" = 1 ]; then notarize "$CLI_ZIP"; fi
"$WORK/bin/printcraft-cli" --version
"$WORK/bin/pdfcraft-cli" --version
echo "==> done"
ls -lh "$DMG" "$CLI_ZIP"
+13 -13
View File
@@ -1,22 +1,22 @@
# Hosting PrintCraft for the web
# Hosting PdfCraft for the web
`printcraft-web-<version>.zip` (from the GitHub release, or `packaging/web/package.sh`) holds a
static site in `printcraft-web-<version>/`:
`pdfcraft-web-<version>.zip` (from the GitHub release, or `packaging/web/package.sh`) holds a
static site in `pdfcraft-web-<version>/`:
| File | What it is |
|---|---|
| `index.html` | The page. It loads everything through relative URLs. |
| `printcraft-web-<hash>.js` | wasm-bindgen glue (generated, ES module) |
| `printcraft-web-<hash>_bg.wasm` | The app, about 13 MB, or 5 MB with compression |
| `pdfcraft-web-<hash>.js` | wasm-bindgen glue (generated, ES module) |
| `pdfcraft-web-<hash>_bg.wasm` | The app, about 13 MB, or 5 MB with compression |
| `_headers`, `.htaccess` | Sample header rules for Netlify/Cloudflare Pages and Apache |
There is no server-side code. Upload the folder's contents anywhere that serves static files.
## Any path works
All URLs in `index.html` are relative (`public_url = "./"` in `apps/printcraft-web/Trunk.toml`),
All URLs in `index.html` are relative (`public_url = "./"` in `apps/pdfcraft-web/Trunk.toml`),
so the site works at a domain root (`https://example.com/`), under a prefix
(`https://example.com/tools/printcraft/`) and from a CDN bucket. The asset names carry a content
(`https://example.com/tools/pdfcraft/`) and from a CDN bucket. The asset names carry a content
hash, so they can be cached forever. Only `index.html` needs revalidation.
## Required server settings
@@ -31,7 +31,7 @@ hash, so they can be cached forever. Only `index.html` needs revalidation.
`.js` files, and `no-cache` on `index.html`.
- **HTTPS:** WebGPU (and the clipboard) only work in a secure context, which means `https://`
or `http://localhost`. Over plain HTTP elsewhere, the app falls back to WebGL2.
- **No special isolation headers:** PrintCraft doesn't use `SharedArrayBuffer`, so it doesn't
- **No special isolation headers:** PdfCraft doesn't use `SharedArrayBuffer`, so it doesn't
need `Cross-Origin-Opener-Policy` or `Cross-Origin-Embedder-Policy`. If your site already sends
COEP `require-corp`, also send `Cross-Origin-Resource-Policy: same-origin` (or `cross-origin`
when the files live on a CDN) on the app's files.
@@ -39,7 +39,7 @@ hash, so they can be cached forever. Only `index.html` needs revalidation.
nginx example:
```nginx
location /printcraft/ {
location /pdfcraft/ {
types { application/wasm wasm; text/javascript js; text/html html; }
gzip on;
gzip_types application/wasm text/javascript text/html;
@@ -54,8 +54,8 @@ Local test: `python3 -m http.server 8765` inside the folder, then open http://lo
```html
<iframe
src="https://example.com/printcraft/"
title="PrintCraft PDF workbench"
src="https://example.com/pdfcraft/"
title="PdfCraft PDF workbench"
style="width: 100%; height: 720px; border: 0;"
allow="fullscreen; clipboard-read; clipboard-write"
allowfullscreen>
@@ -75,7 +75,7 @@ Local test: `python3 -m http.server 8765` inside the folder, then open http://lo
## Renderer selection and fallback flags
PrintCraft renders with wgpu. It uses **WebGPU** when the browser has it and falls back to
PdfCraft renders with wgpu. It uses **WebGPU** when the browser has it and falls back to
**WebGL2** on its own. URL query flags override this, and they work on the iframe `src` too:
| Flag | Effect |
@@ -84,6 +84,6 @@ PrintCraft renders with wgpu. It uses **WebGPU** when the browser has it and fal
| `?webgl` | Force the WebGL2 backend (useful when a WebGPU driver misbehaves) |
| `?cpu` | Force the CPU canvas path (slowest, most compatible) |
For example: `<iframe src="https://example.com/printcraft/?webgl" ...>`.
For example: `<iframe src="https://example.com/pdfcraft/?webgl" ...>`.
A browser with neither WebGPU nor WebGL2 gets a message in place of the app.
+4 -4
View File
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
# Build the browser version and zip it: $DIST/printcraft-web-<version>.zip
# Build the browser version and zip it: $DIST/pdfcraft-web-<version>.zip
#
# Usage: packaging/web/package.sh [--skip-build]
#
# Needs: trunk (brew install trunk / cargo install trunk --locked) and the wasm32-unknown-unknown
# target. The zip holds a self-contained static site in printcraft-web-<version>/ that works
# target. The zip holds a self-contained static site in pdfcraft-web-<version>/ that works
# from any URL path and inside an <iframe>. Hosting notes: packaging/web/README.md.
set -euo pipefail
# shellcheck source=../env.sh
@@ -13,7 +13,7 @@ HERE="$ROOT/packaging/web"
if [ "${1:-}" != "--skip-build" ]; then
command -v trunk >/dev/null || { echo "error: trunk not found (cargo install trunk --locked)" >&2; exit 1; }
(cd "$ROOT/apps/printcraft-web" && trunk build --release)
(cd "$ROOT/apps/pdfcraft-web" && trunk build --release)
fi
SITE="$ROOT/dist/web"
@@ -24,7 +24,7 @@ if grep -Eq '(src|href)="/[^/]' "$SITE/index.html"; then
exit 1
fi
NAME="printcraft-web-$VERSION"
NAME="pdfcraft-web-$VERSION"
WORK="$CARGO_TARGET_DIR/web-package"
rm -rf "$WORK"
mkdir -p "$WORK/$NAME"
+19 -19
View File
@@ -1,11 +1,11 @@
<#
.SYNOPSIS
Build, sign and package PrintCraft for Windows.
Build, sign and package PdfCraft for Windows.
.DESCRIPTION
Produces, in $env:DIST (default: dist/release):
printcraft-<version>-windows-<arch>.msi per-machine installer (WiX v5)
printcraft-<version>-windows-<arch>-portable.zip printcraft.exe + printcraft-cli.exe
pdfcraft-<version>-windows-<arch>.msi per-machine installer (WiX v5)
pdfcraft-<version>-windows-<arch>-portable.zip pdfcraft.exe + pdfcraft-cli.exe
The binaries link the C runtime statically (+crt-static), so neither the MSI nor the portable
zip needs the Visual C++ redistributable. Signing is delegated to sign.ps1 (skipped with a
@@ -33,7 +33,7 @@ function Invoke-Native([string] $What, [scriptblock] $Block) {
}
# The version lives in one place: [workspace.package] version in the root Cargo.toml.
$Version = $env:PRINTCRAFT_VERSION
$Version = $env:PDFCRAFT_VERSION
if (-not $Version) {
$inPkg = $false
foreach ($line in Get-Content (Join-Path $Root 'Cargo.toml')) {
@@ -50,10 +50,10 @@ $Dist = if ($env:DIST) { $env:DIST } else { Join-Path $Root 'dist\release' }
$TargetDir = if ($env:CARGO_TARGET_DIR) { $env:CARGO_TARGET_DIR } else { Join-Path $Root 'target' }
New-Item -ItemType Directory -Force -Path $Dist | Out-Null
if (-not $env:PRINTCRAFT_BUILD_SHA) { $env:PRINTCRAFT_BUILD_SHA = (git -C $Root rev-parse HEAD 2>$null) }
if (-not $env:PRINTCRAFT_BUILD_DATE) { $env:PRINTCRAFT_BUILD_DATE = (Get-Date).ToUniversalTime().ToString('yyyy-MM-dd') }
if (-not $env:PDFCRAFT_BUILD_SHA) { $env:PDFCRAFT_BUILD_SHA = (git -C $Root rev-parse HEAD 2>$null) }
if (-not $env:PDFCRAFT_BUILD_DATE) { $env:PDFCRAFT_BUILD_DATE = (Get-Date).ToUniversalTime().ToString('yyyy-MM-dd') }
Write-Output "PrintCraft $Version for Windows $Arch ($Target)"
Write-Output "PdfCraft $Version for Windows $Arch ($Target)"
if (-not $SkipBuild) {
# Static CRT: no VC++ redistributable needed. Scoped to the target so host build scripts and
@@ -61,8 +61,8 @@ if (-not $SkipBuild) {
$flagVar = 'CARGO_TARGET_' + ($Target.ToUpper() -replace '-', '_') + '_RUSTFLAGS'
[Environment]::SetEnvironmentVariable($flagVar, '-C target-feature=+crt-static')
# Fail the build (rather than warn) if the icon/VERSIONINFO can't be embedded.
$env:PRINTCRAFT_REQUIRE_WINRES = '1'
Invoke-Native "cargo build ($Target)" { cargo build --release --locked -p printcraft -p printcraft-cli --target $Target }
$env:PDFCRAFT_REQUIRE_WINRES = '1'
Invoke-Native "cargo build ($Target)" { cargo build --release --locked -p pdfcraft -p pdfcraft-cli --target $Target }
}
$Bin = Join-Path $TargetDir "$Target\release"
@@ -77,7 +77,7 @@ function Get-PeHeader([string] $Path) {
return @{ Machine = [BitConverter]::ToUInt16($bytes, $pe + 4); Subsystem = [BitConverter]::ToUInt16($bytes, $pe + 0x5C) }
}
$Machine = switch ($Arch) { 'x64' { 0x8664 } 'x86' { 0x14C } 'arm64' { 0xAA64 } }
foreach ($check in @(@('printcraft.exe', 2), @('printcraft-cli.exe', 3))) {
foreach ($check in @(@('pdfcraft.exe', 2), @('pdfcraft-cli.exe', 3))) {
$h = Get-PeHeader (Join-Path $Bin $check[0])
if ($h.Machine -ne $Machine) { throw "$($check[0]) is for machine 0x$('{0:X}' -f $h.Machine), expected 0x$('{0:X}' -f $Machine) ($Arch)" }
if ($h.Subsystem -ne $check[1]) { throw "$($check[0]) has PE subsystem $($h.Subsystem), expected $($check[1])" }
@@ -86,15 +86,15 @@ foreach ($check in @(@('printcraft.exe', 2), @('printcraft-cli.exe', 3))) {
$Stage = Join-Path $TargetDir "windows-package\$Arch"
Remove-Item -Recurse -Force $Stage -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Force -Path $Stage | Out-Null
Copy-Item (Join-Path $Bin 'printcraft.exe'), (Join-Path $Bin 'printcraft-cli.exe') $Stage
Copy-Item (Join-Path $Bin 'pdfcraft.exe'), (Join-Path $Bin 'pdfcraft-cli.exe') $Stage
& (Join-Path $PSScriptRoot 'sign.ps1') (Join-Path $Stage 'printcraft.exe') (Join-Path $Stage 'printcraft-cli.exe')
& (Join-Path $PSScriptRoot 'sign.ps1') (Join-Path $Stage 'pdfcraft.exe') (Join-Path $Stage 'pdfcraft-cli.exe')
# ---- MSI ---------------------------------------------------------------------------------------
$Msi = Join-Path $Dist "printcraft-$Version-windows-$Arch.msi"
$Msi = Join-Path $Dist "pdfcraft-$Version-windows-$Arch.msi"
Invoke-Native 'wix build' {
wix build (Join-Path $PSScriptRoot 'printcraft.wxs') -arch $Arch `
-d "Version=$MsiVersion" -d "BinDir=$Stage" -d "IconPath=$(Join-Path $Root 'assets\app-icon\printcraft.ico')" `
wix build (Join-Path $PSScriptRoot 'pdfcraft.wxs') -arch $Arch `
-d "Version=$MsiVersion" -d "BinDir=$Stage" -d "IconPath=$(Join-Path $Root 'assets\app-icon\pdfcraft.ico')" `
-o $Msi
}
# wix writes its debug symbols (.wixpdb) next to the MSI; keep them out of the release assets.
@@ -102,7 +102,7 @@ Remove-Item -Force -ErrorAction SilentlyContinue ([IO.Path]::ChangeExtension($Ms
& (Join-Path $PSScriptRoot 'sign.ps1') $Msi
# ---- portable zip ------------------------------------------------------------------------------
$Portable = Join-Path $TargetDir "windows-package\printcraft-$Version-windows-$Arch-portable"
$Portable = Join-Path $TargetDir "windows-package\pdfcraft-$Version-windows-$Arch-portable"
Remove-Item -Recurse -Force $Portable -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Force -Path $Portable | Out-Null
Copy-Item (Join-Path $Stage '*.exe') $Portable
@@ -118,7 +118,7 @@ if ($env:CRAFT_FONTS_DIR) {
if (Test-Path $ofl) { Copy-Item $ofl (Join-Path $Portable "OFL-$($_.Name).txt") }
}
}
$Zip = Join-Path $Dist "printcraft-$Version-windows-$Arch-portable.zip"
$Zip = Join-Path $Dist "pdfcraft-$Version-windows-$Arch-portable.zip"
Remove-Item -Force $Zip -ErrorAction SilentlyContinue
Compress-Archive -Path $Portable -DestinationPath $Zip
@@ -126,8 +126,8 @@ Compress-Archive -Path $Portable -DestinationPath $Zip
# here; .github/workflows/windows-arm64.yml installs and runs it on ARM64 instead.
$HostArch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLowerInvariant()
if ($Arch -ne 'arm64' -or $HostArch -eq 'arm64') {
Invoke-Native 'printcraft-cli --version' { & (Join-Path $Stage 'printcraft-cli.exe') --version }
Invoke-Native 'pdfcraft-cli --version' { & (Join-Path $Stage 'pdfcraft-cli.exe') --version }
} else {
Write-Output "skipping printcraft-cli --version: an $Arch build doesn't run on this $HostArch machine"
Write-Output "skipping pdfcraft-cli --version: an $Arch build doesn't run on this $HostArch machine"
}
Get-Item $Msi, $Zip | Format-Table Name, Length
+81
View File
@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
PdfCraft MSI (WiX Toolset v5: `dotnet tool install -g wix`). Built by package.ps1:
wix build pdfcraft.wxs -arch x64 -d Version=1.2.3 -d BinDir=... -d IconPath=... -o out.msi
Per-machine install into Program Files, a Start Menu shortcut, an App Paths entry, and PdfCraft
registered as a PDF handler (offered under "Open with" and in Default apps, never forced as the
default). Files opened with PdfCraft arrive on its command line.
-->
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Package
Name="PdfCraft"
Manufacturer="Learning Machines LLC"
Version="$(var.Version)"
UpgradeCode="EA00C367-7270-4C50-9D8B-A7A5C88AD27F"
Scope="perMachine"
Compressed="yes"
Language="1033">
<SummaryInformation Description="PdfCraft PDF workbench" Manufacturer="Learning Machines LLC" />
<!-- Same-version upgrades let successive pre-releases of one X.Y.Z replace each other
(MSI versions are numeric, so 1.2.3-rc.1 and 1.2.3-rc.2 are both 1.2.3). -->
<MajorUpgrade AllowSameVersionUpgrades="yes"
DowngradeErrorMessage="A newer version of PdfCraft is already installed." />
<MediaTemplate EmbedCab="yes" CompressionLevel="high" />
<!-- Windows Installer requires an Icon id ending in .ico or .exe, or advertised shortcuts and
Add/Remove Programs show a blank icon (#57). -->
<Icon Id="PdfcraftIcon.ico" SourceFile="$(var.IconPath)" />
<Property Id="ARPPRODUCTICON" Value="PdfcraftIcon.ico" />
<Property Id="ARPURLINFOABOUT" Value="https://getartcraft.com/apps/pdfcraft" />
<Property Id="ARPURLUPDATEINFO" Value="https://getartcraft.com/apps/pdfcraft" />
<Property Id="ARPHELPLINK" Value="https://discord.gg/artcraft" />
<StandardDirectory Id="ProgramFiles6432Folder">
<Directory Id="INSTALLFOLDER" Name="PdfCraft" />
</StandardDirectory>
<StandardDirectory Id="ProgramMenuFolder" />
<Feature Id="Main" Title="PdfCraft" Level="1">
<ComponentGroupRef Id="PdfcraftFiles" />
</Feature>
</Package>
<Fragment>
<ComponentGroup Id="PdfcraftFiles" Directory="INSTALLFOLDER">
<Component Id="PdfcraftApp" Guid="E724C1C6-091F-4E21-A685-80D089FDBE21">
<File Id="PdfcraftExe" Source="$(var.BinDir)\pdfcraft.exe" KeyPath="yes">
<Shortcut Id="StartMenuShortcut" Directory="ProgramMenuFolder" Name="PdfCraft"
Description="PdfCraft PDF workbench" WorkingDirectory="INSTALLFOLDER" Advertise="yes"
Icon="PdfcraftIcon.ico" IconIndex="0" />
</File>
<RegistryValue Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\App Paths\pdfcraft.exe" Value="[#PdfcraftExe]" Type="string" />
<!-- PDF files (#107): PdfCraft is offered under "Open with" and in Settings ▸ Default
apps, through Windows' Default Programs registration (a ProgID, OpenWithProgids,
Capabilities and RegisteredApplications). It never takes over an existing default:
.pdf's own default value is left alone, and the user chooses. Without this, the only
PdfCraft entry to pick was the advertised Start Menu shortcut, which Windows can't
run as a file handler ("This app can't run on your PC"). -->
<RegistryValue Root="HKLM" Key="Software\Classes\PdfCraft.Document" Value="PDF Document" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\PdfCraft.Document\DefaultIcon" Value="[#PdfcraftExe],0" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\PdfCraft.Document\shell\open\command" Value="&quot;[#PdfcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\.pdf\OpenWithProgids" Name="PdfCraft.Document" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\pdfcraft.exe" Name="FriendlyAppName" Value="PdfCraft" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\pdfcraft.exe\SupportedTypes" Name=".pdf" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\pdfcraft.exe\shell\open\command" Value="&quot;[#PdfcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKLM" Key="Software\PdfCraft\Capabilities" Name="ApplicationName" Value="PdfCraft" Type="string" />
<RegistryValue Root="HKLM" Key="Software\PdfCraft\Capabilities" Name="ApplicationDescription" Value="Open-source PDF workbench" Type="string" />
<RegistryValue Root="HKLM" Key="Software\PdfCraft\Capabilities" Name="ApplicationIcon" Value="[#PdfcraftExe],0" Type="string" />
<RegistryValue Root="HKLM" Key="Software\PdfCraft\Capabilities\FileAssociations" Name=".pdf" Value="PdfCraft.Document" Type="string" />
<RegistryValue Root="HKLM" Key="Software\RegisteredApplications" Name="PdfCraft" Value="Software\PdfCraft\Capabilities" Type="string" />
</Component>
<Component Id="PdfcraftCli">
<File Id="PdfcraftCliExe" Source="$(var.BinDir)\pdfcraft-cli.exe" KeyPath="yes" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
-81
View File
@@ -1,81 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
PrintCraft MSI (WiX Toolset v5: `dotnet tool install -g wix`). Built by package.ps1:
wix build printcraft.wxs -arch x64 -d Version=1.2.3 -d BinDir=... -d IconPath=... -o out.msi
Per-machine install into Program Files, a Start Menu shortcut, an App Paths entry, and PrintCraft
registered as a PDF handler (offered under "Open with" and in Default apps, never forced as the
default). Files opened with PrintCraft arrive on its command line.
-->
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Package
Name="PrintCraft"
Manufacturer="Learning Machines LLC"
Version="$(var.Version)"
UpgradeCode="EA00C367-7270-4C50-9D8B-A7A5C88AD27F"
Scope="perMachine"
Compressed="yes"
Language="1033">
<SummaryInformation Description="PrintCraft PDF workbench" Manufacturer="Learning Machines LLC" />
<!-- Same-version upgrades let successive pre-releases of one X.Y.Z replace each other
(MSI versions are numeric, so 1.2.3-rc.1 and 1.2.3-rc.2 are both 1.2.3). -->
<MajorUpgrade AllowSameVersionUpgrades="yes"
DowngradeErrorMessage="A newer version of PrintCraft is already installed." />
<MediaTemplate EmbedCab="yes" CompressionLevel="high" />
<!-- Windows Installer requires an Icon id ending in .ico or .exe, or advertised shortcuts and
Add/Remove Programs show a blank icon (#57). -->
<Icon Id="PrintcraftIcon.ico" SourceFile="$(var.IconPath)" />
<Property Id="ARPPRODUCTICON" Value="PrintcraftIcon.ico" />
<Property Id="ARPURLINFOABOUT" Value="https://getartcraft.com/apps/printcraft" />
<Property Id="ARPURLUPDATEINFO" Value="https://getartcraft.com/apps/printcraft" />
<Property Id="ARPHELPLINK" Value="https://discord.gg/artcraft" />
<StandardDirectory Id="ProgramFiles6432Folder">
<Directory Id="INSTALLFOLDER" Name="PrintCraft" />
</StandardDirectory>
<StandardDirectory Id="ProgramMenuFolder" />
<Feature Id="Main" Title="PrintCraft" Level="1">
<ComponentGroupRef Id="PrintcraftFiles" />
</Feature>
</Package>
<Fragment>
<ComponentGroup Id="PrintcraftFiles" Directory="INSTALLFOLDER">
<Component Id="PrintcraftApp" Guid="E724C1C6-091F-4E21-A685-80D089FDBE21">
<File Id="PrintcraftExe" Source="$(var.BinDir)\printcraft.exe" KeyPath="yes">
<Shortcut Id="StartMenuShortcut" Directory="ProgramMenuFolder" Name="PrintCraft"
Description="PrintCraft PDF workbench" WorkingDirectory="INSTALLFOLDER" Advertise="yes"
Icon="PrintcraftIcon.ico" IconIndex="0" />
</File>
<RegistryValue Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\App Paths\printcraft.exe" Value="[#PrintcraftExe]" Type="string" />
<!-- PDF files (#107): PrintCraft is offered under "Open with" and in Settings ▸ Default
apps, through Windows' Default Programs registration (a ProgID, OpenWithProgids,
Capabilities and RegisteredApplications). It never takes over an existing default:
.pdf's own default value is left alone, and the user chooses. Without this, the only
PrintCraft entry to pick was the advertised Start Menu shortcut, which Windows can't
run as a file handler ("This app can't run on your PC"). -->
<RegistryValue Root="HKLM" Key="Software\Classes\PrintCraft.Document" Value="PDF Document" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\PrintCraft.Document\DefaultIcon" Value="[#PrintcraftExe],0" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\PrintCraft.Document\shell\open\command" Value="&quot;[#PrintcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\.pdf\OpenWithProgids" Name="PrintCraft.Document" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\printcraft.exe" Name="FriendlyAppName" Value="PrintCraft" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\printcraft.exe\SupportedTypes" Name=".pdf" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\printcraft.exe\shell\open\command" Value="&quot;[#PrintcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKLM" Key="Software\PrintCraft\Capabilities" Name="ApplicationName" Value="PrintCraft" Type="string" />
<RegistryValue Root="HKLM" Key="Software\PrintCraft\Capabilities" Name="ApplicationDescription" Value="Open-source PDF workbench" Type="string" />
<RegistryValue Root="HKLM" Key="Software\PrintCraft\Capabilities" Name="ApplicationIcon" Value="[#PrintcraftExe],0" Type="string" />
<RegistryValue Root="HKLM" Key="Software\PrintCraft\Capabilities\FileAssociations" Name=".pdf" Value="PrintCraft.Document" Type="string" />
<RegistryValue Root="HKLM" Key="Software\RegisteredApplications" Name="PrintCraft" Value="Software\PrintCraft\Capabilities" Type="string" />
</Component>
<Component Id="PrintcraftCli">
<File Id="PrintcraftCliExe" Source="$(var.BinDir)\printcraft-cli.exe" KeyPath="yes" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
+3 -3
View File
@@ -15,7 +15,7 @@
timestamp server, ...). Optional overrides: WINDOWS_TIMESTAMP_URL, SIGNTOOL (path to signtool.exe).
.EXAMPLE
pwsh packaging/windows/sign.ps1 dist/printcraft.exe dist/Printcraft.msi
pwsh packaging/windows/sign.ps1 dist/pdfcraft.exe dist/Pdfcraft.msi
#>
param(
[Parameter(Mandatory = $true, ValueFromRemainingArguments = $true)]
@@ -55,8 +55,8 @@ if (-not $haveCert -and -not $haveAzure) {
}
$script:SignTool = Find-SignTool
$common = @('sign', '/v', '/fd', 'SHA256', '/td', 'SHA256', '/d', 'PrintCraft', '/du', 'https://github.com/storytold/printcraft')
$tmp = Join-Path ([IO.Path]::GetTempPath()) "printcraft-sign-$PID"
$common = @('sign', '/v', '/fd', 'SHA256', '/td', 'SHA256', '/d', 'PdfCraft', '/du', 'https://github.com/storytold/pdfcraft')
$tmp = Join-Path ([IO.Path]::GetTempPath()) "pdfcraft-sign-$PID"
New-Item -ItemType Directory -Force -Path $tmp | Out-Null
try {